zold 0.23.11 → 0.24.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5849ac3bfc78f34607a15fa94739391b1d655f9c2870d1eb0de3fb9d2eaa2603
4
- data.tar.gz: 345524d2e2202209dc7a8fcd64835b0168fe58c18035db7d8b208a638e332d88
3
+ metadata.gz: fede79d35bed10c7da7902883eeaca119b416034d9e39c3fae34a6cb33994ae2
4
+ data.tar.gz: e2f01c2f7fa5739164b98e541697822b629b92d749bf96aa6b26e5c94d8b49ea
5
5
  SHA512:
6
- metadata.gz: b274dd3d8f5a7441ba06704e1d3b0baaa14f0b96ba431e163864a7e4652b3f85267f763015b0569b51c0eeb2610cadf9a1ec980a8d08a1256a53ca42753251bf
7
- data.tar.gz: 0e22e857b8a5aee8b06df59f1979bc33d7c740fb6ffd6ef920f587eea59a0e23c5ec04131bbc7cb09fed31afb8bdf785fdc5e91f703f070cb4903d5cfa45d70c
6
+ metadata.gz: b05c9c74665361bc4ca45bb0259f048fa88f69693470cecf9195f8cbbfbe68afa2eece977a714b5f39ab1bdd749649b96b42c6c3bf16544be3659deeef430f9e
7
+ data.tar.gz: aa6a7d2415c2b0dff71153704253a9c84e62f6a952e8c92aabac753a9028f1978c2ef77824b102efcd542a1662e298282c435c86199e611448f5bdbe975bc822
@@ -62,6 +62,9 @@ Available options:"
62
62
  o.bool '--shallow',
63
63
  'Don\'t try to pull other wallets if their confirmations are required',
64
64
  default: false
65
+ o.string '--ledger',
66
+ 'The name of the file where all new negative transactions will be recorded (default: /dev/null)',
67
+ default: '/dev/null'
65
68
  o.string '--network',
66
69
  'The name of the network we work in',
67
70
  default: 'test'
@@ -128,12 +131,12 @@ into #{@wallets.acq(id, &:mnemo)} in #{Age.new(start, limit: 0.1 + cps.count * 0
128
131
  start = Time.now
129
132
  @log.debug("Building a patch for #{wallet.id} from remote copy ##{name} with #{wallet.mnemo}...")
130
133
  if opts['shallow']
131
- patch.join(wallet) do |txn|
134
+ patch.join(wallet, ledger: opts['ledger']) do |txn|
132
135
  @log.debug("Paying wallet #{txn.bnf} file is absent but it's a \"shallow\" MERGE: #{txn.to_text}")
133
136
  false
134
137
  end
135
138
  else
136
- patch.join(wallet) do |txn|
139
+ patch.join(wallet, ledger: opts['ledger']) do |txn|
137
140
  Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
138
141
  ['pull', txn.bnf.to_s, "--network=#{opts['network']}", '--shallow']
139
142
  )
@@ -258,6 +258,8 @@ the node won\'t connect to the network like that; try to do "zold remote reset"
258
258
  Front.set(:copies, @copies)
259
259
  Front.set(:address, address)
260
260
  Front.set(:root, home)
261
+ ledger = File.join(home, 'ledger.csv')
262
+ Front.set(:ledger, ledger)
261
263
  Front.set(:opts, opts)
262
264
  Front.set(:dump_errors, opts['dump-errors'])
263
265
  Front.set(:port, opts['bind-port'])
@@ -270,6 +272,7 @@ the node won\'t connect to the network like that; try to do "zold remote reset"
270
272
  SyncEntrance.new(
271
273
  Entrance.new(
272
274
  wts, @remotes, @copies, address,
275
+ ledger: ledger,
273
276
  log: @log, network: opts['network']
274
277
  ),
275
278
  File.join(home, '.zoldata/sync-entrance'),
@@ -74,12 +74,12 @@ Available commands:
74
74
  #{Rainbow('remote trim').green}
75
75
  Remove the least reliable nodes
76
76
  #{Rainbow('remote select [options]').green}
77
- Select the most reliable N nodes.
77
+ Select the most reliable N nodes
78
78
  #{Rainbow('remote update').green}
79
79
  Check each registered remote node for availability
80
80
  Available options:"
81
81
  o.integer '--tolerate',
82
- 'Maximum level of errors we are able to tolerate',
82
+ "Maximum level of errors we are able to tolerate (default: #{Remotes::TOLERANCE})",
83
83
  default: Remotes::TOLERANCE
84
84
  o.bool '--ignore-score-weakness',
85
85
  'Don\'t complain when their score is too weak',
@@ -115,10 +115,10 @@ Available options:"
115
115
  'Don\'t fail if ping fails, just report the problem in the log',
116
116
  default: false
117
117
  o.integer '--depth',
118
- 'The amount of update cycles to run, in order to fetch as many nodes as possible (default: 2)',
118
+ 'The amount of update cycles to run, in order to fetch as many nodes as possible (default: 3)',
119
119
  default: 3
120
120
  o.string '--network',
121
- "The name of the network we work in (default: #{Wallet::MAINET}",
121
+ "The name of the network we work in (default: #{Wallet::MAINET})",
122
122
  required: true,
123
123
  default: Wallet::MAINET
124
124
  o.bool '--reboot',
@@ -134,7 +134,7 @@ Available options:"
134
134
  # - Remove note from the --max-nodes option saying that it applies to the select
135
135
  # subcommand only.
136
136
  o.integer '--max-nodes',
137
- "This applies only to the select subcommand. Number of nodes to limit to. Defaults to #{Remotes::MAX_NODES}.",
137
+ "Number of nodes to limit to (default: #{Remotes::MAX_NODES})",
138
138
  default: Remotes::MAX_NODES
139
139
  o.bool '--help', 'Print instructions'
140
140
  end
@@ -39,7 +39,8 @@ require_relative '../commands/push'
39
39
  module Zold
40
40
  # The entrance
41
41
  class Entrance
42
- def initialize(wallets, remotes, copies, address, log: Log::NULL, network: 'test')
42
+ def initialize(wallets, remotes, copies, address, ledger: '/dev/null',
43
+ log: Log::NULL, network: 'test')
43
44
  @wallets = wallets
44
45
  @remotes = remotes
45
46
  @copies = copies
@@ -49,6 +50,7 @@ module Zold
49
50
  @history = []
50
51
  @speed = []
51
52
  @mutex = Mutex.new
53
+ @ledger = ledger
52
54
  end
53
55
 
54
56
  def start
@@ -60,7 +62,8 @@ module Zold
60
62
  {
61
63
  'history': @history.join(', '),
62
64
  'history_size': @history.count,
63
- 'speed': @speed.empty? ? 0 : (@speed.inject(&:+) / @speed.count)
65
+ 'speed': @speed.empty? ? 0 : (@speed.inject(&:+) / @speed.count),
66
+ 'ledger': File.exist?(@ledger) ? IO.read(@ledger).split("\n").count : 0
64
67
  }
65
68
  end
66
69
 
@@ -78,9 +81,7 @@ module Zold
78
81
  wallets: @wallets, remotes: @remotes, copies: copies.root, log: @log
79
82
  ).run(['fetch', id.to_s, "--ignore-node=#{@address}", "--network=#{@network}", '--quiet-if-absent'])
80
83
  end
81
- modified = Merge.new(
82
- wallets: @wallets, remotes: @remotes, copies: copies.root, log: @log
83
- ).run(['merge', id.to_s])
84
+ modified = merge(id, copies)
84
85
  Clean.new(wallets: @wallets, copies: copies.root, log: @log).run(['clean', id.to_s])
85
86
  copies.remove(localhost, Remotes::PORT)
86
87
  modified += Rebase.new(wallets: @wallets, log: @log).run(['rebase', id.to_s])
@@ -100,5 +101,27 @@ module Zold
100
101
  end
101
102
  modified
102
103
  end
104
+
105
+ def merge(id, copies)
106
+ Tempfile.open do |f|
107
+ modified = Merge.new(
108
+ wallets: @wallets, remotes: @remotes, copies: copies.root, log: @log
109
+ ).run(['merge', id.to_s, "--ledger=#{f.path}"])
110
+ @mutex.synchronize do
111
+ txns = File.exist?(@ledger) ? IO.read(@ledger).strip.split("\n") : []
112
+ txns += IO.read(f.path).strip.split("\n")
113
+ IO.write(
114
+ @ledger,
115
+ txns.map { |t| t.split(';') }
116
+ .uniq { |t| "#{t[1]}-#{t[3]}" }
117
+ .reject { |t| Txn.parse_time(t[0]) < Time.now - 24 * 60 * 60 }
118
+ .map { |t| t.join(';') }
119
+ .join("\n")
120
+ .strip
121
+ )
122
+ end
123
+ modified
124
+ end
125
+ end
103
126
  end
104
127
  end
@@ -62,6 +62,7 @@ module Zold
62
62
  set :server, :thin
63
63
  set :opts, nil # to be injected at node.rb
64
64
  set :log, nil # to be injected at node.rb
65
+ set :ledger, nil # to be injected at node.rb
65
66
  set :trace, nil # to be injected at node.rb
66
67
  set :dump_errors, false # to be injected at node.rb
67
68
  set :protocol, PROTOCOL # to be injected at node.rb
@@ -384,6 +385,30 @@ this is not a normal behavior, you may want to report a bug to our GitHub reposi
384
385
  )
385
386
  end
386
387
 
388
+ get '/ledger' do
389
+ content_type('text/plain')
390
+ File.exist?(settings.ledger) ? IO.read(settings.ledger) : ''
391
+ end
392
+
393
+ get '/ledger.json' do
394
+ content_type('application/json')
395
+ pretty(
396
+ (File.exist?(settings.ledger) ? IO.read(settings.ledger).split("\n") : []).map do |t|
397
+ parts = t.split(';')
398
+ {
399
+ found: parts[0],
400
+ id: parts[1].to_i,
401
+ date: parts[2],
402
+ source: parts[3],
403
+ target: parts[4],
404
+ amount: parts[5],
405
+ prefix: parts[6],
406
+ details: parts[7]
407
+ }
408
+ end
409
+ )
410
+ end
411
+
387
412
  get '/farm' do
388
413
  content_type('text/plain')
389
414
  settings.farm.to_text
@@ -58,7 +58,7 @@ module Zold
58
58
  # Joins a new wallet on top of existing patch. An attempt is made to
59
59
  # copy as many transactions from the newcoming wallet to the existing
60
60
  # set of transactions, avoiding mistakes and duplicates.
61
- def join(wallet)
61
+ def join(wallet, ledger: '/dev/null')
62
62
  if @id.nil?
63
63
  @id = wallet.id
64
64
  @key = wallet.key
@@ -122,6 +122,22 @@ doesn't have this transaction: \"#{txn.to_text}\"")
122
122
  end
123
123
  end
124
124
  @txns << txn
125
+ if txn.amount.negative?
126
+ File.open(ledger, 'a') do |f|
127
+ f.puts(
128
+ [
129
+ Time.now.utc.iso8601,
130
+ txn.id,
131
+ txn.date.utc.iso8601,
132
+ wallet.id,
133
+ txn.bnf,
134
+ txn.amount.to_i * -1,
135
+ txn.prefix,
136
+ txn.details
137
+ ].map(&:to_s).join(';') + "\n"
138
+ )
139
+ end
140
+ end
125
141
  @log.debug("Merged on top, balance is #{@txns.map(&:amount).inject(&:+)}: #{txn.to_text}")
126
142
  end
127
143
  end
@@ -79,8 +79,8 @@ module Zold
79
79
  msg = response.status_line.strip
80
80
  return if response.status.to_i == code
81
81
  if response.headers && response.headers['X-Zold-Error']
82
- raise CantAssert, "Error ##{response.status} \"#{response.headers['X-Zold-Error']}\"
83
- at #{response.headers['X-Zold-Path']}"
82
+ raise CantAssert, "Error ##{response.status} \"#{response.headers['X-Zold-Error']}\" \
83
+ at #{response.headers['X-Zold-Path']}"
84
84
  end
85
85
  raise CantAssert, "Unexpected HTTP code #{response.status}, instead of #{code}" if msg.empty?
86
86
  raise CantAssert, "#{msg} (HTTP code #{response.status}, instead of #{code})"
@@ -71,7 +71,7 @@ module Zold
71
71
  @id = id
72
72
  raise 'The time can\'t be NIL' if date.nil?
73
73
  raise 'Time have to be of type Time' unless date.is_a?(Time)
74
- raise "Time can't be in the future: #{date}" if date > Time.now
74
+ raise "Time can't be in the future: #{date.utc.iso8601}" if date > Time.now
75
75
  @date = date
76
76
  raise 'The amount can\'t be NIL' if amount.nil?
77
77
  raise 'The amount has to be of type Amount' unless amount.is_a?(Amount)
@@ -25,7 +25,7 @@
25
25
  # Copyright:: Copyright (c) 2018 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Zold
28
- VERSION = '0.23.11'
28
+ VERSION = '0.24.0'
29
29
  PROTOCOL = 2
30
30
  REPO = 'zold-io/zold'
31
31
  end
@@ -53,13 +53,15 @@ class TestEntrance < Zold::Test
53
53
  FakeHome.new(log: test_log).run do |home|
54
54
  source = home.create_wallet(sid)
55
55
  target = home.create_wallet(tid)
56
- e = Zold::Entrance.new(home.wallets, home.remotes, home.copies(source).root, 'x', log: test_log)
56
+ 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)
57
58
  modified = e.push(source.id, body)
58
59
  assert_equal(3, modified.count)
59
60
  assert_equal(Zold::Amount.new(zld: -19.99), source.balance)
60
61
  assert_equal(Zold::Amount.new(zld: 19.99), target.balance)
61
62
  assert(modified.include?(sid))
62
63
  assert(modified.include?(tid))
64
+ assert_equal(1, IO.read(ledger).split("\n").count)
63
65
  end
64
66
  end
65
67
 
@@ -82,6 +82,8 @@ class FrontTest < Zold::Test
82
82
  '/version',
83
83
  '/protocol',
84
84
  '/farm',
85
+ '/ledger',
86
+ '/ledger.json',
85
87
  '/metronome',
86
88
  '/score',
87
89
  '/trace',
@@ -146,4 +146,33 @@ class TestPatch < Zold::Test
146
146
  assert_equal(Zold::Amount.new(zld: -6.0).to_s, first.balance.to_s)
147
147
  end
148
148
  end
149
+
150
+ def test_protocols_new_txns
151
+ FakeHome.new(log: test_log).run do |home|
152
+ first = home.create_wallet(Zold::Id::ROOT)
153
+ second = home.create_wallet
154
+ IO.write(second.path, IO.read(first.path))
155
+ amount = Zold::Amount.new(zld: 333.0)
156
+ key = Zold::Key.new(file: 'fixtures/id_rsa')
157
+ target = Zold::Id.new
158
+ second.sub(amount, "NOPREFIX@#{target}", key, 'some details')
159
+ second.sub(amount * 2, "NOPREFIX@#{target}", key)
160
+ patch = Zold::Patch.new(home.wallets, log: test_log)
161
+ patch.legacy(first)
162
+ Tempfile.open do |f|
163
+ patch.join(second, ledger: f.path) { false }
164
+ lines = IO.read(f).split("\n")
165
+ assert_equal(2, lines.count)
166
+ parts = lines[0].split(';')
167
+ assert(!Zold::Txn.parse_time(parts[0]).nil?)
168
+ assert_equal(1, parts[1].to_i)
169
+ assert(!Zold::Txn.parse_time(parts[2]).nil?)
170
+ assert_equal(Zold::Id::ROOT.to_s, parts[3])
171
+ assert_equal(target.to_s, parts[4])
172
+ assert_equal(amount, Zold::Amount.new(zents: parts[5].to_i))
173
+ assert_equal('NOPREFIX', parts[6])
174
+ assert_equal('some details', parts[7])
175
+ end
176
+ end
177
+ end
149
178
  end
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.23.11
4
+ version: 0.24.0
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-02-18 00:00:00.000000000 Z
11
+ date: 2019-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -753,7 +753,7 @@ licenses:
753
753
  - MIT
754
754
  metadata: {}
755
755
  post_install_message: |-
756
- Thanks for installing Zold 0.23.11!
756
+ Thanks for installing Zold 0.24.0!
757
757
  Study our White Paper: https://papers.zold.io/wp.pdf
758
758
  Read our blog posts: https://blog.zold.io
759
759
  Try ZLD online wallet at: https://wts.zold.io