zold 0.14.28 → 0.14.29
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/appveyor.yml +9 -8
- data/bin/zold +8 -4
- data/fixtures/scripts/distribute-wallet.sh +4 -3
- data/lib/zold/commands/create.rb +6 -5
- data/lib/zold/commands/diff.rb +5 -7
- data/lib/zold/commands/fetch.rb +3 -2
- data/lib/zold/commands/invoice.rb +4 -3
- data/lib/zold/commands/merge.rb +14 -13
- data/lib/zold/commands/node.rb +40 -17
- data/lib/zold/commands/pay.rb +16 -9
- data/lib/zold/commands/propagate.rb +24 -21
- data/lib/zold/commands/push.rb +23 -22
- data/lib/zold/commands/remote.rb +16 -23
- data/lib/zold/commands/routines/reconnect.rb +5 -1
- data/lib/zold/commands/show.rb +3 -1
- data/lib/zold/commands/taxes.rb +9 -3
- data/lib/zold/copies.rb +2 -2
- data/lib/zold/hungry_wallets.rb +21 -1
- data/lib/zold/node/async_entrance.rb +5 -6
- data/lib/zold/node/entrance.rb +3 -2
- data/lib/zold/node/front.rb +119 -88
- data/lib/zold/node/nodup_entrance.rb +3 -2
- data/lib/zold/node/sync_entrance.rb +81 -0
- data/lib/zold/node/trace.rb +75 -0
- data/lib/zold/patch.rb +2 -3
- data/lib/zold/remotes.rb +1 -1
- data/lib/zold/sync_wallets.rb +78 -0
- data/lib/zold/version.rb +1 -1
- data/lib/zold/wallet.rb +1 -0
- data/lib/zold/wallets.rb +5 -5
- data/test/commands/test_create.rb +9 -6
- data/test/commands/test_diff.rb +1 -1
- data/test/commands/test_invoice.rb +7 -6
- data/test/commands/test_list.rb +4 -3
- data/test/commands/test_merge.rb +2 -2
- data/test/commands/test_pull.rb +3 -1
- data/test/commands/test_remote.rb +4 -0
- data/test/commands/test_show.rb +5 -4
- data/test/fake_home.rb +2 -1
- data/test/node/test_async_entrance.rb +1 -1
- data/test/node/test_farm.rb +2 -2
- data/test/node/test_front.rb +63 -17
- data/test/node/test_sync_entrance.rb +41 -0
- data/test/node/test_trace.rb +36 -0
- data/test/test__helper.rb +18 -0
- data/test/test_copies.rb +1 -1
- data/test/test_metronome.rb +2 -3
- data/test/test_patch.rb +1 -1
- data/test/test_remotes.rb +3 -3
- data/test/test_sync_wallets.rb +69 -0
- data/test/test_upgrades.rb +0 -0
- data/test/test_wallet.rb +1 -1
- data/test/test_wallets.rb +14 -10
- data/test/test_zold.rb +2 -2
- data/test/upgrades/test_protocol_up.rb +3 -2
- data/zold.gemspec +1 -0
- metadata +25 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz: '
|
3
|
+
metadata.gz: 9b4acd567c5e890ca57ca7503ef5620cb7011c92
|
4
|
+
data.tar.gz: '08020f9c49dcd23340fe4f614190d3d24be30201'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b31303f911f6a4f90b9e5a646e719f0df55163e3f3a4923a7b4953fc9f89fe436d6ed0f846a3115e1852e3308ffe4751a86da717ea0c7aaec13ea3ddf99d16e2
|
7
|
+
data.tar.gz: a33a1e676dfa1557baafb3f886c38de513ba7c98481d806313a96b5780c723bea580321768e3d1efc502138142ac785394effdaedc56de6e9b7948eed9007254
|
data/.rubocop.yml
CHANGED
data/appveyor.yml
CHANGED
@@ -9,12 +9,12 @@ branches:
|
|
9
9
|
os: Windows Server 2012
|
10
10
|
environment:
|
11
11
|
matrix:
|
12
|
-
-
|
13
|
-
-
|
14
|
-
-
|
12
|
+
- ruby_version: "23-x64"
|
13
|
+
- ruby_version: "24-x64"
|
14
|
+
- ruby_version: "25-x64"
|
15
15
|
install:
|
16
16
|
- ps: |
|
17
|
-
$Env:PATH = "C:\Ruby${Env:ruby_version}
|
17
|
+
$Env:PATH = "C:\Ruby${Env:ruby_version}\bin;${Env:PATH}"
|
18
18
|
if ($Env:ruby_version -match "^23" ) {
|
19
19
|
# RubyInstaller; download OpenSSL headers from OpenKnapsack Project
|
20
20
|
$Env:openssl_dir = "C:\Ruby${Env:ruby_version}"
|
@@ -25,13 +25,14 @@ install:
|
|
25
25
|
# RubyInstaller2; openssl package seems to be installed already
|
26
26
|
$Env:openssl_dir = "C:\msys64\mingw64"
|
27
27
|
}
|
28
|
-
-
|
29
|
-
-
|
30
|
-
-
|
28
|
+
- bundle config --local path vendor/bundle
|
29
|
+
- bundle config build.openssl --with-openssl-dir=%openssl_dir%
|
30
|
+
- ruby -v
|
31
|
+
- bundle -v
|
31
32
|
build_script:
|
32
33
|
- bundle update
|
33
34
|
- bundle install
|
34
35
|
test_script:
|
35
|
-
- rake
|
36
|
+
- bundle exec rake --quiet
|
36
37
|
cache:
|
37
38
|
- vendor/bundle
|
data/bin/zold
CHANGED
@@ -35,6 +35,7 @@ require_relative '../lib/zold'
|
|
35
35
|
require_relative '../lib/zold/version'
|
36
36
|
require_relative '../lib/zold/wallet'
|
37
37
|
require_relative '../lib/zold/wallets'
|
38
|
+
require_relative '../lib/zold/sync_wallets'
|
38
39
|
require_relative '../lib/zold/log'
|
39
40
|
require_relative '../lib/zold/key'
|
40
41
|
require_relative '../lib/zold/amount'
|
@@ -43,6 +44,7 @@ require_relative '../lib/zold/remotes'
|
|
43
44
|
require_relative '../lib/zold/upgrades'
|
44
45
|
require_relative '../lib/zold/version_file'
|
45
46
|
|
47
|
+
Thread.current.name = 'main'
|
46
48
|
|
47
49
|
Encoding.default_external = Encoding::UTF_8
|
48
50
|
Encoding.default_internal = Encoding::UTF_8
|
@@ -138,7 +140,9 @@ Available options:"
|
|
138
140
|
FileUtils.mkdir_p(opts[:home])
|
139
141
|
Dir.chdir(opts[:home])
|
140
142
|
|
141
|
-
|
143
|
+
zoldata = File.expand_path(File.join(Dir.pwd, '.zoldata'))
|
144
|
+
|
145
|
+
Zold::Upgrades.new(Zold::VersionFile.new(File.join(zoldata, 'version')), 'upgrades').run
|
142
146
|
|
143
147
|
# @todo #384:30min This is a workaround, move this code into Upgrades, somehow.
|
144
148
|
# We should find a way to run these arbitrary scripts and pass arguments
|
@@ -150,9 +154,9 @@ Available options:"
|
|
150
154
|
require_relative '../upgrades/rename_foreign_wallets'
|
151
155
|
Zold::RenameForeignWallets.new(Dir.pwd, opts['network'], log).exec
|
152
156
|
|
153
|
-
wallets = Zold::Wallets.new('.')
|
154
|
-
remotes = Zold::Remotes.new(file: '
|
155
|
-
copies = '
|
157
|
+
wallets = Zold::SyncWallets.new(Zold::Wallets.new('.'), File.join(zoldata, 'locks'), log: log)
|
158
|
+
remotes = Zold::Remotes.new(file: File.join(zoldata, 'remotes'), network: opts['network'])
|
159
|
+
copies = File.join(zoldata, 'copies')
|
156
160
|
|
157
161
|
case command
|
158
162
|
when 'node'
|
@@ -73,15 +73,16 @@ if [ ! $(echo ${json} | jq -r '.wallets') == "1" ]; then
|
|
73
73
|
fi
|
74
74
|
|
75
75
|
# Now, we remove the wallet from the second node and expect the first
|
76
|
-
# one to "spread" it again, almost immediately.
|
77
|
-
|
76
|
+
# one to "spread" it again, almost immediately. The second node should
|
77
|
+
# have the wallet very soon.
|
78
|
+
rm -f ${second}/0000000000000000.z
|
78
79
|
i=0
|
79
80
|
until zold fetch 0000000000000000 --ignore-score-weakness; do
|
80
81
|
echo 'Failed to fetch, let us try again'
|
81
82
|
((i++)) || sleep 0
|
82
83
|
if ((i==5)); then
|
84
|
+
echo "The wallet 0000000000000000 has not been spread, after ${i} attempts, here is the log:"
|
83
85
|
cat ${first}/log.txt
|
84
|
-
echo "The wallet 0000000000000000 has not been spread, after ${i} attempts"
|
85
86
|
exit 8
|
86
87
|
fi
|
87
88
|
sleep 5
|
data/lib/zold/commands/create.rb
CHANGED
@@ -60,12 +60,13 @@ Available options:"
|
|
60
60
|
private
|
61
61
|
|
62
62
|
def create(id, opts)
|
63
|
-
wallet = @wallets.find(id)
|
64
63
|
key = Zold::Key.new(file: opts['public-key'])
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
64
|
+
@wallets.find(id) do |wallet|
|
65
|
+
wallet.init(id, key, network: opts['network'])
|
66
|
+
@log.debug("Wallet #{Rainbow(wallet).green} created at #{@wallets.path}")
|
67
|
+
end
|
68
|
+
@log.info(id)
|
69
|
+
id
|
69
70
|
end
|
70
71
|
end
|
71
72
|
end
|
data/lib/zold/commands/diff.rb
CHANGED
@@ -53,25 +53,23 @@ Available options:"
|
|
53
53
|
raise 'At least one wallet ID is required' if mine.empty?
|
54
54
|
stdout = ''
|
55
55
|
mine.map { |i| Id.new(i) }.each do |id|
|
56
|
-
stdout += diff(
|
57
|
-
@wallets.find(id),
|
58
|
-
Copies.new(File.join(@copies, id)),
|
59
|
-
opts
|
60
|
-
)
|
56
|
+
stdout += diff(id, Copies.new(File.join(@copies, id)), opts)
|
61
57
|
end
|
62
58
|
stdout
|
63
59
|
end
|
64
60
|
|
65
61
|
private
|
66
62
|
|
67
|
-
def diff(
|
63
|
+
def diff(id, cps, _)
|
68
64
|
raise "There are no remote copies, try 'zold fetch' first" if cps.all.empty?
|
69
65
|
cps = cps.all.sort_by { |c| c[:score] }.reverse
|
70
66
|
patch = Patch.new(@wallets, log: @log)
|
71
67
|
cps.each do |c|
|
72
68
|
patch.join(Wallet.new(c[:path]))
|
73
69
|
end
|
74
|
-
before =
|
70
|
+
before = @wallets.find(id) do |wallet|
|
71
|
+
AtomicFile.new(wallet.path).read
|
72
|
+
end
|
75
73
|
after = ''
|
76
74
|
Tempfile.open(['', Wallet::EXTENSION]) do |f|
|
77
75
|
patch.save(f.path, overwrite: true)
|
data/lib/zold/commands/fetch.rb
CHANGED
@@ -77,6 +77,7 @@ Available options:"
|
|
77
77
|
private
|
78
78
|
|
79
79
|
def fetch(id, cps, opts)
|
80
|
+
start = Time.now
|
80
81
|
total = Concurrent::AtomicFixnum.new
|
81
82
|
nodes = Concurrent::AtomicFixnum.new
|
82
83
|
done = Concurrent::AtomicFixnum.new
|
@@ -87,7 +88,7 @@ Available options:"
|
|
87
88
|
end
|
88
89
|
raise "There are no remote nodes, run 'zold remote reset'" if nodes.value.zero?
|
89
90
|
raise "No nodes out of #{nodes.value} have the wallet #{id}" if done.value.zero? && !opts['quiet-if-absent']
|
90
|
-
@log.info("#{done.value} copies of #{id} fetched with the total score of \
|
91
|
+
@log.info("#{done.value} copies of #{id} fetched in #{(Time.now - start).round}s with the total score of \
|
91
92
|
#{total.value} from #{nodes.value} nodes")
|
92
93
|
@log.debug("#{cps.all.count} local copies:")
|
93
94
|
cps.all.each do |c|
|
@@ -127,7 +128,7 @@ Available options:"
|
|
127
128
|
end
|
128
129
|
copy = cps.add(File.read(f), score.host, score.port, score.value)
|
129
130
|
@log.info("#{r} returned #{body.length}b/#{wallet.balance}/#{wallet.txns.count}t/\
|
130
|
-
#{digest(json)}/#{Age.new(json['mtime'])} \
|
131
|
+
#{digest(json)}/#{Age.new(json['mtime'])}/#{json['copies']}c \
|
131
132
|
as copy #{copy} of #{id} in #{(Time.now - start).round(2)}s: #{Rainbow(score.value).green} (#{json['version']})")
|
132
133
|
end
|
133
134
|
score.value
|
@@ -51,9 +51,10 @@ Available options:"
|
|
51
51
|
mine = Args.new(opts, @log).take || return
|
52
52
|
raise 'Receiver wallet ID is required' if mine[0].nil?
|
53
53
|
id = Zold::Id.new(mine[0])
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
@wallets.find(id) do |wallet|
|
55
|
+
raise "Wallet #{id} doesn\'t exist in #{@wallets}, do 'zold pull' first" unless wallet.exists?
|
56
|
+
invoice(wallet, opts)
|
57
|
+
end
|
57
58
|
end
|
58
59
|
|
59
60
|
private
|
data/lib/zold/commands/merge.rb
CHANGED
@@ -75,21 +75,22 @@ Available options:"
|
|
75
75
|
merge_one(opts, patch, wallet, "#{c[:name]}/#{idx}/#{c[:score]}")
|
76
76
|
score += c[:score]
|
77
77
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
78
|
+
@wallets.find(id) do |wallet|
|
79
|
+
if wallet.exists?
|
80
|
+
merge_one(opts, patch, wallet, 'localhost')
|
81
|
+
@log.debug("Local copy of #{id} merged: #{patch}")
|
82
|
+
else
|
83
|
+
@log.debug("Local copy of #{id} is absent, nothing to merge")
|
84
|
+
end
|
85
|
+
modified = patch.save(wallet.path, overwrite: true)
|
86
|
+
if modified
|
87
|
+
@log.info("#{cps.count} copies with the total score of #{score} successfully merged \
|
88
88
|
into #{wallet.id}/#{wallet.balance}/#{wallet.txns.count}t")
|
89
|
-
|
90
|
-
|
89
|
+
else
|
90
|
+
@log.info("Nothing changed in #{wallet.id} after merge of #{cps.count} copies")
|
91
|
+
end
|
92
|
+
modified
|
91
93
|
end
|
92
|
-
modified
|
93
94
|
end
|
94
95
|
|
95
96
|
def merge_one(opts, patch, wallet, name)
|
data/lib/zold/commands/node.rb
CHANGED
@@ -28,19 +28,21 @@ require_relative '../backtrace'
|
|
28
28
|
require_relative '../metronome'
|
29
29
|
require_relative '../wallet'
|
30
30
|
require_relative '../wallets'
|
31
|
-
require_relative '../hungry_wallets'
|
32
31
|
require_relative '../remotes'
|
33
32
|
require_relative '../verbose_thread'
|
34
33
|
require_relative '../node/entrance'
|
35
34
|
require_relative '../node/safe_entrance'
|
36
35
|
require_relative '../node/spread_entrance'
|
37
36
|
require_relative '../node/async_entrance'
|
37
|
+
require_relative '../node/sync_entrance'
|
38
38
|
require_relative '../node/nodup_entrance'
|
39
39
|
require_relative '../node/front'
|
40
|
+
require_relative '../node/trace'
|
40
41
|
require_relative '../node/farm'
|
41
42
|
require_relative 'pull'
|
42
43
|
require_relative 'push'
|
43
44
|
require_relative 'pay'
|
45
|
+
require_relative 'remote'
|
44
46
|
|
45
47
|
# NODE command.
|
46
48
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
@@ -50,10 +52,10 @@ module Zold
|
|
50
52
|
# NODE command
|
51
53
|
class Node
|
52
54
|
def initialize(wallets:, remotes:, copies:, log: Log::Quiet.new)
|
53
|
-
@wallets = HungryWallets.new(wallets)
|
54
55
|
@remotes = remotes
|
55
56
|
@copies = copies
|
56
57
|
@log = log
|
58
|
+
@wallets = wallets
|
57
59
|
end
|
58
60
|
|
59
61
|
def run(args = [])
|
@@ -97,6 +99,9 @@ module Zold
|
|
97
99
|
o.string '--halt-code',
|
98
100
|
'The value of HTTP query parameter "halt," which will cause the front-end immediate termination',
|
99
101
|
default: ''
|
102
|
+
o.integer '--trace-length',
|
103
|
+
'Maximum length of the trace to keep in memory (default: 4096)',
|
104
|
+
default: 4096
|
100
105
|
o.string '--save-pid',
|
101
106
|
'The file to save process ID into right after start (only in NOHUP mode)'
|
102
107
|
o.bool '--never-reboot',
|
@@ -140,7 +145,9 @@ module Zold
|
|
140
145
|
@log.info(pid)
|
141
146
|
return
|
142
147
|
end
|
143
|
-
|
148
|
+
trace = Trace.new(@log, opts['trace-length'])
|
149
|
+
Front.set(:log, trace)
|
150
|
+
Front.set(:trace, trace)
|
144
151
|
Front.set(:version, opts['expose-version'])
|
145
152
|
Front.set(:protocol, Zold::PROTOCOL)
|
146
153
|
Front.set(:logging, @log.debug?)
|
@@ -152,9 +159,13 @@ module Zold
|
|
152
159
|
@log.info("Zold protocol version: #{Zold::PROTOCOL}")
|
153
160
|
@log.info("Network ID: #{opts['network']}")
|
154
161
|
host = opts[:host] || ip
|
155
|
-
|
162
|
+
port = opts[:port]
|
163
|
+
address = "#{host}:#{port}".downcase
|
156
164
|
@log.info("Node location: #{address}")
|
157
165
|
@log.info("Local address: http://localhost:#{opts['bind-port']}/")
|
166
|
+
@log.info("Remote nodes (#{@remotes.all.count}): \
|
167
|
+
#{@remotes.all.map { |r| "#{r[:host]}:#{r[:port]}" }.join(', ')}")
|
168
|
+
@log.info("Wallets at: #{@wallets.path}")
|
158
169
|
Front.set(
|
159
170
|
:server_settings,
|
160
171
|
Logger: WebrickLog.new(@log),
|
@@ -163,6 +174,9 @@ module Zold
|
|
163
174
|
if opts['standalone']
|
164
175
|
@remotes = Zold::Remotes::Empty.new(file: '/tmp/standalone')
|
165
176
|
@log.debug('Running in standalone mode! (will never talk to other remotes)')
|
177
|
+
else
|
178
|
+
Zold::Remote.new(remotes: @remotes).run(['remote', 'remove', host, port.to_s, '--force'])
|
179
|
+
@log.info("Removed current node (#{address}) from list of remotes")
|
166
180
|
end
|
167
181
|
Front.set(:ignore_score_weakness, opts['ignore-score-weakness'])
|
168
182
|
Front.set(:network, opts['network'])
|
@@ -175,21 +189,22 @@ module Zold
|
|
175
189
|
Front.set(:port, opts['bind-port'])
|
176
190
|
Front.set(:reboot, !opts['never-reboot'])
|
177
191
|
node_alias = opts[:alias] || address
|
178
|
-
unless node_alias.eql?(address)
|
179
|
-
|
180
|
-
raise '--alias should be a 4 to 16 char long alphanumeric string' unless re.match(node_alias)
|
192
|
+
unless node_alias.eql?(address) || node_alias =~ /^[a-z0-9]{4,16}$/
|
193
|
+
raise "Alias should be a 4 to 16 char long alphanumeric string: #{node_alias}"
|
181
194
|
end
|
182
195
|
Front.set(:node_alias, node_alias)
|
183
196
|
invoice = opts[:invoice]
|
184
197
|
unless invoice.include?('@')
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
198
|
+
@wallets.find(Id.new(invoice)) do |wallet|
|
199
|
+
if wallet.exists?
|
200
|
+
@log.info("Wallet #{invoice} already exists locally, won't pull")
|
201
|
+
else
|
202
|
+
@log.info("The wallet #{invoice} is not available locally, will pull now...")
|
203
|
+
require_relative 'pull'
|
204
|
+
Pull.new(wallets: @wallets, remotes: @remotes, copies: @copies, log: @log).run(
|
205
|
+
['pull', invoice, "--network=#{opts['network']}"]
|
206
|
+
)
|
207
|
+
end
|
193
208
|
end
|
194
209
|
require_relative 'invoice'
|
195
210
|
invoice = Invoice.new(wallets: @wallets, log: @log).run(['invoice', invoice])
|
@@ -198,7 +213,15 @@ module Zold
|
|
198
213
|
NoDupEntrance.new(
|
199
214
|
AsyncEntrance.new(
|
200
215
|
SpreadEntrance.new(
|
201
|
-
|
216
|
+
SyncEntrance.new(
|
217
|
+
Entrance.new(
|
218
|
+
@wallets,
|
219
|
+
@remotes, @copies, address,
|
220
|
+
log: @log, network: opts['network']
|
221
|
+
),
|
222
|
+
File.join(Dir.pwd, '.zoldata/entrance'),
|
223
|
+
log: @log
|
224
|
+
),
|
202
225
|
@wallets, @remotes, address,
|
203
226
|
log: @log,
|
204
227
|
ignore_score_weakeness: opts['ignore-score-weakness']
|
@@ -293,7 +316,7 @@ module Zold
|
|
293
316
|
metronome.add(Routines::Spread.new(opts, @wallets, @remotes, log: @log))
|
294
317
|
unless opts['standalone']
|
295
318
|
require_relative 'routines/reconnect'
|
296
|
-
metronome.add(Routines::Reconnect.new(opts, @remotes, farm, network: opts['network'], log:
|
319
|
+
metronome.add(Routines::Reconnect.new(opts, @remotes, farm, network: opts['network'], log: @log))
|
297
320
|
end
|
298
321
|
@log.info('Metronome created')
|
299
322
|
metronome
|
data/lib/zold/commands/pay.rb
CHANGED
@@ -67,8 +67,6 @@ Available options:"
|
|
67
67
|
mine = Args.new(opts, @log).take || return
|
68
68
|
raise 'Payer wallet ID is required as the first argument' if mine[0].nil?
|
69
69
|
id = Id.new(mine[0])
|
70
|
-
from = @wallets.find(id)
|
71
|
-
raise "Wallet #{id} doesn't exist, do 'zold pull' first" unless from.exists?
|
72
70
|
raise 'Recepient\'s invoice or wallet ID is required as the second argument' if mine[1].nil?
|
73
71
|
invoice = mine[1]
|
74
72
|
unless invoice.include?('@')
|
@@ -78,20 +76,29 @@ Available options:"
|
|
78
76
|
raise 'Amount is required (in ZLD) as the third argument' if mine[2].nil?
|
79
77
|
amount = Amount.new(zld: mine[2].to_f)
|
80
78
|
details = mine[3] || '-'
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
['taxes', 'pay', "--private-key=#{opts['private-key']}", id.to_s]
|
85
|
-
)
|
79
|
+
taxes(id)
|
80
|
+
@wallets.find(id) do |from|
|
81
|
+
pay(from, invoice, amount, details, opts)
|
86
82
|
end
|
87
|
-
pay(from, invoice, amount, details, opts)
|
88
83
|
return if opts['skip-propagate']
|
89
84
|
require_relative 'propagate'
|
90
|
-
Propagate.new(wallets: @wallets, log: @log).run(['propagate',
|
85
|
+
Propagate.new(wallets: @wallets, log: @log).run(['propagate', id.to_s])
|
91
86
|
end
|
92
87
|
|
93
88
|
private
|
94
89
|
|
90
|
+
def taxes(id)
|
91
|
+
debt = @wallets.find(id) do |wallet|
|
92
|
+
raise "Wallet #{id} doesn't exist, do 'zold pull' first" unless wallet.exists?
|
93
|
+
Tax.new(wallet).in_debt? && !opts['dont-pay-taxes']
|
94
|
+
end
|
95
|
+
return unless debt
|
96
|
+
require_relative 'taxes'
|
97
|
+
Taxes.new(wallets: @wallets, remotes: @remotes, log: @log).run(
|
98
|
+
['taxes', 'pay', "--private-key=#{opts['private-key']}", id.to_s]
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
95
102
|
def pay(from, invoice, amount, details, opts)
|
96
103
|
unless opts.force?
|
97
104
|
raise 'The amount can\'t be zero' if amount.zero?
|
@@ -51,7 +51,7 @@ Available options:"
|
|
51
51
|
mine = @wallets.all if mine.empty?
|
52
52
|
modified = []
|
53
53
|
mine.map { |i| Id.new(i) }.each do |id|
|
54
|
-
modified += propagate(
|
54
|
+
modified += propagate(id, opts)
|
55
55
|
end
|
56
56
|
modified
|
57
57
|
end
|
@@ -59,30 +59,33 @@ Available options:"
|
|
59
59
|
private
|
60
60
|
|
61
61
|
# Returns list of Wallet IDs which were affected
|
62
|
-
def propagate(
|
63
|
-
me = wallet.id
|
62
|
+
def propagate(id, _)
|
64
63
|
modified = []
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
@
|
69
|
-
|
64
|
+
@wallets.find(id) do |wallet|
|
65
|
+
wallet.txns.select { |t| t.amount.negative? }.each do |t|
|
66
|
+
next if t.bnf == id
|
67
|
+
@wallets.find(t.bnf) do |target|
|
68
|
+
unless target.exists?
|
69
|
+
@log.debug("#{t.amount * -1} to #{t.bnf}: wallet is absent")
|
70
|
+
next
|
71
|
+
end
|
72
|
+
unless target.network == wallet.network
|
73
|
+
@log.error("#{t.amount * -1} to #{t.bnf}: network mismatch, '#{target.network}'!='#{wallet.network}'")
|
74
|
+
next
|
75
|
+
end
|
76
|
+
next if target.has?(t.id, id)
|
77
|
+
unless target.prefix?(t.prefix)
|
78
|
+
@log.error("#{t.amount * -1} to #{t.bnf}: wrong prefix")
|
79
|
+
next
|
80
|
+
end
|
81
|
+
target.add(t.inverse(id))
|
82
|
+
@log.info("#{t.amount * -1} arrived to #{t.bnf}: #{t.details}")
|
83
|
+
modified << t.bnf
|
84
|
+
end
|
70
85
|
end
|
71
|
-
unless target.network == wallet.network
|
72
|
-
@log.error("#{t.amount * -1} to #{t.bnf}: network mismatch, '#{target.network}'!='#{wallet.network}'")
|
73
|
-
next
|
74
|
-
end
|
75
|
-
next if target.has?(t.id, me)
|
76
|
-
unless target.prefix?(t.prefix)
|
77
|
-
@log.error("#{t.amount * -1} to #{t.bnf}: wrong prefix")
|
78
|
-
next
|
79
|
-
end
|
80
|
-
target.add(t.inverse(me))
|
81
|
-
@log.info("#{t.amount * -1} arrived to #{t.bnf}: #{t.details}")
|
82
|
-
modified << t.bnf
|
83
86
|
end
|
84
87
|
modified.uniq!
|
85
|
-
@log.debug("Wallet #{
|
88
|
+
@log.debug("Wallet #{id} propagated successfully, #{modified.count} wallets affected")
|
86
89
|
modified
|
87
90
|
end
|
88
91
|
end
|