peatio-jruby 2.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.drone.yml +29 -0
  3. data/.gitignore +16 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +148 -0
  6. data/.simplecov +17 -0
  7. data/.tool-versions +1 -0
  8. data/.travis.yml +18 -0
  9. data/Gemfile +8 -0
  10. data/Gemfile.lock +198 -0
  11. data/README.md +47 -0
  12. data/Rakefile +6 -0
  13. data/bin/console +14 -0
  14. data/bin/peatio +12 -0
  15. data/bin/setup +8 -0
  16. data/lib/peatio.rb +52 -0
  17. data/lib/peatio/adapter_registry.rb +25 -0
  18. data/lib/peatio/auth/error.rb +18 -0
  19. data/lib/peatio/auth/jwt_authenticator.rb +127 -0
  20. data/lib/peatio/block.rb +29 -0
  21. data/lib/peatio/blockchain/abstract.rb +161 -0
  22. data/lib/peatio/blockchain/error.rb +37 -0
  23. data/lib/peatio/blockchain/registry.rb +16 -0
  24. data/lib/peatio/command/base.rb +11 -0
  25. data/lib/peatio/command/db.rb +20 -0
  26. data/lib/peatio/command/inject.rb +13 -0
  27. data/lib/peatio/command/root.rb +14 -0
  28. data/lib/peatio/command/security.rb +29 -0
  29. data/lib/peatio/command/service.rb +40 -0
  30. data/lib/peatio/error.rb +18 -0
  31. data/lib/peatio/executor.rb +64 -0
  32. data/lib/peatio/injectors/peatio_events.rb +240 -0
  33. data/lib/peatio/logger.rb +39 -0
  34. data/lib/peatio/metrics/server.rb +15 -0
  35. data/lib/peatio/mq/client.rb +51 -0
  36. data/lib/peatio/ranger/connection.rb +117 -0
  37. data/lib/peatio/ranger/events.rb +11 -0
  38. data/lib/peatio/ranger/router.rb +234 -0
  39. data/lib/peatio/ranger/web_socket.rb +68 -0
  40. data/lib/peatio/security/key_generator.rb +26 -0
  41. data/lib/peatio/sql/client.rb +19 -0
  42. data/lib/peatio/sql/schema.rb +72 -0
  43. data/lib/peatio/transaction.rb +122 -0
  44. data/lib/peatio/upstream/base.rb +116 -0
  45. data/lib/peatio/upstream/registry.rb +14 -0
  46. data/lib/peatio/version.rb +3 -0
  47. data/lib/peatio/wallet/abstract.rb +189 -0
  48. data/lib/peatio/wallet/error.rb +37 -0
  49. data/lib/peatio/wallet/registry.rb +16 -0
  50. data/peatio.gemspec +59 -0
  51. metadata +480 -0
@@ -0,0 +1,37 @@
1
+ module Peatio
2
+ module Blockchain
3
+ Error = Class.new(StandardError)
4
+
5
+ class ClientError < Error
6
+
7
+ attr_reader :wrapped_ex
8
+
9
+ def initialize(ex_or_string)
10
+ @wrapped_ex = nil
11
+
12
+ if ex_or_string.respond_to?(:backtrace)
13
+ super(ex_or_string.message)
14
+ @wrapped_exception = ex_or_string
15
+ else
16
+ super(ex_or_string.to_s)
17
+ end
18
+ end
19
+ end
20
+
21
+ class MissingSettingError < Error
22
+ def initialize(key)
23
+ super "#{key.capitalize} setting is missing"
24
+ end
25
+ end
26
+
27
+ class UnavailableAddressBalanceError < Error
28
+ def initialize(address)
29
+ @address = address
30
+ end
31
+
32
+ def message
33
+ "Unable to load #{@address} balance"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,16 @@
1
+ require "peatio/adapter_registry"
2
+
3
+ module Peatio
4
+ module Blockchain
5
+
6
+ VERSION = "1.0.0".freeze
7
+
8
+ class << self
9
+ def registry
10
+ @registry ||= Registry.new
11
+ end
12
+ end
13
+ class Registry < Peatio::AdapterRegistry
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Peatio::Command
2
+ class Base < Clamp::Command
3
+ def say(str)
4
+ puts str
5
+ end
6
+
7
+ def sql_client
8
+ @sql_client ||= Peatio::Sql::Client.new.connect
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,20 @@
1
+ module Peatio::Command::DB
2
+ class Create < Peatio::Command::Base
3
+ def execute
4
+ client = Peatio::Sql::Client.new
5
+ database_name = client.config.delete(:database)
6
+ Peatio::Sql::Schema.new(client.connect).create_database(database_name)
7
+ end
8
+ end
9
+
10
+ class Migrate < Peatio::Command::Base
11
+ def execute
12
+ Peatio::Sql::Schema.new(sql_client).create_tables
13
+ end
14
+ end
15
+
16
+ class Root < Peatio::Command::Base
17
+ subcommand "create", "Create database", Peatio::Command::DB::Create
18
+ subcommand "migrate", "Create tables", Peatio::Command::DB::Migrate
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ module Peatio::Command
2
+ class Inject < Peatio::Command::Base
3
+ class PeatioEvents < Peatio::Command::Base
4
+ option ["-e", "--exchange"], "NAME", "exchange name to inject messages to", default: "peatio.events.ranger"
5
+ def execute
6
+ Peatio::Logger.logger.level = :debug
7
+ Peatio::Injectors::PeatioEvents.new.run!(exchange)
8
+ end
9
+ end
10
+
11
+ subcommand "peatio_events", "Inject peatio events in mq", PeatioEvents
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ require "peatio/command/base"
2
+ require "peatio/command/service"
3
+ require "peatio/command/db"
4
+ require "peatio/command/inject"
5
+ require "peatio/command/security"
6
+
7
+ module Peatio
8
+ class Root < Command::Base
9
+ subcommand "db", "Database related sub-commands", Peatio::Command::DB::Root
10
+ subcommand "service", "Services management related sub-commands", Peatio::Command::Service::Root
11
+ subcommand "inject", "Data injectors", Peatio::Command::Inject
12
+ subcommand "security", "Security management related sub-commands", Peatio::Command::Security
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Peatio::Command
4
+ class Security < Peatio::Command::Base
5
+ class KeyGenerator < Peatio::Command::Base
6
+ option "--print", :flag, "print on screen"
7
+ option "--path", "FOLDER", "save keypair into folder", default: "secrets"
8
+
9
+ def execute
10
+ keypair = Peatio::Security::KeyGenerator.new
11
+
12
+ if print?
13
+ puts keypair.private, keypair.public
14
+ puts "-----BASE64 ENCODED-----"
15
+ puts Base64.urlsafe_encode64(keypair.public)
16
+ else
17
+ begin
18
+ keypair.save(path)
19
+ puts "Files saved in #{File.join(path, 'rsa-key')}"
20
+ rescue IOError => e
21
+ abort("Failed saving files")
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ subcommand "keygen", "Generate a public private rsa key pair", KeyGenerator
28
+ end
29
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Peatio::Command::Service
4
+ class Start < Peatio::Command::Base
5
+ class Ranger < Peatio::Command::Base
6
+ option ["-e", "--exchange"], "NAME", "exchange name to inject messages to", default: "peatio.events.ranger"
7
+ option "--[no-]stats", :flag, "display periodically connections statistics", default: true
8
+ option "--stats-period", "SECONDS", "period of displaying stats in seconds", default: 30
9
+ def execute
10
+ raise ArgumentError, "JWT_PUBLIC_KEY was not specified." if ENV["JWT_PUBLIC_KEY"].to_s.empty?
11
+
12
+ key_decoded = Base64.urlsafe_decode64(ENV["JWT_PUBLIC_KEY"])
13
+
14
+ jwt_public_key = OpenSSL::PKey.read(key_decoded)
15
+ if jwt_public_key.private?
16
+ raise ArgumentError, "JWT_PUBLIC_KEY was set to private key, however it should be public."
17
+ end
18
+
19
+ raise "stats period missing" if stats? && !stats_period
20
+
21
+ Prometheus::Client.config.data_store = Prometheus::Client::DataStores::SingleThreaded.new()
22
+ registry = Prometheus::Client.registry
23
+
24
+ opts = {
25
+ display_stats: stats?,
26
+ stats_period: stats_period.to_f,
27
+ metrics_port: 8082,
28
+ registry: registry
29
+ }
30
+ ::Peatio::Ranger.run!(jwt_public_key, exchange, opts)
31
+ end
32
+ end
33
+
34
+ subcommand "ranger", "Start ranger process", Ranger
35
+ end
36
+
37
+ class Root < Peatio::Command::Base
38
+ subcommand "start", "Start a service", Start
39
+ end
40
+ end
@@ -0,0 +1,18 @@
1
+ class Peatio::Error < ::StandardError
2
+ @@default_code = 2000
3
+
4
+ attr :code, :text
5
+
6
+ def initialize(opts = {})
7
+ @code = opts[:code] || @@default_code
8
+ @text = opts[:text] || ""
9
+
10
+ @message = {error: {code: @code, message: @text}}
11
+
12
+ if @text != ""
13
+ super("#{@code}: #{text}")
14
+ else
15
+ super("#{@code}")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,64 @@
1
+ require "mysql2"
2
+ require "benchmark"
3
+
4
+ client = Mysql2::Client.new(
5
+ host: "172.19.0.3",
6
+ username: "root",
7
+ password: "changeme",
8
+ port: 3306,
9
+ database: "peatio_development")
10
+
11
+ queries = [
12
+ "INSERT INTO `trades` (`ask_id`, `ask_member_id`, `bid_id`, `bid_member_id`, `price`, `volume`, `funds`, `market_id`, `trend`, `created_at`, `updated_at`) VALUES (18711, 81, 18708, 82, 0.99999999, 50.0, 49.9999995, 'eurusd', 0, NOW(), NOW())",
13
+ "UPDATE `accounts` SET `accounts`.`locked` = 3571.09999702 WHERE `accounts`.`id` = 164",
14
+ "UPDATE `accounts` SET `accounts`.`balance` = 999995119.5335 WHERE `accounts`.`id` = 163",
15
+ "UPDATE `accounts` SET `accounts`.`locked` = 4257.0 WHERE `accounts`.`id` = 161",
16
+ "UPDATE `accounts` SET `accounts`.`balance` = 999995825.720262199325 WHERE `accounts`.`id` = 162",
17
+ "UPDATE `orders` SET `volume` = 20.0, `locked` = 19.9999998, `funds_received` = 53.0, `trades_count` = 2, `updated_at` = '2018-06-25 23:44:37' WHERE `orders`.`id` = 18708",
18
+ "UPDATE `orders` SET `volume` = 0.0, `locked` = 0.0, `funds_received` = 78.59999924, `trades_count` = 2, `state` = 200, `updated_at` = '2018-06-25 23:44:37' WHERE `orders`.`id` = 18711"
19
+ ]
20
+
21
+ puts Benchmark.measure {
22
+ 1_000.times {
23
+
24
+ client.query("begin")
25
+ begin
26
+
27
+ 100.times {
28
+ queries.each do |q|
29
+ client.query q
30
+ end
31
+ }
32
+
33
+ rescue Mysql2::Error => e
34
+ puts "+++++++ DB ERROR - ROLLING BACK ++++++++"
35
+ puts e
36
+ client.query("rollback")
37
+ exit
38
+ end
39
+ client.query("commit") #commit the changes to the DB
40
+
41
+ }
42
+ }
43
+
44
+ client.close
45
+
46
+ __END__
47
+
48
+ require 'mysql2/em'
49
+
50
+ EM.run do
51
+ client = Mysql2::EM::Client.new(
52
+ :host => '172.19.0.3',
53
+ :username => 'root',
54
+ :password => 'changeme',
55
+ :port => 3306,
56
+ :database => 'peatio_development')
57
+
58
+
59
+ defer1 = client.query "SELECT sleep(3) as first_query"
60
+ defer1.callback do |result|
61
+ puts "Result: #{result.to_a.inspect}"
62
+ end
63
+
64
+ end
@@ -0,0 +1,240 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Peatio::Injectors
4
+ class PeatioEvents
5
+ attr_accessor :market, :market_name, :base_unit, :quote_unit, :seller_uid, :buyer_uid, :logger
6
+
7
+ def run!(exchange_name)
8
+ require "time"
9
+ @logger = Peatio::Logger.logger
10
+ @market = "eurusd"
11
+ @market_name = "EUR/USD"
12
+ @base_unit = "eur"
13
+ @quote_unit = "usd"
14
+ @seller_uid = 21
15
+ @buyer_uid = 42
16
+ @messages = create_messages
17
+ @opts = {
18
+ ex_name: exchange_name
19
+ }
20
+ EventMachine.run do
21
+ inject_message()
22
+ end
23
+ end
24
+
25
+ def inject_message()
26
+ if message = @messages.shift
27
+ type, id, event, data = message
28
+ Peatio::Ranger::Events.publish(type, id, event, data, @opts)
29
+ EM.next_tick do
30
+ inject_message()
31
+ end
32
+ else
33
+ Peatio::MQ::Client.disconnect
34
+ EventMachine.stop
35
+ end
36
+ end
37
+
38
+ def create_messages
39
+ [
40
+ public_tickers,
41
+ public_orderbook,
42
+ private_order,
43
+ private_trade_user1,
44
+ private_trade_user2,
45
+ public_trade,
46
+ public_orderbook_increment1,
47
+ public_orderbook_snapshot1,
48
+ public_orderbook_increment2,
49
+ public_orderbook_increment3,
50
+ ]
51
+ end
52
+
53
+ def created_at
54
+ Time.now - 600
55
+ end
56
+
57
+ def updated_at
58
+ Time.now
59
+ end
60
+
61
+ alias completed_at updated_at
62
+ alias canceled_at updated_at
63
+
64
+ def public_orderbook
65
+ [
66
+ "public",
67
+ market,
68
+ "update",
69
+ {
70
+ "asks": [
71
+ ["1020.0", "0.005"],
72
+ ["1026.0", "0.03"]
73
+ ],
74
+ "bids": [
75
+ ["1000.0", "0.25"],
76
+ ["999.0", "0.005"],
77
+ ["994.0", "0.005"],
78
+ ["1.0", "11.0"]
79
+ ]
80
+ }
81
+ ]
82
+ end
83
+
84
+ def public_orderbook_snapshot1
85
+ [
86
+ "public",
87
+ market,
88
+ "ob-snap",
89
+ {
90
+ "asks": [
91
+ ["1020.0", "0.005"],
92
+ ["1026.0", "0.03"]
93
+ ],
94
+ "bids": [
95
+ ["1000.0", "0.25"],
96
+ ["999.0", "0.005"],
97
+ ["994.0", "0.005"],
98
+ ["1.0", "11.0"]
99
+ ]
100
+ }
101
+ ]
102
+ end
103
+
104
+ def public_orderbook_increment1
105
+ [
106
+ "public",
107
+ market,
108
+ "ob-inc",
109
+ {
110
+ "asks": [
111
+ ["1020.0", "0.015"],
112
+ ],
113
+ }
114
+ ]
115
+ end
116
+
117
+ def public_orderbook_increment2
118
+ [
119
+ "public",
120
+ market,
121
+ "ob-inc",
122
+ {
123
+ "bids": [
124
+ ["1000.0", "0"],
125
+ ],
126
+ }
127
+ ]
128
+ end
129
+
130
+ def public_orderbook_increment3
131
+ [
132
+ "public",
133
+ market,
134
+ "ob-inc",
135
+ {
136
+ "bids": [
137
+ ["999.0", "0.001"],
138
+ ],
139
+ }
140
+ ]
141
+ end
142
+
143
+ def public_tickers
144
+ [
145
+ "public",
146
+ "global",
147
+ "tickers",
148
+ {
149
+ market => {
150
+ "name": market_name,
151
+ "base_unit": base_unit,
152
+ "quote_unit": quote_unit,
153
+ "low": "1000.0",
154
+ "high": "10000.0",
155
+ "last": "1000.0",
156
+ "open": 1000.0,
157
+ "volume": "0.0",
158
+ "sell": "1020.0",
159
+ "buy": "1000.0",
160
+ "at": Time.now.to_i
161
+ }
162
+ }
163
+ ]
164
+ end
165
+
166
+ def private_order
167
+ [
168
+ "private",
169
+ "IDABC0000001",
170
+ "order",
171
+ {
172
+ "id": 22,
173
+ "at": created_at.to_i,
174
+ "market": market,
175
+ "kind": "bid",
176
+ "price": "1026.0",
177
+ "state": "wait",
178
+ "volume": "0.001",
179
+ "origin_volume": "0.001"
180
+ }
181
+ ]
182
+ end
183
+
184
+ def private_trade_user1
185
+ [
186
+ "private",
187
+ "IDABC0000001",
188
+ "trade",
189
+ {
190
+ "id": 7,
191
+ "kind": "ask",
192
+ "at": created_at.to_i,
193
+ "price": "1020.0",
194
+ "volume": "0.001",
195
+ "ask_id": 15,
196
+ "bid_id": 22,
197
+ "market": market
198
+ }
199
+ ]
200
+ end
201
+
202
+ def private_trade_user2
203
+ [
204
+ "private",
205
+ "IDABC0000002",
206
+ "trade",
207
+ {
208
+ "id": 7,
209
+ "kind": "bid",
210
+ "at": created_at.to_i,
211
+ "price": "1020.0",
212
+ "volume": "0.001",
213
+ "ask_id": 15,
214
+ "bid_id": 22,
215
+ "market": market
216
+ }
217
+ ]
218
+ end
219
+
220
+ def public_trade
221
+ [
222
+ "public",
223
+ market,
224
+ "trades",
225
+ {
226
+ "trades": [
227
+ {
228
+ "tid": 7,
229
+ "taker_type": "buy",
230
+ "date": created_at.to_i,
231
+ "price": "1020.0",
232
+ "amount":
233
+ "0.001"
234
+ }
235
+ ]
236
+ }
237
+ ]
238
+ end
239
+ end
240
+ end