zold 0.0.8 → 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE.md +12 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +11 -0
- data/.rubocop.yml +9 -1
- data/.simplecov +2 -2
- data/.travis.yml +1 -1
- data/Gemfile +1 -1
- data/LICENSE.txt +1 -1
- data/Procfile +1 -1
- data/README.md +208 -101
- data/Rakefile +2 -1
- data/bin/zold +135 -54
- data/features/cli.feature +1 -1
- data/features/step_definitions/steps.rb +1 -1
- data/features/support/env.rb +1 -1
- data/fixtures/scripts/push-and-pull.sh +35 -0
- data/lib/zold.rb +2 -2
- data/lib/zold/amount.rb +10 -2
- data/lib/zold/commands/{send.rb → clean.rb} +16 -16
- data/lib/zold/commands/create.rb +7 -5
- data/lib/zold/commands/diff.rb +59 -0
- data/lib/zold/commands/fetch.rb +74 -0
- data/lib/zold/commands/{pull.rb → list.rb} +11 -17
- data/lib/zold/commands/merge.rb +50 -0
- data/lib/zold/commands/node.rb +94 -0
- data/lib/zold/commands/pay.rb +58 -0
- data/lib/zold/commands/{check.rb → propagate.rb} +19 -20
- data/lib/zold/commands/push.rb +12 -12
- data/lib/zold/commands/remote.rb +115 -0
- data/lib/zold/commands/{balance.rb → show.rb} +11 -7
- data/lib/zold/copies.rb +126 -0
- data/lib/zold/http.rb +70 -0
- data/lib/zold/id.rb +8 -3
- data/lib/zold/key.rb +2 -2
- data/lib/zold/log.rb +51 -2
- data/lib/zold/node/farm.rb +81 -0
- data/lib/zold/node/front.rb +94 -46
- data/lib/zold/patch.rb +58 -0
- data/lib/zold/remotes.rb +106 -0
- data/lib/zold/score.rb +101 -0
- data/lib/zold/signature.rb +48 -0
- data/lib/zold/version.rb +3 -3
- data/lib/zold/wallet.rb +87 -55
- data/lib/zold/wallets.rb +13 -6
- data/resources/remotes +1 -0
- data/test/commands/test_clean.rb +41 -0
- data/test/commands/test_create.rb +2 -2
- data/test/commands/test_diff.rb +61 -0
- data/test/commands/test_fetch.rb +65 -0
- data/test/commands/test_list.rb +42 -0
- data/test/commands/test_merge.rb +62 -0
- data/test/commands/test_node.rb +56 -0
- data/test/commands/{test_send.rb → test_pay.rb} +10 -11
- data/test/commands/test_remote.rb +60 -0
- data/test/commands/{test_balance.rb → test_show.rb} +6 -8
- data/test/node/fake_node.rb +73 -0
- data/test/node/test_farm.rb +34 -0
- data/test/node/test_front.rb +26 -57
- data/test/test__helper.rb +1 -1
- data/test/test_amount.rb +10 -2
- data/test/test_copies.rb +73 -0
- data/test/test_http.rb +42 -0
- data/test/test_id.rb +2 -2
- data/test/test_key.rb +10 -10
- data/test/test_patch.rb +59 -0
- data/test/test_remotes.rb +72 -0
- data/test/test_score.rb +79 -0
- data/test/test_signature.rb +45 -0
- data/test/test_wallet.rb +18 -35
- data/test/test_wallets.rb +14 -3
- data/test/test_zold.rb +52 -5
- data/zold.gemspec +5 -3
- metadata +92 -21
- data/CONTRIBUTING.md +0 -19
- data/views/index.haml +0 -6
- data/views/layout.haml +0 -26
- data/views/not_found.haml +0 -3
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2018
|
1
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -40,6 +40,7 @@ Rake::TestTask.new(:test) do |test|
|
|
40
40
|
test.libs << 'lib' << 'test'
|
41
41
|
test.pattern = 'test/**/test_*.rb'
|
42
42
|
test.verbose = false
|
43
|
+
test.warning = false
|
43
44
|
end
|
44
45
|
|
45
46
|
require 'rdoc/task'
|
data/bin/zold
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# encoding: utf-8
|
3
3
|
#
|
4
|
-
# Copyright (c) 2018
|
4
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
5
5
|
#
|
6
6
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
7
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -32,13 +32,8 @@ require_relative '../lib/zold/wallets'
|
|
32
32
|
require_relative '../lib/zold/log'
|
33
33
|
require_relative '../lib/zold/key'
|
34
34
|
require_relative '../lib/zold/amount'
|
35
|
-
require_relative '../lib/zold/
|
36
|
-
require_relative '../lib/zold/
|
37
|
-
require_relative '../lib/zold/commands/balance'
|
38
|
-
require_relative '../lib/zold/commands/check'
|
39
|
-
require_relative '../lib/zold/commands/pull'
|
40
|
-
require_relative '../lib/zold/commands/push'
|
41
|
-
require_relative '../lib/zold/node/front'
|
35
|
+
require_relative '../lib/zold/copies'
|
36
|
+
require_relative '../lib/zold/remotes'
|
42
37
|
|
43
38
|
Encoding.default_external = Encoding::UTF_8
|
44
39
|
Encoding.default_internal = Encoding::UTF_8
|
@@ -46,21 +41,29 @@ Encoding.default_internal = Encoding::UTF_8
|
|
46
41
|
log = Zold::Log.new
|
47
42
|
|
48
43
|
begin
|
49
|
-
opts = Slop.parse(ARGV, strict:
|
44
|
+
opts = Slop.parse(ARGV, strict: false, suppress_errors: true) do |o|
|
50
45
|
o.banner = "Usage: zold [options] command [arguments]
|
51
46
|
Available commands:
|
47
|
+
#{Rainbow('remote').green}
|
48
|
+
Manage remote nodes
|
52
49
|
#{Rainbow('create').green}
|
53
50
|
Creates a new wallet with a random ID
|
54
|
-
#{Rainbow('
|
55
|
-
|
56
|
-
#{Rainbow('
|
57
|
-
|
58
|
-
#{Rainbow('
|
59
|
-
|
60
|
-
#{Rainbow('
|
61
|
-
|
62
|
-
#{Rainbow('
|
63
|
-
|
51
|
+
#{Rainbow('fetch').green} [ID...]
|
52
|
+
Fetch wallet copies from remote nodes
|
53
|
+
#{Rainbow('clean').green} [ID...]
|
54
|
+
Remove expired local copies
|
55
|
+
#{Rainbow('merge').green} [ID...]
|
56
|
+
Merge remote copies with the HEAD
|
57
|
+
#{Rainbow('pull').green} [ID...]
|
58
|
+
Fetch and then merge
|
59
|
+
#{Rainbow('show').green} [ID...]
|
60
|
+
Show all available information about the wallet
|
61
|
+
#{Rainbow('pay').green} source target amount details
|
62
|
+
Pay ZOLD from one wallet to another
|
63
|
+
#{Rainbow('status').green}
|
64
|
+
Show status of local copies
|
65
|
+
#{Rainbow('push').green} [ID...]
|
66
|
+
Push all/some local wallets or the ones required
|
64
67
|
#{Rainbow('node').green} port
|
65
68
|
Run node at the given TCP port
|
66
69
|
Available options:"
|
@@ -78,71 +81,149 @@ Available options:"
|
|
78
81
|
o.on '--no-colors', 'Disable colors in the ouput' do
|
79
82
|
Rainbow.enabled = false
|
80
83
|
end
|
84
|
+
o.on '--verbose', 'Enable extra logging information' do
|
85
|
+
log = Zold::Log::Verbose.new
|
86
|
+
end
|
81
87
|
o.on '-v', '--version', 'Show current version' do
|
82
|
-
|
88
|
+
log.info(Zold::VERSION)
|
83
89
|
exit
|
84
90
|
end
|
85
91
|
end
|
86
92
|
|
87
|
-
if opts.help?
|
93
|
+
raise 'Try --help' if opts.arguments.empty? && !opts.help?
|
94
|
+
|
95
|
+
if opts.help? && opts.arguments.empty?
|
88
96
|
log.info(opts.to_s)
|
89
97
|
exit
|
90
98
|
end
|
91
99
|
|
92
|
-
raise 'Command is required' if opts.arguments.empty?
|
93
|
-
|
94
100
|
command = opts.arguments[0]
|
95
101
|
|
102
|
+
args = ARGV[(ARGV.index(command) + 1)..-1]
|
103
|
+
|
96
104
|
wallets = Zold::Wallets.new(opts['dir'])
|
105
|
+
remotes = Zold::Remotes.new(File.join(opts['dir'], '.zold/remotes'))
|
106
|
+
copies = File.join(opts['dir'], '.zold/copies')
|
97
107
|
|
98
108
|
case command
|
99
109
|
when 'node'
|
100
|
-
|
101
|
-
Zold::
|
110
|
+
require_relative '../lib/zold/commands/node'
|
111
|
+
Zold::Node.new(log: log).run(args)
|
102
112
|
when 'create'
|
113
|
+
require_relative '../lib/zold/commands/create'
|
103
114
|
Zold::Create.new(
|
104
115
|
wallets: wallets,
|
105
116
|
pubkey: Zold::Key.new(file: opts['public-key']),
|
106
117
|
log: log
|
107
|
-
).run
|
108
|
-
when '
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
payer: wallets.find(Zold::Id.new(opts.arguments[1])),
|
113
|
-
receiver: wallets.find(Zold::Id.new(opts.arguments[2])),
|
114
|
-
amount: Zold::Amount.new(zld: opts.arguments[3].to_f),
|
115
|
-
pvtkey: Zold::Key.new(file: opts['private-key']),
|
116
|
-
log: log
|
117
|
-
).run
|
118
|
-
when 'balance'
|
119
|
-
raise "Wallet ID is required" if opts.arguments[1].nil?
|
120
|
-
Zold::Balance.new(
|
121
|
-
wallet: wallets.find(Zold::Id.new(opts.arguments[1])),
|
118
|
+
).run(args)
|
119
|
+
when 'remote'
|
120
|
+
require_relative '../lib/zold/commands/remote'
|
121
|
+
Zold::Remote.new(
|
122
|
+
remotes: remotes,
|
122
123
|
log: log
|
123
|
-
).run
|
124
|
-
when '
|
125
|
-
raise "
|
126
|
-
|
127
|
-
|
128
|
-
|
124
|
+
).run(args)
|
125
|
+
when 'pay'
|
126
|
+
raise "Payer wallet ID is required" if args[0].nil?
|
127
|
+
raise "Recepient wallet ID is required" if args[1].nil?
|
128
|
+
raise "Amount is required (in Zolds)" if args[2].nil?
|
129
|
+
require_relative '../lib/zold/commands/pay'
|
130
|
+
Zold::Pay.new(
|
131
|
+
payer: wallets.find(Zold::Id.new(args[0])),
|
132
|
+
receiver: Zold::Id.new(args[1]),
|
133
|
+
amount: Zold::Amount.new(zld: args[2].to_f),
|
134
|
+
details: opts.arguments[4] ? args[3] : '-',
|
135
|
+
pvtkey: Zold::Key.new(file: opts['private-key']),
|
129
136
|
log: log
|
130
|
-
).run
|
137
|
+
).run(args)
|
138
|
+
when 'show'
|
139
|
+
if args[0].nil?
|
140
|
+
require_relative '../lib/zold/commands/list'
|
141
|
+
Zold::List.new(
|
142
|
+
wallets: wallets,
|
143
|
+
log: log
|
144
|
+
).run(args)
|
145
|
+
else
|
146
|
+
require_relative '../lib/zold/commands/show'
|
147
|
+
args.each do |id|
|
148
|
+
Zold::Show.new(
|
149
|
+
wallet: wallets.find(Zold::Id.new(id)),
|
150
|
+
log: log
|
151
|
+
).run(args)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
when 'fetch'
|
155
|
+
require_relative '../lib/zold/commands/fetch'
|
156
|
+
args.each do |id|
|
157
|
+
Zold::Fetch.new(
|
158
|
+
wallet: wallets.find(Zold::Id.new(id)),
|
159
|
+
remotes: remotes,
|
160
|
+
copies: Zold::Copies.new(File.join(copies, id)),
|
161
|
+
log: log
|
162
|
+
).run(args)
|
163
|
+
end
|
164
|
+
when 'clean'
|
165
|
+
require_relative '../lib/zold/commands/clean'
|
166
|
+
if args.empty?
|
167
|
+
args = Dir.new(copies).select { |f| f =~ /[0-9a-fA-F]{16}/ }
|
168
|
+
end
|
169
|
+
args.each do |id|
|
170
|
+
Zold::Clean.new(
|
171
|
+
copies: Zold::Copies.new(File.join(copies, id)),
|
172
|
+
log: log
|
173
|
+
).run(args)
|
174
|
+
end
|
175
|
+
when 'diff'
|
176
|
+
require_relative '../lib/zold/commands/diff'
|
177
|
+
args.each do |id|
|
178
|
+
Zold::Diff.new(
|
179
|
+
wallet: wallets.find(Zold::Id.new(id)),
|
180
|
+
copies: Zold::Copies.new(File.join(copies, id)),
|
181
|
+
log: log
|
182
|
+
).run(args)
|
183
|
+
end
|
184
|
+
when 'merge'
|
185
|
+
require_relative '../lib/zold/commands/merge'
|
186
|
+
require_relative '../lib/zold/commands/propagate'
|
187
|
+
args.each do |id|
|
188
|
+
Zold::Merge.new(
|
189
|
+
wallet: wallets.find(Zold::Id.new(id)),
|
190
|
+
copies: Zold::Copies.new(File.join(copies, id)),
|
191
|
+
log: log
|
192
|
+
).run(args)
|
193
|
+
Zold::Propagate.new(
|
194
|
+
wallet: wallets.find(Zold::Id.new(id)),
|
195
|
+
wallets: wallets,
|
196
|
+
log: log
|
197
|
+
).run(args)
|
198
|
+
end
|
131
199
|
when 'pull'
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
200
|
+
require_relative '../lib/zold/commands/fetch'
|
201
|
+
require_relative '../lib/zold/commands/merge'
|
202
|
+
args.each do |id|
|
203
|
+
Zold::Fetch.new(
|
204
|
+
wallet: wallets.find(Zold::Id.new(id)),
|
205
|
+
remotes: remotes,
|
206
|
+
copies: Zold::Copies.new(File.join(copies, id)),
|
207
|
+
log: log
|
208
|
+
).run(args)
|
209
|
+
Zold::Merge.new(
|
210
|
+
wallet: wallets.find(Zold::Id.new(id)),
|
211
|
+
copies: Zold::Copies.new(File.join(copies, id)),
|
212
|
+
log: log
|
213
|
+
).run(args)
|
214
|
+
end
|
136
215
|
when 'push'
|
216
|
+
require_relative '../lib/zold/commands/push'
|
137
217
|
Zold::Push.new(
|
138
|
-
wallet: wallets.find(Zold::Id.new(
|
218
|
+
wallet: wallets.find(Zold::Id.new(args[0])),
|
219
|
+
remotes: remotes,
|
139
220
|
log: log
|
140
|
-
).run
|
221
|
+
).run(args)
|
141
222
|
else
|
142
223
|
raise "Command '#{command}' is not supported"
|
143
224
|
end
|
144
225
|
rescue StandardError => ex
|
145
|
-
log.error(ex.message)
|
226
|
+
log.error("#{ex.message} (#{ex.class.name})")
|
146
227
|
puts ex.backtrace if opts['trace']
|
147
228
|
exit -1
|
148
229
|
end
|
data/features/cli.feature
CHANGED
@@ -12,6 +12,6 @@ Feature: Command Line Processing
|
|
12
12
|
Then Exit code is zero
|
13
13
|
|
14
14
|
Scenario: Wallet can be created
|
15
|
-
When I run bin/zold with "
|
15
|
+
When I run bin/zold with " --private-key id_rsa --public-key id_rsa.pub --trace create"
|
16
16
|
Then Exit code is zero
|
17
17
|
|
data/features/support/env.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
set -x
|
3
|
+
set -e
|
4
|
+
shopt -s expand_aliases
|
5
|
+
|
6
|
+
alias zold="$1"
|
7
|
+
|
8
|
+
port=`python -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1]); s.close()'`
|
9
|
+
|
10
|
+
mkdir server
|
11
|
+
cd server
|
12
|
+
zold node --host=localhost --port=${port} --bind-port=${port} --threads=0 &
|
13
|
+
pid=$!
|
14
|
+
trap "kill -9 $pid" EXIT
|
15
|
+
cd ..
|
16
|
+
|
17
|
+
while ! nc -z localhost ${port}; do
|
18
|
+
sleep 0.1
|
19
|
+
done
|
20
|
+
|
21
|
+
zold remote clean
|
22
|
+
zold remote add localhost ${port}
|
23
|
+
zold remote show
|
24
|
+
|
25
|
+
zold --public-key id_rsa.pub create 0000000000000000
|
26
|
+
zold --private-key id_rsa --trace pay 0000000000000000 af5788fcadd710c5 14.99 'To save the world!'
|
27
|
+
zold show
|
28
|
+
zold show 0000000000000000
|
29
|
+
|
30
|
+
zold push 0000000000000000
|
31
|
+
zold fetch 0000000000000000
|
32
|
+
zold diff 0000000000000000
|
33
|
+
zold --trace merge 0000000000000000
|
34
|
+
|
35
|
+
echo 'DONE'
|
data/lib/zold.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2018
|
1
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -23,7 +23,7 @@ require_relative 'zold/version'
|
|
23
23
|
|
24
24
|
# Zold main module.
|
25
25
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
26
|
-
# Copyright:: Copyright (c) 2018
|
26
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
27
27
|
# License:: MIT
|
28
28
|
module Zold
|
29
29
|
# to be implemented...
|
data/lib/zold/amount.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2018
|
1
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -22,7 +22,7 @@ require 'rainbow'
|
|
22
22
|
|
23
23
|
# The amount.
|
24
24
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
25
|
-
# Copyright:: Copyright (c) 2018
|
25
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
26
26
|
# License:: MIT
|
27
27
|
module Zold
|
28
28
|
# Amount
|
@@ -57,6 +57,14 @@ module Zold
|
|
57
57
|
@coins == other.to_i
|
58
58
|
end
|
59
59
|
|
60
|
+
def >(other)
|
61
|
+
@coins > other.to_i
|
62
|
+
end
|
63
|
+
|
64
|
+
def <(other)
|
65
|
+
@coins < other.to_i
|
66
|
+
end
|
67
|
+
|
60
68
|
def +(other)
|
61
69
|
Amount.new(coins: @coins + other.to_i)
|
62
70
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2018
|
1
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -18,29 +18,29 @@
|
|
18
18
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
19
|
# SOFTWARE.
|
20
20
|
|
21
|
+
require 'uri'
|
22
|
+
require 'json'
|
23
|
+
require 'time'
|
21
24
|
require_relative '../log.rb'
|
25
|
+
require_relative '../http.rb'
|
26
|
+
require_relative '../score.rb'
|
22
27
|
|
23
|
-
#
|
28
|
+
# CLEAN command.
|
24
29
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
25
|
-
# Copyright:: Copyright (c) 2018
|
30
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
26
31
|
# License:: MIT
|
27
32
|
module Zold
|
28
|
-
#
|
29
|
-
class
|
30
|
-
def initialize(
|
31
|
-
@
|
32
|
-
@receiver = receiver
|
33
|
-
@amount = amount
|
34
|
-
@pvtkey = pvtkey
|
33
|
+
# CLEAN pulling command
|
34
|
+
class Clean
|
35
|
+
def initialize(copies:, log: Log::Quiet.new)
|
36
|
+
@copies = copies
|
35
37
|
@log = log
|
36
38
|
end
|
37
39
|
|
38
|
-
def run
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@log.info("#{@amount} sent from #{@payer} to #{@receiver}")
|
43
|
-
txn[:id]
|
40
|
+
def run(_ = [])
|
41
|
+
@copies.clean
|
42
|
+
@log.debug("Expired local copies removed for #{@copies}, \
|
43
|
+
#{@copies.all.count} left")
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
data/lib/zold/commands/create.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2018
|
1
|
+
# Copyright (c) 2018 Yegor Bugayenko
|
2
2
|
#
|
3
3
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
4
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -24,7 +24,7 @@ require_relative '../id.rb'
|
|
24
24
|
|
25
25
|
# CREATE command.
|
26
26
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
27
|
-
# Copyright:: Copyright (c) 2018
|
27
|
+
# Copyright:: Copyright (c) 2018 Yegor Bugayenko
|
28
28
|
# License:: MIT
|
29
29
|
module Zold
|
30
30
|
# Create command
|
@@ -35,11 +35,13 @@ module Zold
|
|
35
35
|
@log = log
|
36
36
|
end
|
37
37
|
|
38
|
-
def run
|
39
|
-
id = Id.new
|
38
|
+
def run(args = [])
|
39
|
+
id = args.empty? ? Id.new : Id.new(args[0])
|
40
40
|
wallet = @wallets.find(id)
|
41
41
|
wallet.init(id, @pubkey)
|
42
|
-
@log.info(
|
42
|
+
@log.info(wallet.id)
|
43
|
+
@log.debug("Wallet #{Rainbow(wallet).green} \
|
44
|
+
created at #{@wallets.path}")
|
43
45
|
wallet
|
44
46
|
end
|
45
47
|
end
|