zold 0.16.27 → 0.16.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/zold +19 -8
- data/fixtures/scripts/distribute-wallet.sh +1 -1
- data/fixtures/scripts/pull-on-start.sh +1 -1
- data/fixtures/scripts/push-and-pull.sh +1 -1
- data/fixtures/scripts/spread-wallets.sh +1 -1
- data/lib/zold/commands/alias.rb +4 -1
- data/lib/zold/commands/calculate.rb +4 -1
- data/lib/zold/commands/clean.rb +1 -1
- data/lib/zold/commands/create.rb +6 -3
- data/lib/zold/commands/diff.rb +4 -1
- data/lib/zold/commands/fetch.rb +4 -1
- data/lib/zold/commands/invoice.rb +4 -1
- data/lib/zold/commands/list.rb +12 -4
- data/lib/zold/commands/merge.rb +8 -1
- data/lib/zold/commands/next.rb +4 -1
- data/lib/zold/commands/node.rb +6 -3
- data/lib/zold/commands/pay.rb +4 -1
- data/lib/zold/commands/propagate.rb +4 -1
- data/lib/zold/commands/pull.rb +4 -1
- data/lib/zold/commands/push.rb +4 -1
- data/lib/zold/commands/remote.rb +6 -3
- data/lib/zold/commands/remove.rb +4 -1
- data/lib/zold/commands/routines/reconnect.rb +1 -1
- data/lib/zold/commands/routines/spread.rb +1 -1
- data/lib/zold/commands/show.rb +7 -3
- data/lib/zold/commands/taxes.rb +4 -1
- data/lib/zold/commands/thread_badge.rb +47 -0
- data/lib/zold/copies.rb +1 -1
- data/lib/zold/endless.rb +1 -1
- data/lib/zold/http.rb +3 -3
- data/lib/zold/key.rb +3 -0
- data/lib/zold/log.rb +52 -111
- data/lib/zold/metronome.rb +12 -10
- data/lib/zold/node/async_entrance.rb +2 -2
- data/lib/zold/node/entrance.rb +1 -1
- data/lib/zold/node/farm.rb +1 -1
- data/lib/zold/node/farmers.rb +1 -1
- data/lib/zold/node/front.rb +5 -5
- data/lib/zold/node/nodup_entrance.rb +1 -1
- data/lib/zold/node/spread_entrance.rb +1 -1
- data/lib/zold/node/sync_entrance.rb +1 -1
- data/lib/zold/patch.rb +2 -2
- data/lib/zold/remotes.rb +1 -1
- data/lib/zold/signature.rb +5 -1
- data/lib/zold/sync_wallets.rb +1 -1
- data/lib/zold/upgrades.rb +1 -1
- data/lib/zold/verbose_thread.rb +1 -1
- data/lib/zold/version.rb +1 -1
- data/lib/zold/version_file.rb +1 -1
- data/lib/zold/wallet.rb +2 -2
- data/resources/root.pub +14 -0
- data/test/commands/test_list.rb +2 -1
- data/test/commands/test_remote.rb +35 -4
- data/test/commands/test_show.rb +1 -1
- data/test/fake_home.rb +1 -1
- data/test/node/fake_node.rb +3 -2
- data/test/node/test_farm.rb +1 -1
- data/test/test__helper.rb +4 -3
- data/test/test_dir_items.rb +1 -1
- data/test/test_http.rb +44 -6
- data/test/test_key.rb +7 -0
- data/test/test_log.rb +12 -1
- data/test/test_remotes.rb +1 -1
- data/test/test_signature.rb +1 -0
- data/test/test_verbose_thread.rb +3 -3
- data/test/test_zold.rb +4 -3
- data/zold.gemspec +3 -2
- metadata +8 -5
data/lib/zold/commands/push.rb
CHANGED
@@ -24,6 +24,7 @@ require 'rainbow'
|
|
24
24
|
require 'slop'
|
25
25
|
require 'json'
|
26
26
|
require 'net/http'
|
27
|
+
require_relative 'thread_badge'
|
27
28
|
require_relative 'args'
|
28
29
|
require_relative '../age'
|
29
30
|
require_relative '../size'
|
@@ -39,7 +40,9 @@ require_relative '../json_page'
|
|
39
40
|
module Zold
|
40
41
|
# Wallet pushing command
|
41
42
|
class Push
|
42
|
-
|
43
|
+
prepend ThreadBadge
|
44
|
+
|
45
|
+
def initialize(wallets:, remotes:, log: Log::NULL)
|
43
46
|
@wallets = wallets
|
44
47
|
@remotes = remotes
|
45
48
|
@log = log
|
data/lib/zold/commands/remote.rb
CHANGED
@@ -27,6 +27,7 @@ require 'net/http'
|
|
27
27
|
require 'json'
|
28
28
|
require 'time'
|
29
29
|
require 'zold/score'
|
30
|
+
require_relative 'thread_badge'
|
30
31
|
require_relative 'args'
|
31
32
|
require_relative '../node/farm'
|
32
33
|
require_relative '../log'
|
@@ -44,7 +45,9 @@ require_relative '../gem'
|
|
44
45
|
module Zold
|
45
46
|
# Remote command
|
46
47
|
class Remote
|
47
|
-
|
48
|
+
prepend ThreadBadge
|
49
|
+
|
50
|
+
def initialize(remotes:, farm: Farm::Empty.new, log: Log::NULL)
|
48
51
|
@remotes = remotes
|
49
52
|
@farm = farm
|
50
53
|
@log = log
|
@@ -103,9 +106,9 @@ Available options:"
|
|
103
106
|
'The amount of update cycles to run, in order to fetch as many nodes as possible (default: 2)',
|
104
107
|
default: 2
|
105
108
|
o.string '--network',
|
106
|
-
"The name of the network we work in (default: #{Wallet::
|
109
|
+
"The name of the network we work in (default: #{Wallet::MAINET}",
|
107
110
|
required: true,
|
108
|
-
default: Wallet::
|
111
|
+
default: Wallet::MAINET
|
109
112
|
o.bool '--reboot',
|
110
113
|
'Exit if any node reports version higher than we have',
|
111
114
|
default: false
|
data/lib/zold/commands/remove.rb
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
|
23
23
|
require 'slop'
|
24
24
|
require 'rainbow'
|
25
|
+
require_relative 'thread_badge'
|
25
26
|
require_relative 'args'
|
26
27
|
require_relative '../log'
|
27
28
|
|
@@ -32,7 +33,9 @@ require_relative '../log'
|
|
32
33
|
module Zold
|
33
34
|
# REMOVE command
|
34
35
|
class Remove
|
35
|
-
|
36
|
+
prepend ThreadBadge
|
37
|
+
|
38
|
+
def initialize(wallets:, log: Log::NULL)
|
36
39
|
@wallets = wallets
|
37
40
|
@log = log
|
38
41
|
end
|
@@ -32,7 +32,7 @@ module Zold
|
|
32
32
|
module Routines
|
33
33
|
# Reconnect to the network
|
34
34
|
class Reconnect
|
35
|
-
def initialize(opts, remotes, farm = Farm::Empty.new, network: 'test', log: Log::
|
35
|
+
def initialize(opts, remotes, farm = Farm::Empty.new, network: 'test', log: Log::NULL)
|
36
36
|
@opts = opts
|
37
37
|
@remotes = remotes
|
38
38
|
@farm = farm
|
data/lib/zold/commands/show.rb
CHANGED
@@ -22,6 +22,7 @@
|
|
22
22
|
|
23
23
|
require 'slop'
|
24
24
|
require 'rainbow'
|
25
|
+
require_relative 'thread_badge'
|
25
26
|
require_relative 'args'
|
26
27
|
require_relative '../log'
|
27
28
|
require_relative '../id'
|
@@ -35,8 +36,11 @@ require_relative '../wallet'
|
|
35
36
|
module Zold
|
36
37
|
# Show command
|
37
38
|
class Show
|
38
|
-
|
39
|
+
prepend ThreadBadge
|
40
|
+
|
41
|
+
def initialize(wallets:, copies:, log: Log::NULL)
|
39
42
|
@wallets = wallets
|
43
|
+
@copies = copies
|
40
44
|
@log = log
|
41
45
|
end
|
42
46
|
|
@@ -49,7 +53,7 @@ Available options:"
|
|
49
53
|
mine = Args.new(opts, @log).take || return
|
50
54
|
if mine.empty?
|
51
55
|
require_relative 'list'
|
52
|
-
List.new(wallets: @wallets, log: @log).run(args)
|
56
|
+
List.new(wallets: @wallets, copies: @copies, log: @log).run(args)
|
53
57
|
else
|
54
58
|
total = Amount::ZERO
|
55
59
|
mine.map { |i| Id.new(i) }.each do |id|
|
@@ -69,7 +73,7 @@ Available options:"
|
|
69
73
|
@log.info(t.to_text)
|
70
74
|
end
|
71
75
|
msg = "The balance of #{wallet}: #{balance}"
|
72
|
-
msg += " (net:#{wallet.network})" if wallet.network != Wallet::
|
76
|
+
msg += " (net:#{wallet.network})" if wallet.network != Wallet::MAINET
|
73
77
|
@log.info(msg)
|
74
78
|
balance
|
75
79
|
end
|
data/lib/zold/commands/taxes.rb
CHANGED
@@ -24,6 +24,7 @@ require 'slop'
|
|
24
24
|
require 'json'
|
25
25
|
require 'rainbow'
|
26
26
|
require 'zold/score'
|
27
|
+
require_relative 'thread_badge'
|
27
28
|
require_relative 'args'
|
28
29
|
require_relative 'pay'
|
29
30
|
require_relative '../log'
|
@@ -51,7 +52,9 @@ module Zold
|
|
51
52
|
# just selects the most suitable wallet to transfer taxes to and sends
|
52
53
|
# the payment. More details you can find in the White Paper.
|
53
54
|
class Taxes
|
54
|
-
|
55
|
+
prepend ThreadBadge
|
56
|
+
|
57
|
+
def initialize(wallets:, remotes:, log: Log::NULL)
|
55
58
|
@wallets = wallets
|
56
59
|
@remotes = remotes
|
57
60
|
@log = log
|
@@ -0,0 +1,47 @@
|
|
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
|
+
# Thread badge.
|
24
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
25
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
26
|
+
# License:: MIT
|
27
|
+
module Zold
|
28
|
+
# This module should be included in each command, in order to label
|
29
|
+
# the current Thread correctly, when the command is running. This is mostly
|
30
|
+
# useful for debugging/testing purposes - want to be able to see what's
|
31
|
+
# going on in the thread when it gets stuck with a Futex.
|
32
|
+
#
|
33
|
+
# Since all commands have exactly the same external interface and implement
|
34
|
+
# the method "run," we catch all calls to this method and label the
|
35
|
+
# current thread properly. We label it back when it's over.
|
36
|
+
module ThreadBadge
|
37
|
+
def run(args = [])
|
38
|
+
before = Thread.current.name || ''
|
39
|
+
Thread.current.name = "#{before}:#{self.class.name.gsub(/^Zold::/, '')}"
|
40
|
+
begin
|
41
|
+
super(args)
|
42
|
+
ensure
|
43
|
+
Thread.current.name = before
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/zold/copies.rb
CHANGED
data/lib/zold/endless.rb
CHANGED
data/lib/zold/http.rb
CHANGED
@@ -67,7 +67,7 @@ module Zold
|
|
67
67
|
@network = network
|
68
68
|
end
|
69
69
|
|
70
|
-
def get(timeout: READ_TIMEOUT
|
70
|
+
def get(timeout: READ_TIMEOUT)
|
71
71
|
base_url = "#{@uri.scheme}://#{@uri.host}:#{@uri.port}"
|
72
72
|
session = Patron::Session.new(
|
73
73
|
timeout: timeout,
|
@@ -82,7 +82,7 @@ module Zold
|
|
82
82
|
Error.new(e)
|
83
83
|
end
|
84
84
|
|
85
|
-
def put(body, timeout: READ_TIMEOUT
|
85
|
+
def put(body, timeout: READ_TIMEOUT)
|
86
86
|
base_url = "#{@uri.scheme}://#{@uri.host}:#{@uri.port}"
|
87
87
|
session = Patron::Session.new(
|
88
88
|
timeout: timeout,
|
@@ -109,7 +109,7 @@ module Zold
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def to_s
|
112
|
-
"#{
|
112
|
+
"#{status}: #{status_line}\n#{body}"
|
113
113
|
end
|
114
114
|
|
115
115
|
def body
|
data/lib/zold/key.rb
CHANGED
data/lib/zold/log.rb
CHANGED
@@ -20,10 +20,8 @@
|
|
20
20
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
21
|
# SOFTWARE.
|
22
22
|
|
23
|
+
require 'logger'
|
23
24
|
require 'rainbow'
|
24
|
-
require 'monitor'
|
25
|
-
|
26
|
-
STDOUT.sync = true
|
27
25
|
|
28
26
|
# Zold module.
|
29
27
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -47,121 +45,64 @@ module Zold
|
|
47
45
|
# messages. The user turns this mode by using --verbose command line argument.
|
48
46
|
#
|
49
47
|
module Log
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
return unless debug?
|
59
|
-
@monitor.synchronize do
|
60
|
-
@log.debug(msg)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
def debug?
|
65
|
-
@log.debug?
|
66
|
-
end
|
67
|
-
|
68
|
-
def info(msg)
|
69
|
-
return unless info?
|
70
|
-
@monitor.synchronize do
|
71
|
-
@log.info(msg)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def info?
|
76
|
-
@log.info?
|
77
|
-
end
|
78
|
-
|
79
|
-
def error(msg)
|
80
|
-
@monitor.synchronize do
|
81
|
-
@log.error(msg)
|
82
|
-
end
|
83
|
-
end
|
48
|
+
def self.colored(text, severity)
|
49
|
+
case severity
|
50
|
+
when 'ERROR', 'FATAL'
|
51
|
+
return Rainbow(text).red
|
52
|
+
when 'DEBUG'
|
53
|
+
return Rainbow(text).yellow
|
54
|
+
end
|
55
|
+
text
|
84
56
|
end
|
85
57
|
|
86
|
-
#
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
def info(msg)
|
97
|
-
print(msg)
|
98
|
-
end
|
99
|
-
|
100
|
-
def info?
|
101
|
-
true
|
102
|
-
end
|
103
|
-
|
104
|
-
def error(msg)
|
105
|
-
print("#{Rainbow('ERROR').red}: #{msg}")
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
|
110
|
-
def print(text)
|
111
|
-
puts(text)
|
58
|
+
# Compact formatter
|
59
|
+
COMPACT = proc do |severity, _time, _target, msg|
|
60
|
+
prefix = ''
|
61
|
+
case severity
|
62
|
+
when 'ERROR', 'FATAL'
|
63
|
+
prefix = 'E: '
|
64
|
+
when 'DEBUG'
|
65
|
+
prefix = 'D: '
|
112
66
|
end
|
67
|
+
colored(prefix, severity) + msg.to_s.rstrip.gsub(/\n/, "\n" + (' ' * prefix.length)) + "\n"
|
113
68
|
end
|
114
69
|
|
115
|
-
#
|
116
|
-
|
117
|
-
|
118
|
-
# nothing
|
119
|
-
end
|
120
|
-
|
121
|
-
def debug?
|
122
|
-
false
|
123
|
-
end
|
124
|
-
|
125
|
-
def info(msg)
|
126
|
-
print(msg)
|
127
|
-
end
|
128
|
-
|
129
|
-
def info?
|
130
|
-
true
|
131
|
-
end
|
132
|
-
|
133
|
-
def error(msg)
|
134
|
-
print("#{Rainbow('ERROR').red}: #{msg}")
|
135
|
-
end
|
136
|
-
|
137
|
-
private
|
138
|
-
|
139
|
-
def print(text)
|
140
|
-
puts(text)
|
141
|
-
end
|
70
|
+
# Short formatter
|
71
|
+
SHORT = proc do |_severity, _time, _target, msg|
|
72
|
+
msg.to_s.rstrip + "\n"
|
142
73
|
end
|
143
74
|
|
144
|
-
#
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
end
|
153
|
-
|
154
|
-
def info(msg)
|
155
|
-
# nothing to do here
|
156
|
-
end
|
157
|
-
|
158
|
-
def info?
|
159
|
-
false
|
160
|
-
end
|
161
|
-
|
162
|
-
def error(msg)
|
163
|
-
# nothing to do here
|
164
|
-
end
|
75
|
+
# Full formatter
|
76
|
+
FULL = proc do |severity, time, _target, msg|
|
77
|
+
format(
|
78
|
+
"%<time>s %<severity>5s %<msg>s\n",
|
79
|
+
time: time.utc.iso8601,
|
80
|
+
severity: colored(severity, severity),
|
81
|
+
msg: msg.to_s.rstrip
|
82
|
+
)
|
165
83
|
end
|
84
|
+
|
85
|
+
# No logging at all
|
86
|
+
NULL = Logger.new(STDOUT)
|
87
|
+
NULL.level = Logger::UNKNOWN
|
88
|
+
NULL.freeze
|
89
|
+
|
90
|
+
# Everything, including debug
|
91
|
+
VERBOSE = Logger.new(STDOUT)
|
92
|
+
VERBOSE.level = Logger::DEBUG
|
93
|
+
VERBOSE.formatter = COMPACT
|
94
|
+
VERBOSE.freeze
|
95
|
+
|
96
|
+
# Info and errors, no debug info
|
97
|
+
REGULAR = Logger.new(STDOUT)
|
98
|
+
REGULAR.level = Logger::INFO
|
99
|
+
REGULAR.formatter = COMPACT
|
100
|
+
REGULAR.freeze
|
101
|
+
|
102
|
+
# Errors only
|
103
|
+
ERRORS = Logger.new(STDOUT)
|
104
|
+
ERRORS.level = Logger::ERROR
|
105
|
+
ERRORS.formatter = COMPACT
|
106
|
+
ERRORS.freeze
|
166
107
|
end
|
167
108
|
end
|
data/lib/zold/metronome.rb
CHANGED
@@ -32,7 +32,7 @@ require_relative 'verbose_thread'
|
|
32
32
|
module Zold
|
33
33
|
# Metronome
|
34
34
|
class Metronome
|
35
|
-
def initialize(log = Log::
|
35
|
+
def initialize(log = Log::NULL)
|
36
36
|
@log = log
|
37
37
|
@routines = []
|
38
38
|
@threads = []
|
@@ -86,16 +86,18 @@ module Zold
|
|
86
86
|
begin
|
87
87
|
yield(self)
|
88
88
|
ensure
|
89
|
-
alive = false
|
90
|
-
@log.info("Stopping the metronome with #{@threads.count} threads: #{@threads.map(&:name).join(', ')}")
|
91
89
|
start = Time.now
|
92
|
-
@threads.
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
t.
|
98
|
-
|
90
|
+
unless @threads.empty?
|
91
|
+
alive = false
|
92
|
+
@log.info("Stopping the metronome with #{@threads.count} threads: #{@threads.map(&:name).join(', ')}")
|
93
|
+
@threads.each do |t|
|
94
|
+
tstart = Time.now
|
95
|
+
if t.join(60)
|
96
|
+
@log.info("Thread #{t.name} finished in #{Age.new(tstart)}")
|
97
|
+
else
|
98
|
+
t.exit
|
99
|
+
@log.info("Thread #{t.name} killed in #{Age.new(tstart)}")
|
100
|
+
end
|
99
101
|
end
|
100
102
|
end
|
101
103
|
@log.info("Metronome stopped in #{Age.new(start)}, #{@failures.count} failures")
|