zold 0.22.3 → 0.22.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/Dockerfile +14 -0
- data/README.md +13 -0
- data/bin/zold +5 -6
- data/fixtures/scripts/redeploy-on-upgrade.sh +1 -1
- data/lib/zold/commands/fetch.rb +3 -2
- data/lib/zold/commands/node.rb +7 -0
- data/lib/zold/commands/remote.rb +1 -1
- data/lib/zold/head.rb +1 -1
- data/lib/zold/key.rb +4 -0
- data/lib/zold/node/front.rb +2 -1
- data/lib/zold/signature.rb +1 -1
- data/lib/zold/version.rb +1 -1
- data/lib/zold/wallet.rb +51 -23
- data/test/fake_home.rb +3 -1
- data/test/test__helper.rb +1 -1
- data/test/test_hungry_wallets.rb +1 -1
- data/test/test_wallet.rb +2 -2
- data/test/test_zold.rb +1 -1
- data/zold.gemspec +1 -1
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad91826d6e1a3e8d2b8b55ccdbf662ed3462098ad9ac97a638ca3a315ca16bf0
|
4
|
+
data.tar.gz: 139cd5314e6dd0dac0a10f20f0933e5e1d826820f4a3386eb3f7c643b49d8acc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3004779c370ec2ce966c89cbfa4e004c5b8644e164da6ab7a6dfb3be0eb64020853979eb6cf9ab2b8a980f0d6b0b8b610dfa44a47cdb351bd25c3d7b95341702
|
7
|
+
data.tar.gz: e9901486c5cb9f653723687091a25a4902e30818757a4cd56d71c7dced8a83c5dfbefd8de77b73b5053c3e91836e6edd33dbf1169edb914e10d2e6691f35a5b5
|
data/.rubocop.yml
CHANGED
data/Dockerfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
FROM ruby:2.6
|
2
|
+
|
3
|
+
RUN gem install zold
|
4
|
+
EXPOSE 4096
|
5
|
+
|
6
|
+
RUN echo "#!/bin/bash" > node.sh
|
7
|
+
RUN echo "zold node --nohup \044\100" >> node.sh
|
8
|
+
RUN echo "tail -f zold.log" >> node.sh
|
9
|
+
RUN chmod +x /node.sh
|
10
|
+
|
11
|
+
RUN mkdir /zold
|
12
|
+
WORKDIR /zold
|
13
|
+
|
14
|
+
CMD ["/node.sh"]
|
data/README.md
CHANGED
@@ -127,6 +127,19 @@ If you are lost, run this:
|
|
127
127
|
$ zold node --help
|
128
128
|
```
|
129
129
|
|
130
|
+
You can run a node in a docker container also.
|
131
|
+
|
132
|
+
```bash
|
133
|
+
docker run -d -p 4096:4096 zold/zold:latest /node.sh --host=<your host IP> --invoice=5f96e731e48ae21f
|
134
|
+
```
|
135
|
+
|
136
|
+
To store zold data between container restarts create a volume or bind a directory from host
|
137
|
+
|
138
|
+
```bash
|
139
|
+
docker volume create zold
|
140
|
+
docker run -d -p 4096:4096 -v zold:/zold zold/zold:latest /node.sh --host=<your host IP> --invoice=5f96e731e48ae21f
|
141
|
+
```
|
142
|
+
|
130
143
|
## Frequently Asked Questions
|
131
144
|
|
132
145
|
> Where are my RSA private/public keys?
|
data/bin/zold
CHANGED
@@ -276,14 +276,13 @@ else
|
|
276
276
|
code = cmd.call
|
277
277
|
end
|
278
278
|
|
279
|
+
Zold::Hands.stop
|
280
|
+
|
279
281
|
log.debug("Memory footprint at the end is #{Zold::Size.new(GetProcessMem.new.bytes.to_i)}")
|
280
282
|
if code.zero?
|
281
|
-
log.debug("Failed in in #{Zold::Age.new(start)}")
|
282
|
-
exit(code)
|
283
|
-
else
|
284
283
|
log.debug("Successfully finished in #{Zold::Age.new(start)}")
|
284
|
+
else
|
285
|
+
log.debug("Failed in #{Zold::Age.new(start)}")
|
286
|
+
exit(code)
|
285
287
|
end
|
286
288
|
|
287
|
-
Zold::Hands.stop
|
288
|
-
|
289
|
-
abort # We need this in case some threads are still alive
|
@@ -6,7 +6,7 @@ function start_node {
|
|
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
8
|
--expose-version=$2 --save-pid=pid --routine-immediately --tolerate-edges --tolerate-quorum=1 \
|
9
|
-
--verbose --trace --invoice=REDEPLOY@ffffffffffffffff \
|
9
|
+
--verbose --trace --invoice=REDEPLOY@ffffffffffffffff --ignore-empty-remotes \
|
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
|
12
12
|
cat pid
|
data/lib/zold/commands/fetch.rb
CHANGED
@@ -170,8 +170,8 @@ run 'zold remote update' or use --tolerate-quorum=1"
|
|
170
170
|
end
|
171
171
|
copy = cps.add(IO.read(f), score.host, score.port, score.value, master: r.master?)
|
172
172
|
@log.info("#{r} returned #{wallet.mnemo} #{Age.new(json['mtime'])}/#{json['copies']}c \
|
173
|
-
|
174
|
-
|
173
|
+
as copy ##{copy}/#{cps.all.count} in #{Age.new(start, limit: 4)}: \
|
174
|
+
#{Rainbow(score.value).green} (#{json['version']})")
|
175
175
|
end
|
176
176
|
end
|
177
177
|
score.value
|
@@ -183,6 +183,7 @@ run 'zold remote update' or use --tolerate-quorum=1"
|
|
183
183
|
begin
|
184
184
|
uri = "/wallet/#{id}"
|
185
185
|
head = r.http(uri).get
|
186
|
+
raise "The wallet #{id} doesn't exist at #{r}" if head.status == 404
|
186
187
|
r.assert_code(200, head)
|
187
188
|
json = JsonPage.new(head.body, uri).to_hash
|
188
189
|
score = Score.parse_json(json['score'])
|
data/lib/zold/commands/node.rb
CHANGED
@@ -145,6 +145,9 @@ module Zold
|
|
145
145
|
o.bool '--allow-spam',
|
146
146
|
'Don\'t filter the incoming spam via PUT requests (duplicate wallets)',
|
147
147
|
default: false
|
148
|
+
o.bool '--ignore-empty-remotes',
|
149
|
+
'Don\'t fail if the list of remotes is empty (for testing mostly)',
|
150
|
+
default: false
|
148
151
|
o.bool '--skip-oom',
|
149
152
|
'Skip Out Of Memory check and never exit, no matter how much RAM is consumed',
|
150
153
|
default: false
|
@@ -197,6 +200,10 @@ module Zold
|
|
197
200
|
end
|
198
201
|
raise '--invoice is mandatory' unless opts['invoice']
|
199
202
|
if opts['nohup']
|
203
|
+
if @remotes.all.empty? && !opts['standalone'] && !opts['ignore-empty-remotes']
|
204
|
+
raise 'There are no remote nodes in the list and you are not running in --standalone mode;
|
205
|
+
the node won\'t connect to the network like that; try to do "zold remote reset" first'
|
206
|
+
end
|
200
207
|
pid = nohup(opts)
|
201
208
|
IO.write(opts['save-pid'], pid) if opts['save-pid']
|
202
209
|
@log.debug("Process ID #{pid} saved into \"#{opts['save-pid']}\"")
|
data/lib/zold/commands/remote.rb
CHANGED
@@ -323,7 +323,7 @@ Available options:"
|
|
323
323
|
rescue JsonPage::CantParse, Score::CantParse, RemoteNode::CantAssert => e
|
324
324
|
attempt += 1
|
325
325
|
if attempt < opts['retry']
|
326
|
-
@log.error("#{r} failed to read
|
326
|
+
@log.error("#{r} failed to read, trying again (attempt no.#{attempt}): #{e.message}")
|
327
327
|
retry
|
328
328
|
end
|
329
329
|
raise e
|
data/lib/zold/head.rb
CHANGED
@@ -44,7 +44,7 @@ module Zold
|
|
44
44
|
raise "Wallet file '#{@file}' is absent" unless File.exist?(@file)
|
45
45
|
lines = []
|
46
46
|
File.open(@file) do |f|
|
47
|
-
lines << f.readline while lines.count < 4 && !f.eof?
|
47
|
+
lines << f.readline.strip while lines.count < 4 && !f.eof?
|
48
48
|
end
|
49
49
|
raise CantParse, "Not enough lines in #{@file}, just #{lines.count}" if lines.count < 4
|
50
50
|
lines
|
data/lib/zold/key.rb
CHANGED
data/lib/zold/node/front.rb
CHANGED
@@ -246,6 +246,7 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
|
|
246
246
|
id: wallet.id.to_s,
|
247
247
|
score: score.to_h,
|
248
248
|
mtime: wallet.mtime.utc.iso8601,
|
249
|
+
age: wallet.age.to_s,
|
249
250
|
size: wallet.size,
|
250
251
|
digest: wallet.digest,
|
251
252
|
copies: Copies.new(File.join(settings.copies, wallet.id)).all.count,
|
@@ -454,7 +455,7 @@ time to stop; use --skip-oom to never quit")
|
|
454
455
|
settings.zache.get(:total_mem, lifetime: settings.opts['no-cache'] ? 0 : 60) do
|
455
456
|
Total::Mem.new.bytes
|
456
457
|
rescue Total::CantDetect => e
|
457
|
-
|
458
|
+
settings.log.error(e.message)
|
458
459
|
0
|
459
460
|
end
|
460
461
|
end
|
data/lib/zold/signature.rb
CHANGED
@@ -56,7 +56,7 @@ module Zold
|
|
56
56
|
raise 'pub must be of type Key' unless pub.is_a?(Key)
|
57
57
|
raise 'id must be of type Id' unless id.is_a?(Id)
|
58
58
|
raise 'txn must be of type Txn' unless txn.is_a?(Txn)
|
59
|
-
pub.verify(txn.sign, body(id, txn)) && (@network != Wallet::MAINET || id
|
59
|
+
pub.verify(txn.sign, body(id, txn)) && (@network != Wallet::MAINET || !id.root? || pub.root?)
|
60
60
|
end
|
61
61
|
|
62
62
|
private
|
data/lib/zold/version.rb
CHANGED
data/lib/zold/wallet.rb
CHANGED
@@ -54,6 +54,9 @@ module Zold
|
|
54
54
|
# The extension of the wallet files
|
55
55
|
EXT = '.z'
|
56
56
|
|
57
|
+
# The constructor of the wallet, from the file. The file may be
|
58
|
+
# absent at the time of creating the object. Later, don't forget to
|
59
|
+
# call init() in order to initialize the wallet, if it's absent.
|
57
60
|
def initialize(file)
|
58
61
|
unless file.end_with?(Wallet::EXT, Copies::EXT)
|
59
62
|
raise "Wallet file must end with #{Wallet::EXT} or #{Copies::EXT}: #{file}"
|
@@ -71,55 +74,67 @@ module Zold
|
|
71
74
|
id.to_s
|
72
75
|
end
|
73
76
|
|
77
|
+
# Returns a convenient printable mnemo code of the wallet (mostly
|
78
|
+
# useful for logs).
|
74
79
|
def mnemo
|
75
80
|
"#{id}/#{balance.to_zld(4)}/#{txns.count}t/#{digest[0, 6]}/#{Size.new(size)}"
|
76
81
|
end
|
77
82
|
|
83
|
+
# Convert the content of the wallet to the text.
|
78
84
|
def to_text
|
79
85
|
(@head.fetch + [''] + @txns.fetch.map(&:to_text)).join("\n")
|
80
86
|
end
|
81
87
|
|
88
|
+
# Returns the network ID of the wallet.
|
82
89
|
def network
|
83
|
-
n = @head.fetch[0]
|
90
|
+
n = @head.fetch[0]
|
84
91
|
raise "Invalid network name '#{n}'" unless n =~ /^[a-z]{4,16}$/
|
85
92
|
n
|
86
93
|
end
|
87
94
|
|
95
|
+
# Returns the protocol ID of the wallet file.
|
88
96
|
def protocol
|
89
|
-
v = @head.fetch[1]
|
97
|
+
v = @head.fetch[1]
|
90
98
|
raise "Invalid protocol version name '#{v}'" unless v =~ /^[0-9]+$/
|
91
99
|
v.to_i
|
92
100
|
end
|
93
101
|
|
102
|
+
# Returns TRUE if the wallet file exists.
|
94
103
|
def exists?
|
95
|
-
File.exist?(
|
104
|
+
File.exist?(path)
|
96
105
|
end
|
97
106
|
|
107
|
+
# Returns the absolute path of the wallet file (it may be absent).
|
98
108
|
def path
|
99
109
|
@file
|
100
110
|
end
|
101
111
|
|
112
|
+
# Creates an empty wallet with the specified ID and public key.
|
102
113
|
def init(id, pubkey, overwrite: false, network: 'test')
|
103
|
-
raise "File '#{
|
114
|
+
raise "File '#{path}' already exists" if File.exist?(path) && !overwrite
|
104
115
|
raise "Invalid network name '#{network}'" unless network =~ /^[a-z]{4,16}$/
|
105
|
-
FileUtils.mkdir_p(File.dirname(
|
106
|
-
IO.write(
|
116
|
+
FileUtils.mkdir_p(File.dirname(path))
|
117
|
+
IO.write(path, "#{network}\n#{PROTOCOL}\n#{id}\n#{pubkey.to_pub}\n\n")
|
107
118
|
@txns.flush
|
108
119
|
@head.flush
|
109
120
|
end
|
110
121
|
|
122
|
+
# Returns TRUE if it's a root wallet.
|
111
123
|
def root?
|
112
124
|
id == Id::ROOT
|
113
125
|
end
|
114
126
|
|
127
|
+
# Returns the wallet ID.
|
115
128
|
def id
|
116
|
-
Id.new(@head.fetch[2]
|
129
|
+
Id.new(@head.fetch[2])
|
117
130
|
end
|
118
131
|
|
132
|
+
# Returns current wallet balance.
|
119
133
|
def balance
|
120
134
|
txns.inject(Amount::ZERO) { |sum, t| sum + t.amount }
|
121
135
|
end
|
122
136
|
|
137
|
+
# Add a payment transaction to the wallet.
|
123
138
|
def sub(amount, invoice, pvt, details = '-', time: Time.now)
|
124
139
|
raise 'The amount has to be of type Amount' unless amount.is_a?(Amount)
|
125
140
|
raise "The amount can't be negative: #{amount}" if amount.negative?
|
@@ -141,6 +156,7 @@ module Zold
|
|
141
156
|
txn
|
142
157
|
end
|
143
158
|
|
159
|
+
# Add a transaction to the wallet.
|
144
160
|
def add(txn)
|
145
161
|
raise 'The txn has to be of type Txn' unless txn.is_a?(Txn)
|
146
162
|
raise "Wallet #{id} can't pay itself: #{txn}" if txn.bnf == id
|
@@ -152,66 +168,75 @@ module Zold
|
|
152
168
|
raise "Positive transaction with the same ID #{txn.id} and BNF #{txn.bnf} already exists in #{id}"
|
153
169
|
end
|
154
170
|
raise "The tax payment already exists in #{id}: #{txn}" if Tax.new(self).exists?(txn.details)
|
155
|
-
File.open(
|
171
|
+
File.open(path, 'a') { |f| f.print "#{txn}\n" }
|
156
172
|
@txns.flush
|
157
173
|
end
|
158
174
|
|
175
|
+
# Returns TRUE if the wallet contains a payment sent with the specified
|
176
|
+
# ID, which was sent to the specified beneficiary.
|
159
177
|
def includes_negative?(id, bnf = nil)
|
160
178
|
raise 'The txn ID has to be of type Integer' unless id.is_a?(Integer)
|
161
179
|
!txns.find { |t| t.id == id && (bnf.nil? || t.bnf == bnf) && t.amount.negative? }.nil?
|
162
180
|
end
|
163
181
|
|
182
|
+
# Returns TRUE if the wallet contains a payment received with the specified
|
183
|
+
# ID, which was sent by the specified beneficiary.
|
164
184
|
def includes_positive?(id, bnf)
|
165
185
|
raise 'The txn ID has to be of type Integer' unless id.is_a?(Integer)
|
166
186
|
raise 'The bnf has to be of type Id' unless bnf.is_a?(Id)
|
167
187
|
!txns.find { |t| t.id == id && t.bnf == bnf && !t.amount.negative? }.nil?
|
168
188
|
end
|
169
189
|
|
190
|
+
# Returns TRUE if the public key of the wallet includes this payment
|
191
|
+
# prefix of the invoice.
|
170
192
|
def prefix?(prefix)
|
171
193
|
key.to_pub.include?(prefix)
|
172
194
|
end
|
173
195
|
|
196
|
+
# Returns the public key of the wallet.
|
174
197
|
def key
|
175
|
-
Key.new(text: @head.fetch[3]
|
176
|
-
end
|
177
|
-
|
178
|
-
def income
|
179
|
-
txns.each do |t|
|
180
|
-
yield t unless t.amount.negative?
|
181
|
-
end
|
198
|
+
Key.new(text: @head.fetch[3])
|
182
199
|
end
|
183
200
|
|
201
|
+
# Returns the time of when the wallet file was recently modified.
|
184
202
|
def mtime
|
185
|
-
File.mtime(
|
203
|
+
File.mtime(path)
|
186
204
|
end
|
187
205
|
|
206
|
+
# Returns a pseudo-unique hexadecimal digest of the wallet content.
|
188
207
|
def digest
|
189
|
-
OpenSSL::Digest::SHA256.file(
|
208
|
+
OpenSSL::Digest::SHA256.file(path).hexdigest
|
190
209
|
end
|
191
210
|
|
192
|
-
# Age of wallet in hours
|
211
|
+
# Age of wallet in hours.
|
193
212
|
def age
|
194
213
|
list = txns
|
195
214
|
list.empty? ? 0 : (Time.now - list.min_by(&:date).date) / (60 * 60)
|
196
215
|
end
|
197
216
|
|
198
|
-
# Size of the wallet file in bytes
|
217
|
+
# Size of the wallet file in bytes. If the file doesn't exist
|
218
|
+
# an exception will be raised.
|
199
219
|
def size
|
220
|
+
raise "The wallet file #{path} doesn't exist" unless File.exist?(path)
|
200
221
|
File.size(path)
|
201
222
|
end
|
202
223
|
|
224
|
+
# Retrieve the total list of all transactions.
|
203
225
|
def txns
|
204
226
|
@txns.fetch
|
205
227
|
end
|
206
228
|
|
229
|
+
# Resaves the content of the wallet to the disc in the right format. All
|
230
|
+
# unnecessary space and EOL-s are removed. This operation is required
|
231
|
+
# in order to make sure two wallets with the same content are identical,
|
232
|
+
# no matter whether they were formatted differently.
|
207
233
|
def refurbish
|
208
|
-
IO.write(
|
209
|
-
@file,
|
210
|
-
"#{network}\n#{protocol}\n#{id}\n#{key.to_pub}\n\n#{txns.map { |t| t.to_s + "\n" }.join}"
|
211
|
-
)
|
234
|
+
IO.write(path, (@head.fetch + [''] + @txns.fetch.map(&:to_s)).join("\n") + "\n")
|
212
235
|
@txns.flush
|
213
236
|
end
|
214
237
|
|
238
|
+
# Flush the in-memory cache and force the object to load all data from
|
239
|
+
# the disc again.
|
215
240
|
def flush
|
216
241
|
@head.flush
|
217
242
|
@txns.flush
|
@@ -219,6 +244,9 @@ module Zold
|
|
219
244
|
|
220
245
|
private
|
221
246
|
|
247
|
+
# Calculate the maximum transaction ID visible currently in the wallet.
|
248
|
+
# We go through them all and find the largest number. If there are
|
249
|
+
# no transactions, zero is returned.
|
222
250
|
def max
|
223
251
|
negative = txns.select { |t| t.amount.negative? }
|
224
252
|
negative.empty? ? 0 : negative.max_by(&:id).id
|
data/test/fake_home.rb
CHANGED
@@ -45,7 +45,9 @@ class FakeHome
|
|
45
45
|
def run
|
46
46
|
Dir.mktmpdir do |dir|
|
47
47
|
FileUtils.copy(File.expand_path(File.join(__dir__, '../fixtures/id_rsa')), File.join(dir, 'id_rsa'))
|
48
|
-
yield FakeHome.new(dir, log: @log)
|
48
|
+
result = yield FakeHome.new(dir, log: @log)
|
49
|
+
sleep 0.1 # It's a workaround against a bug (without it tests fail sporadically)
|
50
|
+
result
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
data/test/test__helper.rb
CHANGED
data/test/test_hungry_wallets.rb
CHANGED
data/test/test_wallet.rb
CHANGED
@@ -257,8 +257,8 @@ class TestWallet < Zold::Test
|
|
257
257
|
)
|
258
258
|
)
|
259
259
|
sum = Zold::Amount::ZERO
|
260
|
-
wallet.
|
261
|
-
sum += t.amount
|
260
|
+
wallet.txns.each do |t|
|
261
|
+
sum += t.amount unless t.amount.negative?
|
262
262
|
end
|
263
263
|
assert(
|
264
264
|
sum == Zold::Amount.new(zents: 235_965_503_242),
|
data/test/test_zold.rb
CHANGED
data/zold.gemspec
CHANGED
@@ -77,7 +77,7 @@ and suggests a different architecture for digital wallet maintenance.'
|
|
77
77
|
s.add_runtime_dependency 'sys-proctable', '1.2.1'
|
78
78
|
s.add_runtime_dependency 'thin', '1.7.2'
|
79
79
|
s.add_runtime_dependency 'threads', '>=0.3'
|
80
|
-
s.add_runtime_dependency 'total', '>=0.
|
80
|
+
s.add_runtime_dependency 'total', '>=0.3'
|
81
81
|
s.add_runtime_dependency 'typhoeus', '1.3.1'
|
82
82
|
s.add_runtime_dependency 'usagewatch_ext', '0.2.1'
|
83
83
|
s.add_runtime_dependency 'zache', '>=0.7'
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zold
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.22.
|
4
|
+
version: 0.22.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-01-
|
11
|
+
date: 2019-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: backtrace
|
@@ -240,14 +240,14 @@ dependencies:
|
|
240
240
|
requirements:
|
241
241
|
- - ">="
|
242
242
|
- !ruby/object:Gem::Version
|
243
|
-
version: '0.
|
243
|
+
version: '0.3'
|
244
244
|
type: :runtime
|
245
245
|
prerelease: false
|
246
246
|
version_requirements: !ruby/object:Gem::Requirement
|
247
247
|
requirements:
|
248
248
|
- - ">="
|
249
249
|
- !ruby/object:Gem::Version
|
250
|
-
version: '0.
|
250
|
+
version: '0.3'
|
251
251
|
- !ruby/object:Gem::Dependency
|
252
252
|
name: typhoeus
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
@@ -545,6 +545,7 @@ files:
|
|
545
545
|
- ".rultor.yml"
|
546
546
|
- ".simplecov"
|
547
547
|
- ".travis.yml"
|
548
|
+
- Dockerfile
|
548
549
|
- Gemfile
|
549
550
|
- Guardfile
|
550
551
|
- INSTALL.md
|
@@ -746,7 +747,7 @@ licenses:
|
|
746
747
|
- MIT
|
747
748
|
metadata: {}
|
748
749
|
post_install_message: |-
|
749
|
-
Thanks for installing Zold 0.22.
|
750
|
+
Thanks for installing Zold 0.22.4!
|
750
751
|
Study our White Paper: https://papers.zold.io/wp.pdf
|
751
752
|
Read our blog posts: https://blog.zold.io
|
752
753
|
Try ZLD online wallet at: https://wts.zold.io
|