zold 0.26.16 → 0.26.17

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b0ae546cf6416b998bfd75490dae5b662d89c3e6e598958f1c73c86e51fda17
4
- data.tar.gz: bcc69294f383f7832b3ac832742c89630eb7d8a880741aefd7c0397a88cb9042
3
+ metadata.gz: a0649d6ccb04536eabe73074ef91e87317c15f35b64aea31739e8b82d4bb5347
4
+ data.tar.gz: 788a6dfd9cb3a6cc687f1abe29a9636d3d3245e7e745481fdab8ebe7c96de753
5
5
  SHA512:
6
- metadata.gz: f746fba3dad2802bce2170facba75809d44fee26f29cf61a95c1c74245c61668f1fd75fed47722ab50bfc7676093b287b16e4e1683b280f99fd18715321e8574
7
- data.tar.gz: fe15c859e3ff938901b7ef369e80346dc005be4451e4c2abd2cd45bd778b0b5b8939c3d0201ae78e4802c8d3aec6475779d94ab96a12857eec61e3e8d9476a7b
6
+ metadata.gz: dc2b1ad12503d024a5a31600186a7084b6def9d978fd4e531037f38d5d6e12160c2b47cd716adc89f02f474b4af52dd80e933666e07ed5b2f0d4062e28f5d0e4
7
+ data.tar.gz: f14755645f55d6d954c3bd38668d961ce6121399d6b2f1dc5b13b25ed596f9c4f1527fd75ecf06391401f713653a621a6114f135b216ae77b5d6352046cd2693
@@ -20,11 +20,11 @@
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_relative 'thread_badge'
24
23
  require 'tempfile'
25
24
  require 'slop'
26
25
  require 'diffy'
27
26
  require 'rainbow'
27
+ require_relative 'thread_badge'
28
28
  require_relative 'args'
29
29
  require_relative '../log'
30
30
  require_relative '../patch'
@@ -45,7 +45,8 @@ require_relative '../node/async_entrance'
45
45
  require_relative '../node/sync_entrance'
46
46
  require_relative '../node/nodup_entrance'
47
47
  require_relative '../node/nospam_entrance'
48
- require_relative '../node/journaled_entrance'
48
+ require_relative '../node/pipeline'
49
+ require_relative '../node/journaled_pipeline'
49
50
  require_relative '../node/front'
50
51
  require_relative '../node/trace'
51
52
  require_relative '../node/farm'
@@ -271,25 +272,23 @@ the node won\'t connect to the network like that; try to do "zold remote reset"
271
272
  FileUtils.mkdir_p(journal_dir)
272
273
  Front.set(:journal_dir, journal_dir)
273
274
  Front.set(:node_alias, node_alias(opts, address))
274
- jlog = Logger.new(File.join(journal_dir, 'journal'))
275
- jlog.level = Logger::DEBUG
276
- jlog.formatter = Log::COMPACT
277
275
  entrance = SafeEntrance.new(
278
276
  NoSpamEntrance.new(
279
277
  NoDupEntrance.new(
280
278
  AsyncEntrance.new(
281
279
  SpreadEntrance.new(
282
280
  SyncEntrance.new(
283
- JournaledEntrance.new(
284
- Entrance.new(
285
- wts, @remotes, @copies, address,
286
- ledger: ledger,
287
- log: Log::Tee.new(@log, jlog), network: opts['network']
288
- ),
281
+ Entrance.new(
289
282
  wts,
290
- journal_dir,
291
- jlog,
292
- 'journal'
283
+ JournaledPipeline.new(
284
+ Pipeline.new(
285
+ @remotes, @copies, address,
286
+ ledger: ledger,
287
+ network: opts['network']
288
+ ),
289
+ journal_dir
290
+ ),
291
+ log: @log
293
292
  ),
294
293
  File.join(home, '.zoldata/sync-entrance'),
295
294
  log: @log
@@ -58,7 +58,7 @@ module Zold
58
58
  if @queue.size > 256
59
59
  @log.error("Hungry queue is full with #{@queue.size} wallets, can't add #{id}")
60
60
  elsif @missed.exists?(id.to_s)
61
- @log.debug("Hungry queue has seen #{id} just #{Age.new(@missed.mtime(id.to_s))} ago
61
+ @log.debug("Hungry queue has seen #{id} just #{Age.new(@missed.mtime(id.to_s))} ago \
62
62
  (amoung #{@missed.size} others) and it was not found")
63
63
  else
64
64
  @mutex.synchronize do
@@ -21,15 +21,8 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'tempfile'
24
+ require 'time'
24
25
  require_relative '../log'
25
- require_relative '../remotes'
26
- require_relative '../copies'
27
- require_relative '../tax'
28
- require_relative '../age'
29
- require_relative '../commands/clean'
30
- require_relative '../commands/merge'
31
- require_relative '../commands/fetch'
32
- require_relative '../commands/push'
33
26
 
34
27
  # The entrance of the web front.
35
28
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -38,18 +31,13 @@ require_relative '../commands/push'
38
31
  module Zold
39
32
  # The entrance
40
33
  class Entrance
41
- def initialize(wallets, remotes, copies, address, ledger: '/dev/null',
42
- log: Log::NULL, network: 'test')
34
+ def initialize(wallets, pipeline, log: Log::NULL)
43
35
  @wallets = wallets
44
- @remotes = remotes
45
- @copies = copies
46
- @address = address
36
+ @pipeline = pipeline
47
37
  @log = log
48
- @network = network
49
38
  @history = []
50
39
  @speed = []
51
40
  @mutex = Mutex.new
52
- @ledger = ledger
53
41
  end
54
42
 
55
43
  def start
@@ -62,7 +50,7 @@ module Zold
62
50
  'history': @history.join(', '),
63
51
  'history_size': @history.count,
64
52
  'speed': @speed.empty? ? 0 : (@speed.inject(&:+) / @speed.count),
65
- 'ledger': File.exist?(@ledger) ? IO.read(@ledger).split("\n").count : 0
53
+ 'pipeline': @pipeline.to_json
66
54
  }
67
55
  end
68
56
 
@@ -72,25 +60,7 @@ module Zold
72
60
  raise 'Id must be of type Id' unless id.is_a?(Id)
73
61
  raise 'Body can\'t be nil' if body.nil?
74
62
  start = Time.now
75
- copies = Copies.new(File.join(@copies, id.to_s))
76
- host = '0.0.0.0'
77
- copies.add(body, host, Remotes::PORT, 0)
78
- unless @remotes.all.empty?
79
- Fetch.new(
80
- wallets: @wallets, remotes: @remotes, copies: copies.root, log: @log
81
- ).run(['fetch', id.to_s, "--ignore-node=#{@address}", "--network=#{@network}", '--quiet-if-absent'])
82
- end
83
- modified = merge(id, copies)
84
- Clean.new(wallets: @wallets, copies: copies.root, log: @log).run(
85
- ['clean', id.to_s, '--max-age=1']
86
- )
87
- copies.remove(host, Remotes::PORT)
88
- if modified.empty?
89
- @log.info("Accepted #{id} in #{Age.new(start, limit: 1)} and not modified anything")
90
- else
91
- @log.info("Accepted #{id} in #{Age.new(start, limit: 1)} and modified #{modified.join(', ')}")
92
- end
93
- modified << id if copies.all.count > 1
63
+ modified = @pipeline.push(id, body, @wallets, @log)
94
64
  sec = (Time.now - start).round(2)
95
65
  @mutex.synchronize do
96
66
  @history.shift if @history.length >= 16
@@ -102,27 +72,5 @@ module Zold
102
72
  end
103
73
  modified
104
74
  end
105
-
106
- def merge(id, copies)
107
- Tempfile.open do |f|
108
- modified = Merge.new(
109
- wallets: @wallets, remotes: @remotes, copies: copies.root, log: @log
110
- ).run(['merge', id.to_s, "--ledger=#{f.path}", "--network=#{@network}"])
111
- @mutex.synchronize do
112
- txns = File.exist?(@ledger) ? IO.read(@ledger).strip.split("\n") : []
113
- txns += IO.read(f.path).strip.split("\n")
114
- IO.write(
115
- @ledger,
116
- txns.map { |t| t.split(';') }
117
- .uniq { |t| "#{t[1]}-#{t[3]}" }
118
- .reject { |t| Txn.parse_time(t[0]) < Time.now - 24 * 60 * 60 }
119
- .map { |t| t.join(';') }
120
- .join("\n")
121
- .strip
122
- )
123
- end
124
- modified
125
- end
126
- end
127
75
  end
128
76
  end
@@ -319,7 +319,7 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
319
319
  end
320
320
 
321
321
  get %r{/wallet/(?<id>[A-Fa-f0-9]{16})\.html} do
322
- fetch do |wallet|
322
+ fetch('text/html') do |wallet|
323
323
  [
324
324
  '<!DOCTYPE html><html><head>',
325
325
  '<title>' + wallet.id.to_s + '</title>',
@@ -338,8 +338,8 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
338
338
  '<td style="color:' + (t.amount.negative? ? 'red' : 'green') + "\">#{t.id}</td>",
339
339
  "<td>#{t.date.utc.iso8601}</td>",
340
340
  '<td style="text-align:right">' + t.amount.to_zld(4) + '</td>',
341
- "<td><a href='/wallet/#{t.bnf}.html'>#{t.bnf}</td>",
342
- "<td>#{t.details}</td>",
341
+ "<td><a href='/wallet/#{t.bnf}.html'><code>#{t.bnf}</code></a></td>",
342
+ "<td>#{CGI.escapeHTML(t.details)}</td>",
343
343
  '</tr>'
344
344
  ].join
345
345
  end.join,
@@ -350,7 +350,7 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
350
350
  "File size: #{Size.new(wallet.size)}/#{wallet.size}, \
351
351
  #{Copies.new(File.join(settings.copies, wallet.id)).all.count} copies<br/>",
352
352
  "Modified: #{wallet.mtime.utc.iso8601} (#{Age.new(wallet.mtime.utc.iso8601)} ago)<br/>",
353
- "Digest: #{wallet.digest}</p></section></body></html>"
353
+ "Digest: <code>#{wallet.digest}</code></p></section></body></html>"
354
354
  ].join
355
355
  end
356
356
  end
@@ -488,7 +488,8 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
488
488
  '<link href="https://cdn.jsdelivr.net/gh/yegor256/tacit@gh-pages/tacit-css-1.4.2.min.css" rel="stylesheet"/>',
489
489
  '</head><body><section>',
490
490
  DirItems.new(settings.journal_dir).fetch.sort.map do |f|
491
- "<p><a href='/journal/item?id=#{f}'>#{f}</a></p>"
491
+ file = File.join(settings.journal_dir, f)
492
+ "<p><a href='/journal/item?id=#{f}'>#{f}</a>: #{File.size(file)} #{Age.new(File.mtime(file))} ago</p>"
492
493
  end.join,
493
494
  '</section></body></html>'
494
495
  ].join
@@ -21,23 +21,18 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'tempfile'
24
+ require 'diffy'
25
+ require_relative 'pipeline'
24
26
  require_relative '../log'
25
- require_relative '../remotes'
26
- require_relative '../copies'
27
- require_relative '../tax'
28
27
  require_relative '../age'
29
- require_relative '../commands/clean'
30
- require_relative '../commands/merge'
31
- require_relative '../commands/fetch'
32
- require_relative '../commands/push'
33
28
 
34
- # The entrance with journals.
29
+ # The pipeline with journals.
35
30
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
36
31
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
37
32
  # License:: MIT
38
33
  module Zold
39
34
  # The entrance that keeps a journal for each wallet
40
- class JournaledEntrance
35
+ class JournaledPipeline
41
36
  # Decorated wallets
42
37
  class Wallets < SimpleDelegator
43
38
  def initialize(wallets, log)
@@ -61,12 +56,9 @@ module Zold
61
56
  end
62
57
  end
63
58
 
64
- def initialize(entrance, wallets, dir, log, journal)
65
- @wallets = JournaledEntrance::Wallets.new(wallets, log)
66
- @entrance = entrance
67
- @dir = File.expand_path(dir)
68
- @log = log
69
- @journal = File.join(@dir, journal)
59
+ def initialize(pipeline, dir)
60
+ @pipeline = pipeline
61
+ @dir = dir
70
62
  end
71
63
 
72
64
  def start
@@ -76,21 +68,24 @@ module Zold
76
68
  end
77
69
 
78
70
  def to_json
79
- @entrance.to_json.merge(
71
+ @pipeline.to_json.merge(
80
72
  'dir': @dir
81
73
  )
82
74
  end
83
75
 
84
76
  # Returns a list of modifed wallets (as Zold::Id)
85
- def push(id, body)
77
+ def push(id, body, wallets, log)
86
78
  DirItems.new(@dir).fetch.each do |f|
87
79
  f = File.join(@dir, f)
88
80
  File.delete(f) if File.mtime(f) < Time.now - 24 * 60 * 60
89
81
  end
90
- @log.info("push(#{id}, #{body.length} bytes)")
91
- modified = @entrance.push(id, body)
92
- IO.write(File.join(@dir, "#{Time.now.utc.iso8601.gsub(/[^0-9]/, '-')}-#{id}"), IO.read(@journal))
93
- modified
82
+ journal = File.join(@dir, "#{Time.now.utc.iso8601.gsub(/[^0-9]/, '-')}-#{id}")
83
+ jlog = Logger.new(journal)
84
+ jlog.level = Logger::DEBUG
85
+ jlog.formatter = Log::COMPACT
86
+ tlog = Log::Tee.new(log, jlog)
87
+ tlog.info("push(#{id}, #{body.length} bytes)")
88
+ @pipeline.push(id, body, JournaledPipeline::Wallets.new(wallets, jlog), tlog)
94
89
  end
95
90
  end
96
91
  end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2018-2019 Zerocracy, Inc.
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 'tempfile'
24
+ require_relative '../log'
25
+ require_relative '../remotes'
26
+ require_relative '../copies'
27
+ require_relative '../tax'
28
+ require_relative '../age'
29
+ require_relative '../commands/clean'
30
+ require_relative '../commands/merge'
31
+ require_relative '../commands/fetch'
32
+ require_relative '../commands/push'
33
+
34
+ # The pipeline that accepts new wallets and merges them.
35
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
36
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
37
+ # License:: MIT
38
+ module Zold
39
+ # The pipeline
40
+ class Pipeline
41
+ def initialize(remotes, copies, address, ledger: '/dev/null', network: 'test')
42
+ @remotes = remotes
43
+ @copies = copies
44
+ @address = address
45
+ @network = network
46
+ @history = []
47
+ @speed = []
48
+ @mutex = Mutex.new
49
+ @ledger = ledger
50
+ end
51
+
52
+ # Show its internals.
53
+ def to_json
54
+ {
55
+ 'ledger': File.exist?(@ledger) ? IO.read(@ledger).split("\n").count : 0
56
+ }
57
+ end
58
+
59
+ # Returns a list of modifed wallets (as Zold::Id)
60
+ def push(id, body, wallets, log)
61
+ start = Time.now
62
+ copies = Copies.new(File.join(@copies, id.to_s))
63
+ host = '0.0.0.0'
64
+ copies.add(body, host, Remotes::PORT, 0)
65
+ unless @remotes.all.empty?
66
+ Fetch.new(
67
+ wallets: wallets, remotes: @remotes, copies: copies.root, log: log
68
+ ).run(['fetch', id.to_s, "--ignore-node=#{@address}", "--network=#{@network}", '--quiet-if-absent'])
69
+ end
70
+ modified = merge(id, copies, wallets, log)
71
+ Clean.new(wallets: wallets, copies: copies.root, log: log).run(
72
+ ['clean', id.to_s, '--max-age=1']
73
+ )
74
+ copies.remove(host, Remotes::PORT)
75
+ if modified.empty?
76
+ log.info("Accepted #{id} in #{Age.new(start, limit: 1)} and not modified anything")
77
+ else
78
+ log.info("Accepted #{id} in #{Age.new(start, limit: 1)} and modified #{modified.join(', ')}")
79
+ end
80
+ modified << id if copies.all.count > 1
81
+ modified
82
+ end
83
+
84
+ private
85
+
86
+ def merge(id, copies, wallets, log)
87
+ Tempfile.open do |f|
88
+ modified = Merge.new(
89
+ wallets: wallets, remotes: @remotes, copies: copies.root, log: log
90
+ ).run(['merge', id.to_s, "--ledger=#{f.path}", "--network=#{@network}"])
91
+ @mutex.synchronize do
92
+ txns = File.exist?(@ledger) ? IO.read(@ledger).strip.split("\n") : []
93
+ txns += IO.read(f.path).strip.split("\n")
94
+ IO.write(
95
+ @ledger,
96
+ txns.map { |t| t.split(';') }
97
+ .uniq { |t| "#{t[1]}-#{t[3]}" }
98
+ .reject { |t| Txn.parse_time(t[0]) < Time.now - 24 * 60 * 60 }
99
+ .map { |t| t.join(';') }
100
+ .join("\n")
101
+ .strip
102
+ )
103
+ end
104
+ modified
105
+ end
106
+ end
107
+ end
108
+ end
data/lib/zold/version.rb CHANGED
@@ -25,7 +25,7 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.26.16'
28
+ VERSION = '0.26.17'
29
29
  PROTOCOL = 2
30
30
  REPO = 'zold-io/zold'
31
31
  end
@@ -29,6 +29,7 @@ require_relative '../../lib/zold/remotes'
29
29
  require_relative '../../lib/zold/id'
30
30
  require_relative '../../lib/zold/key'
31
31
  require_relative '../../lib/zold/node/entrance'
32
+ require_relative '../../lib/zold/node/pipeline'
32
33
  require_relative '../../lib/zold/commands/pay'
33
34
 
34
35
  # ENTRANCE test.
@@ -54,7 +55,11 @@ class TestEntrance < Zold::Test
54
55
  source = home.create_wallet(sid)
55
56
  target = home.create_wallet(tid)
56
57
  ledger = File.join(home.dir, 'ledger.csv')
57
- e = Zold::Entrance.new(home.wallets, home.remotes, home.copies(source).root, 'x', ledger: ledger, log: test_log)
58
+ e = Zold::Entrance.new(
59
+ home.wallets,
60
+ Zold::Pipeline.new(home.remotes, home.copies(source).root, 'x', ledger: ledger),
61
+ log: test_log
62
+ )
58
63
  modified = e.push(source.id, body)
59
64
  assert_equal(2, modified.count)
60
65
  assert_equal(Zold::Amount.new(zld: -19.99), source.balance)
@@ -68,7 +73,7 @@ class TestEntrance < Zold::Test
68
73
  def test_renders_json
69
74
  FakeHome.new(log: test_log).run do |home|
70
75
  wallet = home.create_wallet
71
- e = Zold::Entrance.new(home.wallets, home.remotes, home.copies.root, 'x', log: test_log)
76
+ e = Zold::Entrance.new(home.wallets, Zold::Pipeline.new(home.remotes, home.copies.root, 'x'), log: test_log)
72
77
  e.push(wallet.id, IO.read(wallet.path))
73
78
  assert(e.to_json[:history].include?(wallet.id.to_s))
74
79
  assert(!e.to_json[:speed].negative?)
@@ -139,7 +139,7 @@ class FrontTest < Zold::Test
139
139
  def test_increments_score
140
140
  FakeNode.new(log: test_log).run(opts('--threads=1')) do |port|
141
141
  3.times do |i|
142
- assert_equal_wait(true) do
142
+ assert_equal_wait(true, max: 60) do
143
143
  response = Zold::Http.new(uri: "http://localhost:#{port}/").get
144
144
  assert_equal(200, response.status, response.body)
145
145
  score = Zold::Score.parse_json(Zold::JsonPage.new(response.body).to_hash['score'])
@@ -26,6 +26,7 @@ require_relative 'fake_node'
26
26
  require_relative '../test__helper'
27
27
  require_relative '../../lib/zold/id'
28
28
  require_relative '../../lib/zold/node/entrance'
29
+ require_relative '../../lib/zold/node/pipeline'
29
30
  require_relative '../../lib/zold/node/spread_entrance'
30
31
  require_relative 'fake_entrance'
31
32
 
@@ -38,7 +39,11 @@ class TestSpreadEntrance < Zold::Test
38
39
  FakeHome.new(log: test_log).run do |home|
39
40
  wallet = home.create_wallet(Zold::Id.new)
40
41
  Zold::SpreadEntrance.new(
41
- Zold::Entrance.new(home.wallets, home.remotes, home.copies(wallet).root, 'x', log: test_log),
42
+ Zold::Entrance.new(
43
+ home.wallets,
44
+ Zold::Pipeline.new(home.remotes, home.copies(wallet).root, 'x'),
45
+ log: test_log
46
+ ),
42
47
  home.wallets, home.remotes, 'x', log: test_log
43
48
  ).start do |e|
44
49
  assert_equal(0, e.to_json[:modified])
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zold
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.16
4
+ version: 0.26.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -671,9 +671,10 @@ files:
671
671
  - lib/zold/node/farm.rb
672
672
  - lib/zold/node/farmers.rb
673
673
  - lib/zold/node/front.rb
674
- - lib/zold/node/journaled_entrance.rb
674
+ - lib/zold/node/journaled_pipeline.rb
675
675
  - lib/zold/node/nodup_entrance.rb
676
676
  - lib/zold/node/nospam_entrance.rb
677
+ - lib/zold/node/pipeline.rb
677
678
  - lib/zold/node/safe_entrance.rb
678
679
  - lib/zold/node/soft_error.rb
679
680
  - lib/zold/node/spread_entrance.rb
@@ -780,7 +781,7 @@ licenses:
780
781
  - MIT
781
782
  metadata: {}
782
783
  post_install_message: |-
783
- Thanks for installing Zold 0.26.16!
784
+ Thanks for installing Zold 0.26.17!
784
785
  Study our White Paper: https://papers.zold.io/wp.pdf
785
786
  Read our blog posts: https://blog.zold.io
786
787
  Try ZLD online wallet at: https://wts.zold.io