zold 0.18.8 → 0.18.9
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/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
|