zold 0.9.10 → 0.9.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|