zold 0.18.8 → 0.18.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/zold +1 -0
- data/fixtures/scripts/distribute-wallet.sh +4 -4
- data/fixtures/scripts/pull-on-start.sh +5 -4
- data/fixtures/scripts/push-and-pull.sh +5 -5
- data/fixtures/scripts/redeploy-on-upgrade.sh +1 -1
- data/fixtures/scripts/spread-wallets.sh +5 -5
- data/lib/zold/cached_wallets.rb +3 -17
- data/lib/zold/commands/fetch.rb +12 -2
- data/lib/zold/commands/invoice.rb +5 -1
- data/lib/zold/commands/merge.rb +6 -6
- data/lib/zold/commands/node.rb +41 -21
- data/lib/zold/commands/push.rb +23 -10
- data/lib/zold/hungry_wallets.rb +32 -3
- data/lib/zold/node/entrance.rb +1 -1
- data/lib/zold/node/spread_entrance.rb +5 -2
- data/lib/zold/remotes.rb +4 -0
- data/lib/zold/sync_wallets.rb +3 -17
- data/lib/zold/thread_pool.rb +19 -6
- data/lib/zold/verbose_thread.rb +1 -0
- data/lib/zold/version.rb +1 -1
- data/test/commands/test_node.rb +2 -6
- data/test/commands/test_pull.rb +1 -1
- data/test/commands/test_push.rb +2 -2
- data/test/node/fake_node.rb +1 -1
- data/test/test__helper.rb +8 -4
- data/test/test_hungry_wallets.rb +53 -0
- data/test/test_thread_pool.rb +8 -0
- data/test/test_zold.rb +3 -2
- data/zold.gemspec +7 -7
- metadata +31 -29
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ad955cd4ed1c34ff735ca6684945186c29c07bf970f4bdc130ffdc0b3164922
|
4
|
+
data.tar.gz: 9344af265b58567d3aa2afda28815c6efaaddf0235a379d85f1ae69433112cd0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fba208cc63dc399eb24dd6c015f6eada0e22c9a3ca2b22d6a5612576b6ea264f2e3bc6cb57c0a69618694544928faa5f919d779c6e29d7da5137d40325e9b62e
|
7
|
+
data.tar.gz: bbfd1eec62d4f29272c21273aef71d9d110bbe491237b264c18f571e687d724b606861141e2efacadc3551fafe7917b2d896ed88eccc39b80f86066e226d81ee
|
data/bin/zold
CHANGED
@@ -36,6 +36,7 @@ require_relative '../lib/zold/wallets'
|
|
36
36
|
require_relative '../lib/zold/tree_wallets'
|
37
37
|
require_relative '../lib/zold/sync_wallets'
|
38
38
|
require_relative '../lib/zold/cached_wallets'
|
39
|
+
require_relative '../lib/zold/hungry_wallets'
|
39
40
|
require_relative '../lib/zold/log'
|
40
41
|
require_relative '../lib/zold/key'
|
41
42
|
require_relative '../lib/zold/age'
|
@@ -4,7 +4,7 @@ function start_node {
|
|
4
4
|
port=$(reserve_port)
|
5
5
|
mkdir ${port}
|
6
6
|
cd ${port}
|
7
|
-
zold node --trace --invoice=DISTRWALLET@ffffffffffffffff \
|
7
|
+
zold node --trace --invoice=DISTRWALLET@ffffffffffffffff --tolerate-edges \
|
8
8
|
--host=127.0.0.1 --port=${port} --bind-port=${port} \
|
9
9
|
--threads=0 --routine-immediately --never-reboot > log.txt 2>&1 &
|
10
10
|
pid=$!
|
@@ -36,7 +36,7 @@ zold --public-key=id_rsa.pub create 0000000000000000
|
|
36
36
|
zold pay --private-key=id_rsa 0000000000000000 NOPREFIX@aaaabbbbccccdddd 4.95 'For the book'
|
37
37
|
zold remote clean
|
38
38
|
zold remote add 127.0.0.1 ${first}
|
39
|
-
zold push 0000000000000000
|
39
|
+
zold push 0000000000000000 --tolerate-edges
|
40
40
|
zold remote clean
|
41
41
|
zold remote add 127.0.0.1 ${second}
|
42
42
|
|
@@ -45,7 +45,7 @@ zold remote add 127.0.0.1 ${second}
|
|
45
45
|
# delay between them, in order to give the first node a chance to distribute
|
46
46
|
# the wallet.
|
47
47
|
i=0
|
48
|
-
until zold fetch 0000000000000000 --ignore-score-weakness; do
|
48
|
+
until zold fetch 0000000000000000 --ignore-score-weakness --tolerate-edges; do
|
49
49
|
echo 'Failed to fetch, let us try again'
|
50
50
|
((i++)) || sleep 0
|
51
51
|
if ((i==5)); then
|
@@ -73,7 +73,7 @@ fi
|
|
73
73
|
# have the wallet very soon.
|
74
74
|
rm -f ${second}/**/*.z
|
75
75
|
i=0
|
76
|
-
until zold fetch 0000000000000000 --ignore-score-weakness; do
|
76
|
+
until zold fetch 0000000000000000 --ignore-score-weakness --tolerate-edges; do
|
77
77
|
echo 'Failed to fetch, let us try again'
|
78
78
|
((i++)) || sleep 0
|
79
79
|
if ((i==5)); then
|
@@ -3,7 +3,8 @@
|
|
3
3
|
port=$(reserve_port)
|
4
4
|
mkdir server
|
5
5
|
cd server
|
6
|
-
zold
|
6
|
+
zold remote clean
|
7
|
+
zold node --trace --invoice=PULLONSTART@ffffffffffffffff --no-metronome --tolerate-edges \
|
7
8
|
--host=127.0.0.1 --port=${port} --bind-port=${port} \
|
8
9
|
--threads=0 --standalone --pretty=full 2>&1 &
|
9
10
|
cd ..
|
@@ -14,16 +15,16 @@ zold remote clean
|
|
14
15
|
zold remote add 127.0.0.1 ${port}
|
15
16
|
|
16
17
|
zold --public-key=id_rsa.pub create abcdabcdabcdabcd
|
17
|
-
zold push abcdabcdabcdabcd
|
18
|
+
zold push abcdabcdabcdabcd --tolerate-edges
|
18
19
|
zold remove abcdabcdabcdabcd
|
19
|
-
zold invoice abcdabcdabcdabcd
|
20
|
+
zold invoice abcdabcdabcdabcd --tolerate-edges
|
20
21
|
|
21
22
|
second_port=$(reserve_port)
|
22
23
|
mkdir second
|
23
24
|
cd second
|
24
25
|
zold remote clean
|
25
26
|
zold remote add 127.0.0.1 ${port}
|
26
|
-
zold node --trace --invoice=abcdabcdabcdabcd --no-metronome \
|
27
|
+
zold node --trace --invoice=abcdabcdabcdabcd --no-metronome --tolerate-edges \
|
27
28
|
--host=127.0.0.1 --port=${second_port} --bind-port=${second_port} \
|
28
29
|
--threads=0 &
|
29
30
|
|
@@ -4,7 +4,7 @@ port=$(reserve_port)
|
|
4
4
|
|
5
5
|
mkdir server
|
6
6
|
cd server
|
7
|
-
zold node --trace --invoice=PUSHNPULL@ffffffffffffffff \
|
7
|
+
zold node --trace --invoice=PUSHNPULL@ffffffffffffffff --tolerate-edges \
|
8
8
|
--host=127.0.0.1 --port=${port} --bind-port=${port} \
|
9
9
|
--threads=0 --standalone 2>&1 &
|
10
10
|
pid=$!
|
@@ -29,13 +29,13 @@ zold show 0000000000000000
|
|
29
29
|
zold taxes debt 0000000000000000
|
30
30
|
|
31
31
|
zold remote show
|
32
|
-
zold push
|
33
|
-
zold push 0000000000000000
|
34
|
-
until zold fetch 0000000000000000 --ignore-score-weakness; do
|
32
|
+
zold push --tolerate-edges
|
33
|
+
zold push 0000000000000000 --tolerate-edges
|
34
|
+
until zold fetch 0000000000000000 --ignore-score-weakness --tolerate-edges; do
|
35
35
|
echo 'Failed to fetch, let us try again'
|
36
36
|
sleep 1
|
37
37
|
done
|
38
|
-
zold fetch
|
38
|
+
zold fetch --tolerate-edges
|
39
39
|
zold diff 0000000000000000
|
40
40
|
zold merge
|
41
41
|
zold merge 0000000000000000
|
@@ -5,7 +5,7 @@ function start_node {
|
|
5
5
|
cd $1
|
6
6
|
zold remote clean
|
7
7
|
zold node $3 --nohup --nohup-command='touch restarted' --nohup-log=log --nohup-max-cycles=0 --nohup-log-truncate=10240 \
|
8
|
-
--expose-version=$2 --save-pid=pid --routine-immediately \
|
8
|
+
--expose-version=$2 --save-pid=pid --routine-immediately --tolerate-edges \
|
9
9
|
--verbose --trace --invoice=REDEPLOY@ffffffffffffffff \
|
10
10
|
--host=127.0.0.1 --port=$1 --bind-port=$1 --threads=1 --strength=20 > /dev/null 2>&1
|
11
11
|
wait_for_port $1
|
@@ -4,7 +4,8 @@ function start_node {
|
|
4
4
|
port=$(reserve_port)
|
5
5
|
mkdir ${port}
|
6
6
|
cd ${port}
|
7
|
-
zold
|
7
|
+
zold remote clean
|
8
|
+
zold node --trace --invoice=SPREADWALLETS@ffffffffffffffff --tolerate-edges \
|
8
9
|
--host=127.0.0.1 --port=${port} --bind-port=${port} \
|
9
10
|
--threads=0 > log.txt 2>&1 &
|
10
11
|
pid=$!
|
@@ -18,20 +19,19 @@ first=$(start_node)
|
|
18
19
|
second=$(start_node)
|
19
20
|
trap "halt_nodes ${first} ${second}" EXIT
|
20
21
|
|
21
|
-
zold --home=${first} remote clean
|
22
22
|
zold --home=${first} remote add 127.0.0.1 ${second}
|
23
|
-
zold --home=${second} remote clean
|
24
23
|
zold --home=${second} remote add 127.0.0.1 ${first}
|
25
24
|
|
26
25
|
zold --public-key=id_rsa.pub create 0000000000000000
|
27
26
|
zold pay --private-key=id_rsa 0000000000000000 NOPREFIX@aaaabbbbccccdddd 4.95 'To help you, dude!'
|
27
|
+
zold remote clean
|
28
28
|
zold remote add 127.0.0.1 ${first}
|
29
|
-
zold push 0000000000000000
|
29
|
+
zold push 0000000000000000 --tolerate-edges
|
30
30
|
zold remote clean
|
31
31
|
zold remote add 127.0.0.1 ${second}
|
32
32
|
|
33
33
|
i=0
|
34
|
-
until zold fetch 0000000000000000 --ignore-score-weakness; do
|
34
|
+
until zold fetch 0000000000000000 --ignore-score-weakness --tolerate-edges; do
|
35
35
|
echo 'Failed to fetch, let us try again'
|
36
36
|
((i++)) || sleep 0
|
37
37
|
if ((i==5)); then
|
data/lib/zold/cached_wallets.rb
CHANGED
@@ -21,6 +21,7 @@
|
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
23
|
require 'zache'
|
24
|
+
require 'delegate'
|
24
25
|
require_relative 'endless'
|
25
26
|
require_relative 'thread_pool'
|
26
27
|
|
@@ -30,7 +31,7 @@ require_relative 'thread_pool'
|
|
30
31
|
# License:: MIT
|
31
32
|
module Zold
|
32
33
|
# Collection of local wallets
|
33
|
-
class CachedWallets
|
34
|
+
class CachedWallets < SimpleDelegator
|
34
35
|
def initialize(wallets)
|
35
36
|
@wallets = wallets
|
36
37
|
@zache = Zache.new
|
@@ -41,22 +42,7 @@ module Zold
|
|
41
42
|
@zache.clean
|
42
43
|
end
|
43
44
|
end
|
44
|
-
|
45
|
-
|
46
|
-
def to_s
|
47
|
-
@wallets.to_s
|
48
|
-
end
|
49
|
-
|
50
|
-
def path
|
51
|
-
@wallets.path
|
52
|
-
end
|
53
|
-
|
54
|
-
def all
|
55
|
-
@wallets.all
|
56
|
-
end
|
57
|
-
|
58
|
-
def count
|
59
|
-
@wallets.count
|
45
|
+
super(wallets)
|
60
46
|
end
|
61
47
|
|
62
48
|
def acq(id, exclusive: false)
|
data/lib/zold/commands/fetch.rb
CHANGED
@@ -66,6 +66,9 @@ Available options:"
|
|
66
66
|
o.array '--ignore-node',
|
67
67
|
'Ignore this node and don\'t fetch from it',
|
68
68
|
default: []
|
69
|
+
o.bool '--tolerate-edges',
|
70
|
+
'Don\'t fail if only "edge" (not default ones) nodes accepted the wallet',
|
71
|
+
default: false
|
69
72
|
o.bool '--quiet-if-absent',
|
70
73
|
'Don\'t fail if the wallet is absent in all remote nodes',
|
71
74
|
default: false
|
@@ -91,15 +94,22 @@ Available options:"
|
|
91
94
|
total = Concurrent::AtomicFixnum.new
|
92
95
|
nodes = Concurrent::AtomicFixnum.new
|
93
96
|
done = Concurrent::AtomicFixnum.new
|
97
|
+
defaults = Concurrent::AtomicFixnum.new
|
94
98
|
@remotes.iterate(@log) do |r|
|
95
99
|
nodes.increment
|
96
100
|
total.increment(fetch_one(id, r, cps, opts))
|
101
|
+
defaults.increment if r.default?
|
97
102
|
done.increment
|
98
103
|
end
|
99
104
|
raise "There are no remote nodes, run 'zold remote reset'" if nodes.value.zero?
|
100
|
-
|
105
|
+
unless opts['quiet-if-absent']
|
106
|
+
raise "No nodes out of #{nodes.value} have the wallet #{id}" if done.value.zero?
|
107
|
+
if defaults.value.zero? && !opts['tolerate-edges']
|
108
|
+
raise "There are only edge nodes, run 'zold remote reset' or use --tolerate-edges"
|
109
|
+
end
|
110
|
+
end
|
101
111
|
@log.info("#{done.value} copies of #{id} fetched in #{Age.new(start)} with the total score of \
|
102
|
-
#{total.value} from #{nodes.value} nodes")
|
112
|
+
#{total.value} from #{nodes.value} nodes (#{defaults.value} defaults)")
|
103
113
|
list = cps.all.map do |c|
|
104
114
|
" ##{c[:name]}: #{c[:score]} #{Wallet.new(c[:path]).mnemo} \
|
105
115
|
#{Size.new(File.size(c[:path]))}/#{Age.new(File.mtime(c[:path]))}"
|
@@ -51,6 +51,9 @@ Available options:"
|
|
51
51
|
o.integer '--length',
|
52
52
|
'The length of the invoice prefix (default: 8)',
|
53
53
|
default: 8
|
54
|
+
o.bool '--tolerate-edges',
|
55
|
+
'Don\'t fail if only "edge" (not default ones) nodes have the wallet',
|
56
|
+
default: false
|
54
57
|
o.string '--network',
|
55
58
|
'The name of the network we work in',
|
56
59
|
default: 'test'
|
@@ -67,7 +70,8 @@ Available options:"
|
|
67
70
|
unless @wallets.acq(id, &:exists?)
|
68
71
|
require_relative 'pull'
|
69
72
|
Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
|
70
|
-
['pull', id.to_s, "--network=#{opts['network']}"]
|
73
|
+
['pull', id.to_s, "--network=#{opts['network']}"] +
|
74
|
+
(opts['tolerate-edges'] ? ['--tolerate-edges'] : [])
|
71
75
|
)
|
72
76
|
end
|
73
77
|
inv = @wallets.acq(id) do |wallet|
|
data/lib/zold/commands/merge.rb
CHANGED
@@ -78,6 +78,12 @@ Available options:"
|
|
78
78
|
cps = cps.all.sort_by { |c| c[:score] }.reverse
|
79
79
|
patch = Patch.new(@wallets, log: @log)
|
80
80
|
score = 0
|
81
|
+
cps.each_with_index do |c, idx|
|
82
|
+
wallet = Wallet.new(c[:path])
|
83
|
+
name = "#{c[:name]}/#{idx}/#{c[:score]}"
|
84
|
+
merge_one(opts, patch, wallet, name)
|
85
|
+
score += c[:score]
|
86
|
+
end
|
81
87
|
@wallets.acq(id) do |w|
|
82
88
|
if w.exists?
|
83
89
|
merge_one(opts, patch, w, 'localhost')
|
@@ -86,12 +92,6 @@ Available options:"
|
|
86
92
|
@log.debug("Local copy of #{id} is absent, nothing to merge")
|
87
93
|
end
|
88
94
|
end
|
89
|
-
cps.each_with_index do |c, idx|
|
90
|
-
wallet = Wallet.new(c[:path])
|
91
|
-
name = "#{c[:name]}/#{idx}/#{c[:score]}"
|
92
|
-
merge_one(opts, patch, wallet, name)
|
93
|
-
score += c[:score]
|
94
|
-
end
|
95
95
|
modified = @wallets.acq(id, exclusive: true) { |w| patch.save(w.path, overwrite: true) }
|
96
96
|
if modified
|
97
97
|
@log.info("#{cps.count} copies with the total score of #{score} successfully merged \
|
data/lib/zold/commands/node.rb
CHANGED
@@ -30,8 +30,10 @@ require_relative 'thread_badge'
|
|
30
30
|
require_relative '../version'
|
31
31
|
require_relative '../age'
|
32
32
|
require_relative '../metronome'
|
33
|
+
require_relative '../thread_pool'
|
33
34
|
require_relative '../wallet'
|
34
35
|
require_relative '../wallets'
|
36
|
+
require_relative '../hungry_wallets'
|
35
37
|
require_relative '../remotes'
|
36
38
|
require_relative '../verbose_thread'
|
37
39
|
require_relative '../node/farmers'
|
@@ -95,6 +97,9 @@ module Zold
|
|
95
97
|
o.bool '--ignore-score-weakness',
|
96
98
|
'Ignore score weakness of incoming requests and register those nodes anyway',
|
97
99
|
default: false
|
100
|
+
o.bool '--tolerate-edges',
|
101
|
+
'Don\'t fail if only "edge" (not default ones) nodes accepted/have the wallet',
|
102
|
+
default: false
|
98
103
|
o.boolean '--nohup',
|
99
104
|
'Run it in background, rebooting when a higher version is available in the network',
|
100
105
|
default: false
|
@@ -134,8 +139,8 @@ module Zold
|
|
134
139
|
'Maximum amount of memory we can consume, quit if we take more than that, in Mb (default: 512)',
|
135
140
|
default: 512
|
136
141
|
o.integer '--queue-limit',
|
137
|
-
'The maximum number of wallets to be accepted via PUSH and stored in the queue (default:
|
138
|
-
default:
|
142
|
+
'The maximum number of wallets to be accepted via PUSH and stored in the queue (default: 256)',
|
143
|
+
default: 256
|
139
144
|
o.integer '--gc-age',
|
140
145
|
'Maximum time in seconds to keep an empty and unused wallet on the disk',
|
141
146
|
default: 60 * 60 * 24 * 10
|
@@ -213,8 +218,10 @@ module Zold
|
|
213
218
|
Zold::Remote.new(remotes: @remotes).run(['remote', 'remove', host, port.to_s])
|
214
219
|
@log.info("Removed current node (#{address}) from list of remotes")
|
215
220
|
end
|
221
|
+
hungry = Zold::ThreadPool.new('hungry', log: @log)
|
222
|
+
wts = Zold::HungryWallets.new(@wallets, @remotes, @copies, hungry, log: @log, network: opts['network'])
|
216
223
|
Front.set(:zache, Zache.new)
|
217
|
-
Front.set(:wallets,
|
224
|
+
Front.set(:wallets, wts)
|
218
225
|
Front.set(:remotes, @remotes)
|
219
226
|
Front.set(:copies, @copies)
|
220
227
|
Front.set(:address, address)
|
@@ -222,18 +229,7 @@ module Zold
|
|
222
229
|
Front.set(:opts, opts)
|
223
230
|
Front.set(:dump_errors, opts['dump-errors'])
|
224
231
|
Front.set(:port, opts['bind-port'])
|
225
|
-
node_alias
|
226
|
-
unless node_alias.eql?(address) || node_alias =~ /^[A-Za-z0-9]{4,16}$/
|
227
|
-
raise "Alias should be a 4 to 16 char long alphanumeric string: #{node_alias}"
|
228
|
-
end
|
229
|
-
Front.set(:node_alias, node_alias)
|
230
|
-
invoice = opts[:invoice]
|
231
|
-
unless invoice.include?('@')
|
232
|
-
require_relative 'invoice'
|
233
|
-
invoice = Invoice.new(
|
234
|
-
wallets: @wallets, remotes: @remotes, copies: @copies, log: @log
|
235
|
-
).run(['invoice', invoice, "--network=#{opts['network']}"])
|
236
|
-
end
|
232
|
+
Front.set(:node_alias, node_alias(opts, address))
|
237
233
|
entrance = SafeEntrance.new(
|
238
234
|
NoSpamEntrance.new(
|
239
235
|
NoDupEntrance.new(
|
@@ -241,22 +237,22 @@ module Zold
|
|
241
237
|
SpreadEntrance.new(
|
242
238
|
SyncEntrance.new(
|
243
239
|
Entrance.new(
|
244
|
-
@
|
245
|
-
@remotes, @copies, address,
|
240
|
+
wts, @remotes, @copies, address,
|
246
241
|
log: @log, network: opts['network']
|
247
242
|
),
|
248
243
|
File.join(home, '.zoldata/sync-entrance'),
|
249
244
|
log: @log
|
250
245
|
),
|
251
|
-
|
246
|
+
wts, @remotes, address,
|
252
247
|
log: @log,
|
253
|
-
ignore_score_weakeness: opts['ignore-score-weakness']
|
248
|
+
ignore_score_weakeness: opts['ignore-score-weakness'],
|
249
|
+
tolerate_edges: opts['tolerate-edges']
|
254
250
|
),
|
255
251
|
File.join(home, '.zoldata/async-entrance'),
|
256
252
|
log: @log,
|
257
253
|
queue_limit: opts['queue-limit']
|
258
254
|
),
|
259
|
-
|
255
|
+
wts,
|
260
256
|
log: @log
|
261
257
|
),
|
262
258
|
period: opts['allow-spam'] ? 0 : 60 * 60,
|
@@ -266,7 +262,10 @@ module Zold
|
|
266
262
|
)
|
267
263
|
entrance.start do |ent|
|
268
264
|
Front.set(:entrance, ent)
|
269
|
-
farm = Farm.new(
|
265
|
+
farm = Farm.new(
|
266
|
+
invoice(opts), File.join(home, 'farm'),
|
267
|
+
log: @log, farmer: farmer(opts), strength: opts[:strength]
|
268
|
+
)
|
270
269
|
farm.start(host, opts[:port], threads: opts[:threads]) do |f|
|
271
270
|
Front.set(:farm, f)
|
272
271
|
metronome(f, opts).start do |metronome|
|
@@ -277,11 +276,32 @@ module Zold
|
|
277
276
|
end
|
278
277
|
end
|
279
278
|
end
|
279
|
+
hungry.kill
|
280
280
|
@log.info('Thanks for helping Zold network!')
|
281
281
|
end
|
282
282
|
|
283
283
|
private
|
284
284
|
|
285
|
+
def invoice(opts)
|
286
|
+
invoice = opts['invoice']
|
287
|
+
unless invoice.include?('@')
|
288
|
+
require_relative 'invoice'
|
289
|
+
invoice = Invoice.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
|
290
|
+
['invoice', invoice, "--network=#{opts['network']}"] +
|
291
|
+
(opts['tolerate-edges'] ? ['--tolerate-edges'] : [])
|
292
|
+
)
|
293
|
+
end
|
294
|
+
invoice
|
295
|
+
end
|
296
|
+
|
297
|
+
def node_alias(opts, address)
|
298
|
+
a = opts[:alias] || address
|
299
|
+
unless a.eql?(address) || a =~ /^[A-Za-z0-9]{4,16}$/
|
300
|
+
raise "Alias should be a 4 to 16 char long alphanumeric string: #{a}"
|
301
|
+
end
|
302
|
+
a
|
303
|
+
end
|
304
|
+
|
285
305
|
def farmer(opts)
|
286
306
|
case opts['farmer'].downcase.strip
|
287
307
|
when 'plain'
|
data/lib/zold/commands/push.rb
CHANGED
@@ -58,6 +58,12 @@ Available options:"
|
|
58
58
|
o.bool '--ignore-score-weakness',
|
59
59
|
'Don\'t complain when their score is too weak',
|
60
60
|
default: false
|
61
|
+
o.bool '--tolerate-edges',
|
62
|
+
'Don\'t fail if only "edge" (not default ones) nodes accepted the wallet',
|
63
|
+
default: false
|
64
|
+
o.bool '--quiet-if-missed',
|
65
|
+
'Don\'t fail if the wallet wasn\'t delivered to any remotes',
|
66
|
+
default: false
|
61
67
|
o.array '--ignore-node',
|
62
68
|
'Ignore this node and don\'t push to it',
|
63
69
|
default: []
|
@@ -76,19 +82,26 @@ Available options:"
|
|
76
82
|
private
|
77
83
|
|
78
84
|
def push(id, opts)
|
79
|
-
total =
|
80
|
-
nodes =
|
81
|
-
done =
|
85
|
+
total = Concurrent::AtomicFixnum.new
|
86
|
+
nodes = Concurrent::AtomicFixnum.new
|
87
|
+
done = Concurrent::AtomicFixnum.new
|
88
|
+
defaults = Concurrent::AtomicFixnum.new
|
82
89
|
start = Time.now
|
83
90
|
@remotes.iterate(@log) do |r|
|
84
|
-
nodes
|
85
|
-
total
|
86
|
-
|
91
|
+
nodes.increment
|
92
|
+
total.increment(push_one(id, r, opts))
|
93
|
+
defaults.increment if r.default?
|
94
|
+
done.increment
|
95
|
+
end
|
96
|
+
raise "There are no remote nodes, run 'zold remote reset'" if nodes.value.zero?
|
97
|
+
unless opts['quiet-if-missed']
|
98
|
+
raise "No nodes out of #{nodes} accepted the wallet #{id}" if done.value.zero?
|
99
|
+
if defaults.value.zero? && !opts['tolerate-edges']
|
100
|
+
raise "There are only edge nodes, run 'zold remote reset' or use --tolerate-edges"
|
101
|
+
end
|
87
102
|
end
|
88
|
-
|
89
|
-
|
90
|
-
@log.info("Push finished to #{done} nodes out of #{nodes} in #{Age.new(start)}, \
|
91
|
-
total score for #{id} is #{total}")
|
103
|
+
@log.info("Push finished to #{done.value} nodes (#{defaults.value} defaults) \
|
104
|
+
out of #{nodes.value} in #{Age.new(start)}, total score for #{id} is #{total.value}")
|
92
105
|
end
|
93
106
|
|
94
107
|
def push_one(id, r, opts)
|
data/lib/zold/hungry_wallets.rb
CHANGED
@@ -21,14 +21,43 @@
|
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
23
|
require 'delegate'
|
24
|
+
require_relative 'log'
|
25
|
+
require_relative 'thread_pool'
|
26
|
+
require_relative 'commands/pull'
|
24
27
|
|
28
|
+
# Wallets that PULL what's missing, in the background.
|
29
|
+
#
|
30
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
31
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
32
|
+
# License:: MIT
|
25
33
|
module Zold
|
26
34
|
# Wallets decorator that adds missing wallets to the queue to be pulled later.
|
27
35
|
class HungryWallets < SimpleDelegator
|
28
|
-
|
29
|
-
|
36
|
+
def initialize(wallets, remotes, copies, pool,
|
37
|
+
log: Log::NULL, network: 'test')
|
38
|
+
@wallets = wallets
|
39
|
+
@remotes = remotes
|
40
|
+
@copies = copies
|
41
|
+
@log = log
|
42
|
+
@network = network
|
43
|
+
@pool = pool
|
44
|
+
@queue = Queue.new
|
45
|
+
@pool.add do
|
46
|
+
Endless.new('hungry', log: log).run do
|
47
|
+
id = @queue.pop
|
48
|
+
Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
|
49
|
+
['pull', id.to_s, "--network=#{@network}"]
|
50
|
+
)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
super(wallets)
|
54
|
+
end
|
55
|
+
|
30
56
|
def acq(id, exclusive: false)
|
31
|
-
|
57
|
+
@wallets.acq(id, exclusive: exclusive) do |wallet|
|
58
|
+
@queue << id unless wallet.exists?
|
59
|
+
yield wallet
|
60
|
+
end
|
32
61
|
end
|
33
62
|
end
|
34
63
|
end
|
data/lib/zold/node/entrance.rb
CHANGED
@@ -79,7 +79,7 @@ module Zold
|
|
79
79
|
end
|
80
80
|
modified = Merge.new(
|
81
81
|
wallets: @wallets, copies: copies.root, log: @log
|
82
|
-
).run(['merge', id.to_s])
|
82
|
+
).run(['merge', id.to_s, '--no-baseline'])
|
83
83
|
Clean.new(wallets: @wallets, copies: copies.root, log: @log).run(['clean', id.to_s])
|
84
84
|
copies.remove(localhost, Remotes::PORT)
|
85
85
|
if modified.empty?
|
@@ -41,13 +41,15 @@ require_relative '../commands/clean'
|
|
41
41
|
module Zold
|
42
42
|
# The entrance
|
43
43
|
class SpreadEntrance
|
44
|
-
def initialize(entrance, wallets, remotes, address, log: Log::NULL,
|
44
|
+
def initialize(entrance, wallets, remotes, address, log: Log::NULL,
|
45
|
+
ignore_score_weakeness: false, tolerate_edges: false)
|
45
46
|
@entrance = entrance
|
46
47
|
@wallets = wallets
|
47
48
|
@remotes = remotes
|
48
49
|
@address = address
|
49
50
|
@log = log
|
50
51
|
@ignore_score_weakeness = ignore_score_weakeness
|
52
|
+
@tolerate_edges = tolerate_edges
|
51
53
|
@mutex = Mutex.new
|
52
54
|
@push = ThreadPool.new('spread-entrance')
|
53
55
|
end
|
@@ -75,7 +77,8 @@ module Zold
|
|
75
77
|
Thread.current.thread_variable_set(:wallet, id.to_s)
|
76
78
|
Push.new(wallets: @wallets, remotes: @remotes, log: @log).run(
|
77
79
|
['push', "--ignore-node=#{@address}", id.to_s] +
|
78
|
-
(@ignore_score_weakeness ? ['--ignore-score-weakness'] : [])
|
80
|
+
(@ignore_score_weakeness ? ['--ignore-score-weakness'] : []) +
|
81
|
+
(@tolerate_edges ? ['--tolerate-edges'] : [])
|
79
82
|
)
|
80
83
|
end
|
81
84
|
@mutex.synchronize { @seen.delete(id) }
|
data/lib/zold/remotes.rb
CHANGED
data/lib/zold/sync_wallets.rb
CHANGED
@@ -21,6 +21,7 @@
|
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
23
|
require 'futex'
|
24
|
+
require 'delegate'
|
24
25
|
require_relative 'log'
|
25
26
|
|
26
27
|
# Synchronized collection of wallets.
|
@@ -32,27 +33,12 @@ require_relative 'log'
|
|
32
33
|
# License:: MIT
|
33
34
|
module Zold
|
34
35
|
# Synchronized collection of wallets
|
35
|
-
class SyncWallets
|
36
|
+
class SyncWallets < SimpleDelegator
|
36
37
|
def initialize(wallets, log: Log::NULL, dir: wallets.path)
|
37
38
|
@wallets = wallets
|
38
39
|
@log = log
|
39
40
|
@dir = dir
|
40
|
-
|
41
|
-
|
42
|
-
def to_s
|
43
|
-
@wallets.to_s
|
44
|
-
end
|
45
|
-
|
46
|
-
def path
|
47
|
-
@wallets.path
|
48
|
-
end
|
49
|
-
|
50
|
-
def all
|
51
|
-
@wallets.all
|
52
|
-
end
|
53
|
-
|
54
|
-
def count
|
55
|
-
@wallets.count
|
41
|
+
super(wallets)
|
56
42
|
end
|
57
43
|
|
58
44
|
def acq(id, exclusive: false)
|
data/lib/zold/thread_pool.rb
CHANGED
@@ -44,17 +44,22 @@ module Zold
|
|
44
44
|
idx = Concurrent::AtomicFixnum.new
|
45
45
|
mutex = Mutex.new
|
46
46
|
list = set.dup
|
47
|
-
[threads, set.count].min
|
47
|
+
total = [threads, set.count].min
|
48
|
+
latch = Concurrent::CountDownLatch.new(total)
|
49
|
+
total.times do |i|
|
48
50
|
add do
|
51
|
+
Thread.current.name = "#{@title}-#{i}"
|
49
52
|
loop do
|
50
53
|
r = mutex.synchronize { list.pop }
|
51
54
|
break if r.nil?
|
52
55
|
yield(r, idx.increment - 1)
|
53
56
|
end
|
57
|
+
ensure
|
58
|
+
latch.count_down
|
54
59
|
end
|
55
60
|
end
|
56
|
-
|
57
|
-
|
61
|
+
latch.wait
|
62
|
+
kill
|
58
63
|
end
|
59
64
|
|
60
65
|
# Add a new thread
|
@@ -62,6 +67,7 @@ module Zold
|
|
62
67
|
raise 'Block must be given to start()' unless block_given?
|
63
68
|
latch = Concurrent::CountDownLatch.new(1)
|
64
69
|
thread = Thread.start do
|
70
|
+
Thread.current.name = @title
|
65
71
|
VerboseThread.new(@log).run do
|
66
72
|
latch.count_down
|
67
73
|
yield
|
@@ -75,22 +81,29 @@ module Zold
|
|
75
81
|
@threads << thread
|
76
82
|
end
|
77
83
|
|
84
|
+
def join(sec)
|
85
|
+
@threads.each { |t| t.join(sec) }
|
86
|
+
end
|
87
|
+
|
78
88
|
# Kill them all immediately and close the pool
|
79
89
|
def kill
|
80
90
|
if @threads.empty?
|
81
91
|
@log.debug("Thread pool \"#{@title}\" terminated with no threads")
|
82
92
|
return
|
83
93
|
end
|
84
|
-
@log.
|
94
|
+
@log.debug("Stopping \"#{@title}\" thread pool with #{@threads.count} threads: \
|
85
95
|
#{@threads.map { |t| "#{t.name}/#{t.status}" }.join(', ')}...")
|
86
96
|
start = Time.new
|
87
97
|
@threads.each do |t|
|
88
98
|
(t.thread_variable_get(:kids) || []).each(&:kill)
|
89
99
|
t.kill
|
90
100
|
raise "Failed to join the thread \"#{t.name}\" in \"#{@title}\" pool" unless t.join(0.1)
|
91
|
-
|
101
|
+
Thread.current.thread_variable_set(
|
102
|
+
:kids,
|
103
|
+
(Thread.current.thread_variable_get(:kids) || []) - [t]
|
104
|
+
)
|
92
105
|
end
|
93
|
-
@log.
|
106
|
+
@log.debug("Thread pool \"#{@title}\" terminated all threads in #{Age.new(start)}, \
|
94
107
|
it was alive for #{Age.new(@start)}: #{@threads.map { |t| "#{t.name}/#{t.status}" }.join(', ')}")
|
95
108
|
@threads.clear
|
96
109
|
end
|
data/lib/zold/verbose_thread.rb
CHANGED
data/lib/zold/version.rb
CHANGED
data/test/commands/test_node.rb
CHANGED
@@ -39,11 +39,7 @@ require_relative '../node/fake_node'
|
|
39
39
|
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
40
40
|
# License:: MIT
|
41
41
|
class TestNode < Zold::Test
|
42
|
-
# @todo #306:30min This test is failing from time to time
|
43
|
-
# We should find a way to check that tests involved in thread concurrency
|
44
|
-
# are always working
|
45
42
|
def test_push_and_fetch
|
46
|
-
skip
|
47
43
|
FakeHome.new(log: test_log).run do |home|
|
48
44
|
FakeNode.new(log: test_log).run do |port|
|
49
45
|
wallets = home.wallets
|
@@ -51,7 +47,7 @@ class TestNode < Zold::Test
|
|
51
47
|
remotes = home.remotes
|
52
48
|
remotes.add('localhost', port)
|
53
49
|
Zold::Push.new(wallets: wallets, remotes: remotes, log: test_log).run(
|
54
|
-
['push', '--ignore-score-weakness']
|
50
|
+
['push', '--ignore-score-weakness', '--tolerate-edges']
|
55
51
|
)
|
56
52
|
copies = home.copies(wallet)
|
57
53
|
begin
|
@@ -59,7 +55,7 @@ class TestNode < Zold::Test
|
|
59
55
|
Zold::Fetch.new(
|
60
56
|
wallets: wallets, copies: copies.root,
|
61
57
|
remotes: remotes, log: test_log
|
62
|
-
).run(['fetch', '--ignore-score-weakness'])
|
58
|
+
).run(['fetch', '--ignore-score-weakness', '--tolerate-edges'])
|
63
59
|
rescue StandardError => _
|
64
60
|
sleep 1
|
65
61
|
retry if (retries += 1) < 3
|
data/test/commands/test_pull.rb
CHANGED
@@ -42,7 +42,7 @@ class TestPull < Zold::Test
|
|
42
42
|
stub_request(:get, "http://localhost:4096/wallet/#{id}/size").to_return(status: 200, body: '10000')
|
43
43
|
stub_request(:get, "http://localhost:4096/wallet/#{id}").to_return(status: 200, body: json)
|
44
44
|
Zold::Pull.new(wallets: home.wallets, remotes: remotes, copies: home.copies.root.to_s, log: test_log).run(
|
45
|
-
['--ignore-this-stupid-option', 'pull', id.to_s]
|
45
|
+
['--ignore-this-stupid-option', 'pull', id.to_s, '--tolerate-edges']
|
46
46
|
)
|
47
47
|
home.wallets.acq(Zold::Id.new(id)) do |wallet|
|
48
48
|
assert(wallet.exists?)
|
data/test/commands/test_push.rb
CHANGED
@@ -43,7 +43,7 @@ class TestPush < Zold::Test
|
|
43
43
|
remotes.add('localhost', 80)
|
44
44
|
stub_request(:put, "http://localhost:80/wallet/#{wallet.id}").to_return(status: 304)
|
45
45
|
Zold::Push.new(wallets: home.wallets, remotes: remotes, log: test_log).run(
|
46
|
-
['--ignore-this-stupid-option', 'push', wallet.id.to_s]
|
46
|
+
['--ignore-this-stupid-option', 'push', wallet.id.to_s, '--tolerate-edges']
|
47
47
|
)
|
48
48
|
end
|
49
49
|
end
|
@@ -58,7 +58,7 @@ class TestPush < Zold::Test
|
|
58
58
|
stub_request(:put, "http://localhost:80/wallet/#{wallet_a.id}").to_return(status: 304)
|
59
59
|
stub_request(:put, "http://localhost:80/wallet/#{wallet_b.id}").to_return(status: 304)
|
60
60
|
Zold::Push.new(wallets: home.wallets, remotes: remotes, log: log).run(
|
61
|
-
['--
|
61
|
+
['--tolerate-edges', '--threads=2', 'push', wallet_a.id.to_s, wallet_b.id.to_s]
|
62
62
|
)
|
63
63
|
end
|
64
64
|
end
|
data/test/node/fake_node.rb
CHANGED
@@ -44,8 +44,8 @@ class FakeNode
|
|
44
44
|
RandomPort::Pool::SINGLETON.acquire do |port|
|
45
45
|
node = Thread.new do
|
46
46
|
Thread.current.name = 'fake_node'
|
47
|
+
Thread.current.abort_on_exception = true
|
47
48
|
Zold::VerboseThread.new(@log).run do
|
48
|
-
Thread.current.abort_on_exception = true
|
49
49
|
require_relative '../../lib/zold/commands/node'
|
50
50
|
Zold::Node.new(wallets: home.wallets, remotes: home.remotes, copies: home.copies.root, log: @log).run(
|
51
51
|
[
|
data/test/test__helper.rb
CHANGED
@@ -63,10 +63,14 @@ module Zold
|
|
63
63
|
def assert_equal_wait(expected, max: 30)
|
64
64
|
start = Time.now
|
65
65
|
loop do
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
begin
|
67
|
+
actual = yield
|
68
|
+
if expected == actual
|
69
|
+
assert_equal(expected, actual)
|
70
|
+
break
|
71
|
+
end
|
72
|
+
rescue StandardError => e
|
73
|
+
test_log.debug(e.message)
|
70
74
|
end
|
71
75
|
sleep 1
|
72
76
|
sec = Time.now - start
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
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 'minitest/autorun'
|
24
|
+
require 'webmock/minitest'
|
25
|
+
require_relative 'test__helper'
|
26
|
+
require_relative 'fake_home'
|
27
|
+
require_relative '../lib/zold/key'
|
28
|
+
require_relative '../lib/zold/thread_pool'
|
29
|
+
require_relative '../lib/zold/wallets'
|
30
|
+
require_relative '../lib/zold/hungry_wallets'
|
31
|
+
|
32
|
+
# HungryWallets test.
|
33
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
34
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
35
|
+
# License:: MIT
|
36
|
+
class TestHungryWallets < Zold::Test
|
37
|
+
def test_pulls_wallet
|
38
|
+
FakeHome.new(log: test_log).run do |home|
|
39
|
+
id = Zold::Id.new
|
40
|
+
get = stub_request(:get, "http://localhost:4096/wallet/#{id}/size").to_return(status: 404)
|
41
|
+
remotes = home.remotes
|
42
|
+
remotes.add('localhost', 4096)
|
43
|
+
pool = Zold::ThreadPool.new('test', log: test_log)
|
44
|
+
wallets = Zold::HungryWallets.new(
|
45
|
+
home.wallets, remotes, File.join(home.dir, 'copies'),
|
46
|
+
pool, log: test_log
|
47
|
+
)
|
48
|
+
wallets.acq(id) { |w| assert(!w.exists?) }
|
49
|
+
pool.join(1)
|
50
|
+
assert_requested(get)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/test/test_thread_pool.rb
CHANGED
@@ -69,6 +69,14 @@ class TestThreadPool < Zold::Test
|
|
69
69
|
assert_equal('0 1 2', indexes.to_a.sort.join(' '))
|
70
70
|
end
|
71
71
|
|
72
|
+
def test_runs_with_exceptions
|
73
|
+
assert_raises do
|
74
|
+
Zold::ThreadPool.new('test', log: test_log).run(1) do
|
75
|
+
raise 'intended'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
72
80
|
def test_adds_and_stops
|
73
81
|
pool = Zold::ThreadPool.new('test', log: test_log)
|
74
82
|
pool.add do
|
data/test/test_zold.rb
CHANGED
@@ -34,9 +34,10 @@ require_relative '../lib/zold/age'
|
|
34
34
|
# License:: MIT
|
35
35
|
class TestZold < Zold::Test
|
36
36
|
Dir.new('fixtures/scripts').select { |f| f =~ /\.sh$/ && !f.start_with?('_') }.each do |f|
|
37
|
-
|
37
|
+
method = "test_#{f.gsub(/\.sh$/, '').gsub(/[^a-z]/, '_')}"
|
38
|
+
define_method(method) do
|
38
39
|
start = Time.now
|
39
|
-
test_log.info("\n\n#{
|
40
|
+
test_log.info("\n\n#{method} running (script at #{f})...")
|
40
41
|
Dir.mktmpdir do |dir|
|
41
42
|
FileUtils.cp('fixtures/id_rsa.pub', dir)
|
42
43
|
FileUtils.cp('fixtures/id_rsa', dir)
|
data/zold.gemspec
CHANGED
@@ -61,12 +61,12 @@ and suggests a different architecture for digital wallet maintenance.'
|
|
61
61
|
s.test_files = s.files.grep(%r{^(test|features)/})
|
62
62
|
s.rdoc_options = ['--charset=UTF-8']
|
63
63
|
s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
|
64
|
-
s.add_runtime_dependency 'backtrace', '0
|
64
|
+
s.add_runtime_dependency 'backtrace', '~>0'
|
65
65
|
s.add_runtime_dependency 'concurrent-ruby', '1.1.3'
|
66
66
|
s.add_runtime_dependency 'cucumber', '3.1.2' # has to stay here for Heroku
|
67
67
|
s.add_runtime_dependency 'diffy', '3.2.1'
|
68
|
-
s.add_runtime_dependency 'futex', '0
|
69
|
-
s.add_runtime_dependency 'get_process_mem', '0.2
|
68
|
+
s.add_runtime_dependency 'futex', '~>0'
|
69
|
+
s.add_runtime_dependency 'get_process_mem', '~>0.2'
|
70
70
|
s.add_runtime_dependency 'json', '2.1.0'
|
71
71
|
s.add_runtime_dependency 'memory_profiler', '0.9.12'
|
72
72
|
s.add_runtime_dependency 'openssl', '2.1.2'
|
@@ -79,12 +79,12 @@ and suggests a different architecture for digital wallet maintenance.'
|
|
79
79
|
s.add_runtime_dependency 'slop', '4.6.2'
|
80
80
|
s.add_runtime_dependency 'sys-proctable', '1.2.1'
|
81
81
|
s.add_runtime_dependency 'thin', '1.7.2'
|
82
|
-
s.add_runtime_dependency 'threads', '0
|
82
|
+
s.add_runtime_dependency 'threads', '~>0'
|
83
83
|
s.add_runtime_dependency 'typhoeus', '1.3.1'
|
84
84
|
s.add_runtime_dependency 'usagewatch_ext', '0.2.1'
|
85
|
-
s.add_runtime_dependency 'xcop', '0
|
86
|
-
s.add_runtime_dependency 'zache', '0
|
87
|
-
s.add_runtime_dependency 'zold-score', '0.4.
|
85
|
+
s.add_runtime_dependency 'xcop', '~>0'
|
86
|
+
s.add_runtime_dependency 'zache', '~>0'
|
87
|
+
s.add_runtime_dependency 'zold-score', '0.4.4'
|
88
88
|
s.add_development_dependency 'codecov', '0.1.13'
|
89
89
|
s.add_development_dependency 'minitest', '5.11.3'
|
90
90
|
s.add_development_dependency 'minitest-fail-fast', '0.1.0'
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.18.
|
4
|
+
version: 0.18.9
|
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-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backtrace
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: concurrent-ruby
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,30 +70,30 @@ dependencies:
|
|
70
70
|
name: futex
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0
|
75
|
+
version: '0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0
|
82
|
+
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: get_process_mem
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.2
|
89
|
+
version: '0.2'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.2
|
96
|
+
version: '0.2'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: json
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -266,16 +266,16 @@ dependencies:
|
|
266
266
|
name: threads
|
267
267
|
requirement: !ruby/object:Gem::Requirement
|
268
268
|
requirements:
|
269
|
-
- -
|
269
|
+
- - "~>"
|
270
270
|
- !ruby/object:Gem::Version
|
271
|
-
version: 0
|
271
|
+
version: '0'
|
272
272
|
type: :runtime
|
273
273
|
prerelease: false
|
274
274
|
version_requirements: !ruby/object:Gem::Requirement
|
275
275
|
requirements:
|
276
|
-
- -
|
276
|
+
- - "~>"
|
277
277
|
- !ruby/object:Gem::Version
|
278
|
-
version: 0
|
278
|
+
version: '0'
|
279
279
|
- !ruby/object:Gem::Dependency
|
280
280
|
name: typhoeus
|
281
281
|
requirement: !ruby/object:Gem::Requirement
|
@@ -308,44 +308,44 @@ dependencies:
|
|
308
308
|
name: xcop
|
309
309
|
requirement: !ruby/object:Gem::Requirement
|
310
310
|
requirements:
|
311
|
-
- -
|
311
|
+
- - "~>"
|
312
312
|
- !ruby/object:Gem::Version
|
313
|
-
version: '0
|
313
|
+
version: '0'
|
314
314
|
type: :runtime
|
315
315
|
prerelease: false
|
316
316
|
version_requirements: !ruby/object:Gem::Requirement
|
317
317
|
requirements:
|
318
|
-
- -
|
318
|
+
- - "~>"
|
319
319
|
- !ruby/object:Gem::Version
|
320
|
-
version: '0
|
320
|
+
version: '0'
|
321
321
|
- !ruby/object:Gem::Dependency
|
322
322
|
name: zache
|
323
323
|
requirement: !ruby/object:Gem::Requirement
|
324
324
|
requirements:
|
325
|
-
- -
|
325
|
+
- - "~>"
|
326
326
|
- !ruby/object:Gem::Version
|
327
|
-
version: 0
|
327
|
+
version: '0'
|
328
328
|
type: :runtime
|
329
329
|
prerelease: false
|
330
330
|
version_requirements: !ruby/object:Gem::Requirement
|
331
331
|
requirements:
|
332
|
-
- -
|
332
|
+
- - "~>"
|
333
333
|
- !ruby/object:Gem::Version
|
334
|
-
version: 0
|
334
|
+
version: '0'
|
335
335
|
- !ruby/object:Gem::Dependency
|
336
336
|
name: zold-score
|
337
337
|
requirement: !ruby/object:Gem::Requirement
|
338
338
|
requirements:
|
339
339
|
- - '='
|
340
340
|
- !ruby/object:Gem::Version
|
341
|
-
version: 0.4.
|
341
|
+
version: 0.4.4
|
342
342
|
type: :runtime
|
343
343
|
prerelease: false
|
344
344
|
version_requirements: !ruby/object:Gem::Requirement
|
345
345
|
requirements:
|
346
346
|
- - '='
|
347
347
|
- !ruby/object:Gem::Version
|
348
|
-
version: 0.4.
|
348
|
+
version: 0.4.4
|
349
349
|
- !ruby/object:Gem::Dependency
|
350
350
|
name: codecov
|
351
351
|
requirement: !ruby/object:Gem::Requirement
|
@@ -656,6 +656,7 @@ files:
|
|
656
656
|
- test/test_gem.rb
|
657
657
|
- test/test_hexnum.rb
|
658
658
|
- test/test_http.rb
|
659
|
+
- test/test_hungry_wallets.rb
|
659
660
|
- test/test_id.rb
|
660
661
|
- test/test_json_page.rb
|
661
662
|
- test/test_key.rb
|
@@ -689,7 +690,7 @@ licenses:
|
|
689
690
|
- MIT
|
690
691
|
metadata: {}
|
691
692
|
post_install_message: |-
|
692
|
-
Thanks for installing Zold 0.18.
|
693
|
+
Thanks for installing Zold 0.18.9!
|
693
694
|
Study our White Paper: https://papers.zold.io/wp.pdf
|
694
695
|
Read our blog posts: https://blog.zold.io
|
695
696
|
Try online wallet at: https://wts.zold.io
|
@@ -765,6 +766,7 @@ test_files:
|
|
765
766
|
- test/test_gem.rb
|
766
767
|
- test/test_hexnum.rb
|
767
768
|
- test/test_http.rb
|
769
|
+
- test/test_hungry_wallets.rb
|
768
770
|
- test/test_id.rb
|
769
771
|
- test/test_json_page.rb
|
770
772
|
- test/test_key.rb
|