zold 0.7 → 0.8

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
  SHA1:
3
- metadata.gz: cb70a77181642453c08fcda55cd1179d84ad47d3
4
- data.tar.gz: 4d5c99e488c3196efcb4b98b5f698fadddd72625
3
+ metadata.gz: 5ea54309f6fdd147d4338a76415d536e802ffa00
4
+ data.tar.gz: 2cc82cfbe9c204480db65348cc551abad0817d92
5
5
  SHA512:
6
- metadata.gz: b692c87274e9fe516d80cccee43ccc172f03b151732d33271bf6a256e0fd2355af8d0bce3517dc19e7f7b9842c2f778734c0501c3093e6130b561f60da2c933b
7
- data.tar.gz: b0c91ee622378ebcb8b96816c8281ac463153fc6d2daca6591322f3fbd8011cf3b2df954ce5178834efa9833a0711f29f25bd09831597cd153d65d5926971503
6
+ metadata.gz: 64bfd2b5f86befba60e4f976cef6e4e17d3233c5a8d7d48b214dc4e4bbe787afe351a4e783355baa63f844410d1ef923feac211d6186db45215512c79fc79c8e
7
+ data.tar.gz: f648ceffd6b1b5c2d34fd88816cc77dc8705bf3382ae2b6a22397894fd3d1d010168736c38ce2e934196c20b50deabb41d507d6992b1c9531fc8e01a4374136a
data/README.md CHANGED
@@ -93,3 +93,22 @@ $ zold node --invoice=5f96e731e48ae21f
93
93
 
94
94
  Grateful users of the system will pay "taxes" to your wallet for processing
95
95
  of their transactions.
96
+
97
+ ## How to Contribute
98
+
99
+ It is a Ruby command line gem. First, install
100
+ [Ruby](https://www.ruby-lang.org/en/documentation/installation/) 2.3+,
101
+ [Rubygems](https://rubygems.org/pages/download),
102
+ and
103
+ [Bundler](https://bundler.io/).
104
+ Then:
105
+
106
+ ```bash
107
+ $ bundle update
108
+ $ rake
109
+ ```
110
+
111
+ The build has to be clean. If it's not, [submit an issue](https://github.com/zerocracy/zold/issues).
112
+
113
+ Then, make your changes, make sure the build is still clean,
114
+ and [submit a pull request](https://www.yegor256.com/2014/04/15/github-guidelines.html).
@@ -19,6 +19,7 @@
19
19
  # SOFTWARE.
20
20
 
21
21
  require_relative '../log'
22
+ require_relative '../wallet'
22
23
 
23
24
  # LIST command.
24
25
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -35,7 +36,9 @@ module Zold
35
36
  def run(_ = [])
36
37
  @wallets.all.each do |id|
37
38
  wallet = Wallet.new(File.join(@wallets.path, id))
38
- @log.info("#{id}: #{wallet.balance}")
39
+ msg = "#{id}: #{wallet.balance}"
40
+ msg += " (net:#{wallet.network})" if wallet.network != Wallet::MAIN_NETWORK
41
+ @log.info(msg)
39
42
  end
40
43
  end
41
44
  end
@@ -64,9 +64,13 @@ Available options:"
64
64
  @log.debug("#{t.amount * -1} to #{t.bnf}: wallet is absent")
65
65
  next
66
66
  end
67
+ unless target.network == wallet.network
68
+ @log.error("#{t.amount * -1} to #{t.bnf}: network mismatch, '#{target.network}'!='#{wallet.network}'")
69
+ next
70
+ end
67
71
  next if target.has?(t.id, me)
68
72
  unless Prefixes.new(target).valid?(t.prefix)
69
- @log.info("#{t.amount * -1} to #{t.bnf}: wrong prefix")
73
+ @log.error("#{t.amount * -1} to #{t.bnf}: wrong prefix")
70
74
  next
71
75
  end
72
76
  target.add(t.inverse(me))
@@ -24,6 +24,7 @@ require_relative 'args'
24
24
  require_relative '../log'
25
25
  require_relative '../id'
26
26
  require_relative '../amount'
27
+ require_relative '../wallet'
27
28
 
28
29
  # SHOW command.
29
30
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -61,7 +62,9 @@ Available options:"
61
62
  wallet.txns.each do |t|
62
63
  @log.info(t.to_text)
63
64
  end
64
- @log.info("The balance of #{wallet}: #{balance}")
65
+ msg = "The balance of #{wallet}: #{balance}"
66
+ msg += " (net:#{wallet.network})" if wallet.network != Wallet::MAIN_NETWORK
67
+ @log.info(msg)
65
68
  balance
66
69
  end
67
70
  end
@@ -0,0 +1,58 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'concurrent'
22
+ require 'tempfile'
23
+ require_relative '../log'
24
+ require_relative '../remotes'
25
+ require_relative '../copies'
26
+ require_relative '../tax'
27
+ require_relative '../commands/merge'
28
+ require_relative '../commands/fetch'
29
+ require_relative '../commands/push'
30
+
31
+ # The emission control point.
32
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
33
+ # Copyright:: Copyright (c) 2018 Yegor Bugayenko
34
+ # License:: MIT
35
+ module Zold
36
+ # The emission control poine
37
+ class Emission
38
+ def initialize(root)
39
+ @root = root
40
+ end
41
+
42
+ def quota
43
+ 2**(-2048 / @root.age)
44
+ end
45
+
46
+ def limit
47
+ max = 2**63
48
+ Amount.new(coins: (max * quota).to_i)
49
+ end
50
+
51
+ def check
52
+ return unless @root.root?
53
+ allowed = limit
54
+ balance = @root.balance
55
+ raise "The balance #{balance} of the root wallet is too low (max allowed: #{allowed})" if balance < allowed
56
+ end
57
+ end
58
+ end
@@ -19,6 +19,8 @@
19
19
  # SOFTWARE.
20
20
 
21
21
  require 'concurrent'
22
+ require 'tempfile'
23
+ require_relative 'emission'
22
24
  require_relative '../log'
23
25
  require_relative '../remotes'
24
26
  require_relative '../copies'
@@ -44,12 +46,28 @@ module Zold
44
46
  end
45
47
 
46
48
  def push(id, body)
49
+ check(body)
47
50
  @semaphores.put_if_absent(id, Mutex.new)
48
51
  @semaphores.get(id).synchronize do
49
52
  push_unsafe(id, body)
50
53
  end
51
54
  end
52
55
 
56
+ def check(body)
57
+ Tempfile.open do |f|
58
+ File.write(f.path, body)
59
+ wallet = Wallet.new(f)
60
+ break unless wallet.network == Wallet::MAIN_NETWORK
61
+ balance = wallet.balance
62
+ raise "The balance #{balance} is negative and it's not a root wallet" if balance.negative? && !wallet.root?
63
+ Emission.new(wallet).check
64
+ debt = Tax.new(wallet).debt
65
+ if debt > Tax::TRIAL
66
+ raise "Taxes are not paid, the debt is #{debt} (#{debt.to_i} zents), won't promote the wallet"
67
+ end
68
+ end
69
+ end
70
+
53
71
  def push_unsafe(id, body)
54
72
  copies = Copies.new(File.join(@copies, id.to_s))
55
73
  copies.add(body, 'remote', Remotes::PORT, 0)
@@ -59,10 +77,6 @@ module Zold
59
77
  modified = Merge.new(
60
78
  wallets: @wallets, copies: copies.root, log: @log
61
79
  ).run(['merge', id.to_s])
62
- debt = Tax.new(@wallets.find(id)).debt
63
- if debt > Tax::TRIAL
64
- raise "Taxes are not paid, the debt is #{debt} (#{debt.to_i} zents), won't promote the wallet"
65
- end
66
80
  copies.remove('remote', Remotes::PORT)
67
81
  modified.each do |m|
68
82
  Push.new(
data/lib/zold/tax.rb CHANGED
@@ -69,8 +69,7 @@ module Zold
69
69
  score
70
70
  end.reject(&:nil?).uniq(&:hash)
71
71
  paid = scores.empty? ? Amount::ZERO : scores.map(&:amount).inject(&:+) * -1
72
- age_hours = txns.empty? ? 0 : (Time.now - txns.sort_by(&:date)[0].date) / 60
73
- owned = Tax::FEE_TXN_HOUR * txns.count * age_hours
72
+ owned = Tax::FEE_TXN_HOUR * txns.count * @wallet.age
74
73
  owned - paid
75
74
  end
76
75
  end
data/lib/zold/version.rb CHANGED
@@ -23,5 +23,5 @@
23
23
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
24
24
  # License:: MIT
25
25
  module Zold
26
- VERSION = '0.7'.freeze
26
+ VERSION = '0.8'.freeze
27
27
  end
data/lib/zold/wallet.rb CHANGED
@@ -38,6 +38,10 @@ require_relative 'signature'
38
38
  module Zold
39
39
  # A single wallet
40
40
  class Wallet
41
+ # The name of the main production network. All other networks
42
+ # must have different names.
43
+ MAIN_NETWORK = 'zold'.freeze
44
+
41
45
  def initialize(file)
42
46
  @file = file
43
47
  end
@@ -127,6 +131,12 @@ module Zold
127
131
  end
128
132
  end
129
133
 
134
+ # Age of wallet in hours
135
+ def age
136
+ list = txns
137
+ list.empty? ? 0 : (Time.now - list.sort_by(&:date)[0].date) / 60
138
+ end
139
+
130
140
  def txns
131
141
  lines.drop(5)
132
142
  .each_with_index
@@ -0,0 +1,46 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'minitest/autorun'
22
+ require 'tmpdir'
23
+ require_relative '../test__helper'
24
+ require_relative '../../lib/zold/node/emission'
25
+ require_relative '../../lib/zold/amount'
26
+
27
+ class EmissionTest < Minitest::Test
28
+ def test_emission
29
+ (1..10).each do |year|
30
+ Dir.mktmpdir 'test' do |dir|
31
+ id = Zold::Id.new
32
+ wallet = Zold::Wallet.new(File.join(dir, id.to_s))
33
+ wallet.init(id, Zold::Key.new(file: 'fixtures/id_rsa.pub'))
34
+ wallet.add(
35
+ Zold::Txn.new(
36
+ 1, Time.now - 24 * 365 * year,
37
+ Zold::Amount.new(zld: 39.99),
38
+ 'NOPREFIX', Zold::Id::ROOT, '-'
39
+ )
40
+ )
41
+ $log.info("Year: #{year}, Quota: #{(Zold::Emission.new(wallet).quota * 100).round(2)}%, \
42
+ Limit: #{Zold::Emission.new(wallet).limit}")
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,29 @@
1
+ # Copyright (c) 2018 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ require 'minitest/autorun'
22
+ require_relative '../../lib/zold/node/entrance'
23
+ require_relative '../../lib/zold/amount'
24
+
25
+ class EntranceTest < Minitest::Test
26
+ def test_something
27
+ # tbd...
28
+ end
29
+ end
data/test/test__helper.rb CHANGED
@@ -31,6 +31,7 @@ end
31
31
 
32
32
  require_relative '../lib/zold/log'
33
33
  $log = Zold::Log::Quiet.new
34
+ # $log = Zold::Log::Verbose.new
34
35
 
35
36
  require 'minitest/autorun'
36
37
  require_relative '../lib/zold'
data/test/test_zold.rb CHANGED
@@ -21,6 +21,7 @@
21
21
  require 'minitest/autorun'
22
22
  require 'tmpdir'
23
23
  require 'English'
24
+ require_relative 'test__helper'
24
25
 
25
26
  # Zold main module test.
26
27
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -37,10 +38,8 @@ class TestZold < Minitest::Test
37
38
  bin = File.join(Dir.pwd, 'bin/zold')
38
39
  Dir.chdir(dir) do
39
40
  stdout = `/bin/bash #{f} #{bin} 2>&1`
40
- unless $CHILD_STATUS.exitstatus.zero?
41
- $log.info(stdout)
42
- assert_equal($CHILD_STATUS.exitstatus, 0)
43
- end
41
+ $log.info(stdout)
42
+ assert_equal(0, $CHILD_STATUS.exitstatus)
44
43
  end
45
44
  end
46
45
  end
data/wp/wp.tex CHANGED
@@ -5,6 +5,7 @@
5
5
  \usepackage{microtype}
6
6
  \usepackage{mathpazo} % Palantino font
7
7
  \usepackage{mdframed}
8
+ \usepackage{pgfplots}
8
9
  \usepackage{minted}
9
10
  \setminted{fontsize=\small}
10
11
  \setminted{breaklines}
@@ -92,11 +93,12 @@ One ZLD by convention equals to $2^{24}$ \emph{zents} (16,777,216).
92
93
  All amounts are stored as signed 64-bit integers.
93
94
  Thus, the technical capacity of the currency is 549,755,813,888 ZLD (half a trillion).
94
95
 
95
- \textbf{Zero Wallet}.
96
- There is no ``mining,'' the only way to get ZLD is to receive it from someone else.
97
- The wallet with the \dd{0x00} ID belongs to the
98
- issuer and may have a negative balance. All other wallets
99
- may only have positive balances.
96
+ \textbf{Root Wallet}.
97
+ Zold is a pre-mined currency.
98
+ The only way to get ZLD is to receive it from someone else.
99
+ The root wallet belongs to the issuer and may have a negative balance,
100
+ which can grow according to a pre-defined restrictive formula.
101
+ All other wallets may only have positive balances.
100
102
 
101
103
  \colorbox{yellow}{Let's compare each of these principles with other currencies and highlight similarities.}
102
104
 
@@ -268,6 +270,51 @@ Each transaction takes 900 symbols at most.
268
270
  The maximum amount of transactions in one wallet is 65536.
269
271
  Thus, a single wallet may be as big as a 59Mb text file, at most.
270
272
 
273
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
274
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275
+ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276
+ \section{Mining Formula}
277
+
278
+ The only way to get ZLD is to receive it from the \emph{root} wallet \dd{0000000000000000}.
279
+ This wallet is the only one that may have a negative ballance.
280
+ However, to prevent an uncontrolled emission of ZLD, the balance
281
+ of this wallet must satisfy the formula:
282
+
283
+ $$x = \frac{2048}{h};\quad z = 2^{63 - x}.$$
284
+
285
+ Here $h$ is the age of the root wallet in hours and $z$ is the maximum
286
+ amount of zents it can issue at that moment. The first
287
+ six years will look like this:
288
+
289
+ \vspace{\parskip}\begin{center}\begin{tabular}{lrr}
290
+ \hline
291
+ Year & ZLD & Share \\
292
+ \hline
293
+ 1st & 32m & 0.01\% \\
294
+ 2nd & 4b & 0.77\% \\
295
+ 3rd & 21b & 4\%\\
296
+ 4th & 48b & 9\% \\
297
+ 5th & 78b & 14\% \\
298
+ 6th & 108b & 20\% \\
299
+ \hline
300
+ \end{tabular}\end{center}
301
+
302
+ On a large perspective of 25 years total emission of ZLD will look
303
+ like this:
304
+
305
+ \vspace{\parskip}\begin{center}\begin{tikzpicture}
306
+ \begin{axis}[
307
+ axis lines=middle,
308
+ width=12cm,height=5cm,
309
+ xlabel={Age, in years},
310
+ ylabel={Billions of ZLD},
311
+ ]
312
+ \addplot[domain=-0:25, samples=25]{2^(39-2048/(x*24*365)) / 1000000000};
313
+ \end{axis}
314
+ \end{tikzpicture}\end{center}
315
+
316
+ The limitation is hardwired in Zold software and can't be eliminated.
317
+
271
318
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272
319
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273
320
  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.7'
4
+ version: '0.8'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -298,6 +298,7 @@ files:
298
298
  - lib/zold/id.rb
299
299
  - lib/zold/key.rb
300
300
  - lib/zold/log.rb
301
+ - lib/zold/node/emission.rb
301
302
  - lib/zold/node/entrance.rb
302
303
  - lib/zold/node/farm.rb
303
304
  - lib/zold/node/front.rb
@@ -327,6 +328,8 @@ files:
327
328
  - test/commands/test_show.rb
328
329
  - test/commands/test_taxes.rb
329
330
  - test/node/fake_node.rb
331
+ - test/node/test_emission.rb
332
+ - test/node/test_entrance.rb
330
333
  - test/node/test_farm.rb
331
334
  - test/node/test_front.rb
332
335
  - test/test__helper.rb
@@ -396,6 +399,8 @@ test_files:
396
399
  - test/commands/test_show.rb
397
400
  - test/commands/test_taxes.rb
398
401
  - test/node/fake_node.rb
402
+ - test/node/test_emission.rb
403
+ - test/node/test_entrance.rb
399
404
  - test/node/test_farm.rb
400
405
  - test/node/test_front.rb
401
406
  - test/test__helper.rb