zold 0.9.10 → 0.9.11
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/commands/fetch.rb +12 -34
- data/lib/zold/commands/node.rb +3 -0
- data/lib/zold/commands/push.rb +11 -28
- data/lib/zold/commands/remote.rb +9 -36
- data/lib/zold/commands/taxes.rb +8 -30
- data/lib/zold/http.rb +1 -1
- data/lib/zold/node/farm.rb +7 -0
- data/lib/zold/remotes.rb +40 -11
- data/lib/zold/score.rb +2 -4
- data/lib/zold/version.rb +1 -1
- data/test/test_remotes.rb +3 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76a4eedb7d10def207298c7f125a6c9fbe392bec
|
4
|
+
data.tar.gz: 04f8e073cea64e11e7989d1c943a629295e45425
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b70bdc247fa5230a8a6709578d603f1e7a87f8b3a758abc663dc5cf603136f49f8049a1df90fb709c728cf8a9d8b4ca9fcedbc9b0e15ee209ec2556cffe996be
|
7
|
+
data.tar.gz: 9dbfe9ece397a9ef7a6ee65e771ac560fe4aacc2ceb1ac77d291bb53b0d263ddc4349ae45e00ecc8c47564dab15f304a639e6440828325a7cded1a2e7de4db52
|
data/lib/zold/commands/fetch.rb
CHANGED
@@ -64,50 +64,28 @@ Available options:"
|
|
64
64
|
|
65
65
|
def fetch(id, cps, opts)
|
66
66
|
total = 0
|
67
|
-
@remotes.
|
68
|
-
|
69
|
-
|
70
|
-
total += 1
|
71
|
-
else
|
72
|
-
@remotes.error(r[:host], r[:port])
|
73
|
-
end
|
67
|
+
@remotes.iterate(@log) do |r|
|
68
|
+
fetch_one(id, r, cps, opts)
|
69
|
+
total += 1
|
74
70
|
end
|
75
71
|
@log.debug("#{total} copies of #{id} fetched, there are #{cps.all.count} available locally")
|
76
72
|
end
|
77
73
|
|
78
74
|
def fetch_one(id, r, cps, opts)
|
79
|
-
|
80
|
-
|
81
|
-
@log.info("#{address} ignored because of --ignore-node")
|
82
|
-
return false
|
83
|
-
end
|
84
|
-
uri = URI("#{r[:home]}wallet/#{id}")
|
85
|
-
res = Http.new(uri).get
|
86
|
-
if res.code == '404'
|
87
|
-
@log.info("#{address} wallet #{id} #{Rainbow('not found').red}")
|
88
|
-
return false
|
89
|
-
end
|
90
|
-
unless res.code == '200'
|
91
|
-
@log.error("#{address} #{Rainbow(res.code).red}/#{res.message} at #{uri}")
|
75
|
+
if opts['ignore-node'].include?(r.to_s)
|
76
|
+
@log.info("#{r} ignored because of --ignore-node")
|
92
77
|
return false
|
93
78
|
end
|
79
|
+
res = r.http("/wallet/#{id}").get
|
80
|
+
raise "Wallet #{id} not found" if res.code == '404'
|
81
|
+
raise "#{res.code} \"#{res.message}\"" unless res.code == '200'
|
94
82
|
json = JSON.parse(res.body)
|
95
83
|
score = Score.parse_json(json['score'])
|
96
|
-
unless score.valid?
|
97
|
-
|
98
|
-
|
99
|
-
end
|
100
|
-
if score.expired?
|
101
|
-
@log.error("#{address}: score expired: #{score}")
|
102
|
-
return false
|
103
|
-
end
|
104
|
-
if score.strength < Score::STRENGTH && !opts['ignore-score-weakness']
|
105
|
-
@log.error("#{address} score is too weak (#{score.strength}<#{Score::STRENGTH}): #{score}")
|
106
|
-
return false
|
107
|
-
end
|
84
|
+
raise "Invalid score #{score}" unless score.valid?
|
85
|
+
raise "Score expired #{score}" if score.expired?
|
86
|
+
raise "Score is too weak #{score.strength}" if score.strength < Score::STRENGTH && !opts['ignore-score-weakness']
|
108
87
|
cps.add(json['body'], score.host, score.port, score.value)
|
109
|
-
@log.info("#{
|
110
|
-
true
|
88
|
+
@log.info("#{r} #{json['body'].length}b/#{Rainbow(score.value).green} (#{json['version']})")
|
111
89
|
end
|
112
90
|
end
|
113
91
|
end
|
data/lib/zold/commands/node.rb
CHANGED
@@ -112,6 +112,9 @@ module Zold
|
|
112
112
|
threads: opts[:threads], strength: opts[:strength]
|
113
113
|
)
|
114
114
|
Zold::Front.set(:farm, farm)
|
115
|
+
Thread.start do
|
116
|
+
Zold::Remote.new(remotes: remotes, farm: farm, log: @log).run(%w[remote update]) unless best.nil?
|
117
|
+
end
|
115
118
|
@log.debug('Starting up the web front...')
|
116
119
|
begin
|
117
120
|
Zold::Front.run!
|
data/lib/zold/commands/push.rb
CHANGED
@@ -49,44 +49,27 @@ Available options:"
|
|
49
49
|
mine = Args.new(opts, @log).take || return
|
50
50
|
mine = @wallets.all if mine.empty?
|
51
51
|
mine.each do |id|
|
52
|
-
|
52
|
+
wallet = @wallets.find(Id.new(id))
|
53
|
+
raise "The wallet #{id} is absent" unless wallet.exists?
|
54
|
+
push(wallet, opts)
|
53
55
|
end
|
54
56
|
end
|
55
57
|
|
56
58
|
def push(wallet, _)
|
57
|
-
raise 'The wallet is absent' unless wallet.exists?
|
58
59
|
total = 0
|
59
|
-
@remotes.
|
60
|
-
|
61
|
-
response = Http.new(uri).put(File.read(wallet.path))
|
60
|
+
@remotes.iterate(@log) do |r|
|
61
|
+
response = r.http("/wallet/#{wallet.id}").put(File.read(wallet.path))
|
62
62
|
if response.code == '304'
|
63
|
-
@log.info("#{
|
64
|
-
next
|
65
|
-
end
|
66
|
-
unless response.code == '200'
|
67
|
-
@remotes.error(r[:host], r[:port])
|
68
|
-
@log.error("#{uri} failed as #{response.code}/#{response.message}")
|
69
|
-
@log.debug(response.body) unless response.body.empty?
|
63
|
+
@log.info("#{r}: same version there")
|
70
64
|
next
|
71
65
|
end
|
66
|
+
raise "#{response.code} \"#{response.message}\" at #{response.body}" unless response.code == '200'
|
72
67
|
json = JSON.parse(response.body)['score']
|
73
68
|
score = Score.parse_json(json)
|
74
|
-
unless score.valid?
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
end
|
79
|
-
if score.expired?
|
80
|
-
@remotes.error(r[:host], r[:port])
|
81
|
-
@log.error("#{uri} expired score: #{score}")
|
82
|
-
next
|
83
|
-
end
|
84
|
-
if score.strength < Score::STRENGTH
|
85
|
-
@remotes.error(r[:host], r[:port])
|
86
|
-
@log.error("#{uri} score is too weak")
|
87
|
-
next
|
88
|
-
end
|
89
|
-
@log.info("#{uri} accepted: #{Rainbow(score.value).green}")
|
69
|
+
raise "Invalid score #{score}" unless score.valid?
|
70
|
+
raise "Expired score #{score}" if score.expired?
|
71
|
+
raise "Score is too weak #{score}" if score.strength < Score::STRENGTH
|
72
|
+
@log.info("#{r} accepted: #{Rainbow(score.value).green}")
|
90
73
|
total += score.value
|
91
74
|
end
|
92
75
|
@log.info("Total score is #{total}")
|
data/lib/zold/commands/remote.rb
CHANGED
@@ -115,42 +115,15 @@ Available options:"
|
|
115
115
|
|
116
116
|
def update(opts, deep = true)
|
117
117
|
capacity = []
|
118
|
-
@remotes.
|
119
|
-
|
120
|
-
res
|
121
|
-
|
122
|
-
@remotes.error(r[:host], r[:port])
|
123
|
-
@log.info("#{Rainbow(r[:host]).red} #{res.code} \"#{res.message}\" #{uri}")
|
124
|
-
next
|
125
|
-
end
|
126
|
-
begin
|
127
|
-
json = JSON.parse(res.body)
|
128
|
-
rescue JSON::ParserError => e
|
129
|
-
error(r[:host], r[:port])
|
130
|
-
@log.info("#{Rainbow(r[:host]).red} \"#{e.message}\": #{res.body}")
|
131
|
-
next
|
132
|
-
end
|
118
|
+
@remotes.iterate(@log) do |r|
|
119
|
+
res = r.http('/remotes').get
|
120
|
+
raise "#{res.code} \"#{res.message}\"" unless res.code == '200'
|
121
|
+
json = JSON.parse(res.body)
|
133
122
|
score = Score.parse_json(json['score'])
|
134
|
-
unless score.valid?
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
end
|
139
|
-
if score.expired?
|
140
|
-
error(r[:host], r[:port])
|
141
|
-
@log.info("#{Rainbow(r[:host]).red} expired score: #{score}")
|
142
|
-
next
|
143
|
-
end
|
144
|
-
if score.strength < Score::STRENGTH && !opts['ignore-score-weakness']
|
145
|
-
error(r[:host], r[:port])
|
146
|
-
@log.info("#{Rainbow(r[:host]).red} score too weak: #{score.strength}")
|
147
|
-
next
|
148
|
-
end
|
149
|
-
if r[:host] != score.host || r[:port] != score.port
|
150
|
-
@remotes.error(r[:host], r[:port])
|
151
|
-
@remotes.add(score.host, score.port)
|
152
|
-
@log.info("#{r[:host]}:#{r[:port]} renamed to #{score.host}:#{score.port}")
|
153
|
-
end
|
123
|
+
raise "Invalid score #{score}" unless score.valid?
|
124
|
+
raise "Expired score #{score}" if score.expired?
|
125
|
+
raise "Score too weak: #{score.strength}" if score.strength < Score::STRENGTH && !opts['ignore-score-weakness']
|
126
|
+
raise "Masqueraded as #{score.host}:#{score.port}" if r.host != score.host || r.port != score.port
|
154
127
|
@remotes.rescore(score.host, score.port, score.value)
|
155
128
|
if deep
|
156
129
|
json['all'].each do |s|
|
@@ -158,7 +131,7 @@ Available options:"
|
|
158
131
|
end
|
159
132
|
end
|
160
133
|
capacity << { host: score.host, port: score.port, count: json['all'].count }
|
161
|
-
@log.info("#{r
|
134
|
+
@log.info("#{r}: #{Rainbow(score.value).green} (#{json['version']})")
|
162
135
|
end
|
163
136
|
max_capacity = capacity.map { |c| c[:count] }.max || 0
|
164
137
|
capacity.each do |c|
|
data/lib/zold/commands/taxes.rb
CHANGED
@@ -117,37 +117,15 @@ Available options:"
|
|
117
117
|
|
118
118
|
def top_scores
|
119
119
|
best = []
|
120
|
-
@remotes.
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
unless res.code == '200'
|
125
|
-
@log.info("#{name}: #{Rainbow(res.code).red} \"#{res.message}\" at #{uri}")
|
126
|
-
next
|
127
|
-
end
|
128
|
-
begin
|
129
|
-
json = JSON.parse(res.body)
|
130
|
-
rescue JSON::ParserError => e
|
131
|
-
@log.info("#{name}: #{Rainbow('broken').red} JSON \"#{e.message}\": #{res.body}")
|
132
|
-
next
|
133
|
-
end
|
120
|
+
@remotes.iterate(@log) do |r|
|
121
|
+
res = r.http.get
|
122
|
+
raise "#{res.code} \"#{res.message}\" at #{res.body}" unless res.code == '200'
|
123
|
+
json = JSON.parse(res.body)
|
134
124
|
score = Score.parse_json(json['score'])
|
135
|
-
unless score.valid?
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
if score.expired?
|
140
|
-
@log.info("#{name}: #{Rainbow('expired').red} score")
|
141
|
-
next
|
142
|
-
end
|
143
|
-
if score.strength < Score::STRENGTH
|
144
|
-
@log.info("#{name} score #{Rainbow(score.value).red} is too weak (<#{Score::STRENGTH})")
|
145
|
-
next
|
146
|
-
end
|
147
|
-
if score.value < Tax::EXACT_SCORE
|
148
|
-
@log.info("#{name} score #{Rainbow(score.value).red} is too small (<#{Tax::EXACT_SCORE})")
|
149
|
-
next
|
150
|
-
end
|
125
|
+
raise "Invalid score #{score}" unless score.valid?
|
126
|
+
raise "Expired score #{score}" if score.expired?
|
127
|
+
raise "Score is too weak (<#{Score::STRENGTH}) #{score}" if score.strength < Score::STRENGTH
|
128
|
+
raise "Score is too small (<#{Tax::EXACT_SCORE})" if score.value < Tax::EXACT_SCORE
|
151
129
|
@log.info("#{score.host}:#{score.port}: #{Rainbow(score.value).green}")
|
152
130
|
best << score
|
153
131
|
end
|
data/lib/zold/http.rb
CHANGED
@@ -75,7 +75,7 @@ module Zold
|
|
75
75
|
'Connection': 'close'
|
76
76
|
}
|
77
77
|
headers[Http::VERSION_HEADER] = VERSION
|
78
|
-
headers[Http::SCORE_HEADER] = score.reduced(4).to_s if @score.valid? && @score.value >= 3 && !score.expired?
|
78
|
+
headers[Http::SCORE_HEADER] = @score.reduced(4).to_s if @score.valid? && @score.value >= 3 && !score.expired?
|
79
79
|
headers
|
80
80
|
end
|
81
81
|
end
|
data/lib/zold/node/farm.rb
CHANGED
data/lib/zold/remotes.rb
CHANGED
@@ -21,6 +21,7 @@
|
|
21
21
|
require 'csv'
|
22
22
|
require 'uri'
|
23
23
|
require 'fileutils'
|
24
|
+
require_relative 'node/farm'
|
24
25
|
|
25
26
|
# The list of remotes.
|
26
27
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -29,6 +30,7 @@ require 'fileutils'
|
|
29
30
|
module Zold
|
30
31
|
# All remotes
|
31
32
|
class Remotes
|
33
|
+
# The default TCP port all nodes are supposed to use.
|
32
34
|
PORT = 4096
|
33
35
|
|
34
36
|
# Empty, for standalone mode
|
@@ -36,10 +38,34 @@ module Zold
|
|
36
38
|
def all
|
37
39
|
[]
|
38
40
|
end
|
41
|
+
|
42
|
+
def iterate(_)
|
43
|
+
# Nothing to do here
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# One remote.
|
48
|
+
class Remote
|
49
|
+
attr_reader :host, :port
|
50
|
+
def initialize(host, port, score)
|
51
|
+
@host = host
|
52
|
+
@port = port
|
53
|
+
@score = score
|
54
|
+
end
|
55
|
+
|
56
|
+
def http(path = '/')
|
57
|
+
uri = URI("http://#{@host}:#{@port}#{path}")
|
58
|
+
Http.new(uri, @score)
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
"#{@host}:#{@port}"
|
63
|
+
end
|
39
64
|
end
|
40
65
|
|
41
|
-
def initialize(file)
|
66
|
+
def initialize(file, farm = Farm::Empty.new)
|
42
67
|
@file = file
|
68
|
+
@farm = farm
|
43
69
|
end
|
44
70
|
|
45
71
|
def all
|
@@ -89,16 +115,19 @@ module Zold
|
|
89
115
|
save(list)
|
90
116
|
end
|
91
117
|
|
92
|
-
def
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
118
|
+
def iterate(log)
|
119
|
+
best = @farm.best[0]
|
120
|
+
require_relative 'score'
|
121
|
+
score = best.nil? ? Score::ZERO : best
|
122
|
+
all.each do |r|
|
123
|
+
begin
|
124
|
+
yield Remotes::Remote.new(r[:host], r[:port], score)
|
125
|
+
rescue StandardError => e
|
126
|
+
error(r[:host], r[:port])
|
127
|
+
log.info("#{Rainbow("#{r[:host]}:#{r[:port]}").red}: #{e.message}")
|
128
|
+
log.debug(e.backtrace[0..5].join("\n\t"))
|
129
|
+
end
|
130
|
+
end
|
102
131
|
end
|
103
132
|
|
104
133
|
def error(host, port = Remotes::PORT)
|
data/lib/zold/score.rb
CHANGED
@@ -48,10 +48,8 @@ module Zold
|
|
48
48
|
@strength = strength
|
49
49
|
end
|
50
50
|
|
51
|
-
|
52
|
-
|
53
|
-
Remotes::PORT, 'NOPREFIX@ffffffffffffffff'
|
54
|
-
)
|
51
|
+
# The default no-value score.
|
52
|
+
ZERO = Score.new(Time.now, 'localhost', 80, 'NOPREFIX@ffffffffffffffff')
|
55
53
|
|
56
54
|
def self.parse_json(json)
|
57
55
|
raise "Time in JSON is broken: #{json}" unless json['time'] =~ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/
|
data/lib/zold/version.rb
CHANGED
data/test/test_remotes.rb
CHANGED
@@ -65,7 +65,9 @@ class TestRemotes < Minitest::Test
|
|
65
65
|
remotes = Zold::Remotes.new(file)
|
66
66
|
remotes.add('127.0.0.1', 80)
|
67
67
|
remotes.rescore('127.0.0.1', 80, 15)
|
68
|
-
|
68
|
+
remotes.all.each do |r|
|
69
|
+
assert_equal(15, r[:score])
|
70
|
+
end
|
69
71
|
end
|
70
72
|
end
|
71
73
|
end
|