hive_sql 1.0.1 → 1.0.3
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 +4 -4
- data/Rakefile +807 -0
- data/lib/hive_sql/models/account.rb +5 -0
- data/lib/hive_sql/models/block.rb +13 -1
- data/lib/hive_sql/models/comment.rb +40 -4
- data/lib/hive_sql/models/delegation.rb +24 -0
- data/lib/hive_sql/models/dynamic_global_properties.rb +26 -1
- data/lib/hive_sql/models/proposal.rb +26 -0
- data/lib/hive_sql/models/proposal_approval.rb +15 -0
- data/lib/hive_sql/models/reblog.rb +2 -2
- data/lib/hive_sql/models/transaction.rb +14 -0
- data/lib/hive_sql/models/tx/account_witness_proxy.rb +2 -2
- data/lib/hive_sql/models/tx/custom.rb +1 -0
- data/lib/hive_sql/models/tx/proposal_create.rb +35 -0
- data/lib/hive_sql/models/tx/{update_proposal_vote.rb → proposal_vote_update.rb} +3 -3
- data/lib/hive_sql/models/vo/account_created.rb +23 -0
- data/lib/hive_sql/models/vo/changed_recovery_account.rb +20 -0
- data/lib/hive_sql/models/vo/clear_null_account_balance.rb +21 -0
- data/lib/hive_sql/models/vo/comments_vote.rb +25 -0
- data/lib/hive_sql/models/vo/sps_fund.rb +3 -1
- data/lib/hive_sql/version.rb +1 -1
- data/lib/hive_sql.rb +9 -1
- metadata +41 -44
data/Rakefile
ADDED
@@ -0,0 +1,807 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
require 'hive_sql'
|
4
|
+
require 'awesome_print'
|
5
|
+
|
6
|
+
Rake::TestTask.new(:test) do |t|
|
7
|
+
t.libs << 'test'
|
8
|
+
t.libs << 'lib'
|
9
|
+
t.test_files = FileList['test/**/*_test.rb']
|
10
|
+
t.ruby_opts << if ENV['HELL_ENABLED']
|
11
|
+
'-W2'
|
12
|
+
else
|
13
|
+
'-W1'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
task :default => :test
|
18
|
+
|
19
|
+
task :console do
|
20
|
+
exec "irb -r hive_sql -I ./lib"
|
21
|
+
end
|
22
|
+
|
23
|
+
namespace :created do
|
24
|
+
desc 'Lists accounts created grouped by creator and date.'
|
25
|
+
task :accounts, [:creator, :days_ago] do |t, args|
|
26
|
+
now = Time.now.utc
|
27
|
+
creator = args[:creator]
|
28
|
+
after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
|
29
|
+
|
30
|
+
accounts = HiveSQL::Tx::AccountCreate.all
|
31
|
+
|
32
|
+
if !!creator || creator == '%'
|
33
|
+
unless creator == '%'
|
34
|
+
accounts = accounts.where(creator: creator)
|
35
|
+
end
|
36
|
+
elsif creator =~ /.*%.*/
|
37
|
+
accounts = accounts.where('creator LIKE ?', creator)
|
38
|
+
end
|
39
|
+
|
40
|
+
accounts = accounts.where('timestamp > ?', after_timestamp)
|
41
|
+
accounts = accounts.group('CAST(timestamp AS DATE)', :creator)
|
42
|
+
accounts = accounts.order('cast_timestamp_as_date ASC')
|
43
|
+
|
44
|
+
accounts = accounts.count
|
45
|
+
puts "# Daily creation count by #{creator.nil? ? 'all account creators' : creator} since #{after_timestamp} ..."
|
46
|
+
ap accounts
|
47
|
+
puts "# Total accounts: #{accounts.values.sum}"
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Lists custom_json_operations grouped by id and date.'
|
51
|
+
task :custom_json, [:id, :days_ago, :min_count] do |t, args|
|
52
|
+
now = Time.now.utc
|
53
|
+
tid = args[:id]
|
54
|
+
after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
|
55
|
+
min_count = (args[:min_count] || 1).to_i
|
56
|
+
|
57
|
+
customs = HiveSQL::Tx::Custom.all
|
58
|
+
|
59
|
+
if !!tid && tid != '%' && tid =~ /.*%.*/
|
60
|
+
customs = customs.where("tid LIKE ?", tid)
|
61
|
+
elsif !!tid && tid != '%'
|
62
|
+
customs = customs.where(tid: tid)
|
63
|
+
end
|
64
|
+
|
65
|
+
customs = customs.where('timestamp > ?', after_timestamp)
|
66
|
+
customs = customs.group('CAST(timestamp AS DATE)', :tid)
|
67
|
+
customs = customs.order('cast_timestamp_as_date ASC')
|
68
|
+
|
69
|
+
customs = customs.count
|
70
|
+
|
71
|
+
customs = customs.map do |k, v|
|
72
|
+
[k, v] if v >= min_count
|
73
|
+
end.compact.to_h
|
74
|
+
|
75
|
+
puts "# Daily creation count by #{tid.nil? ? 'all custom_json_operation' : tid} since #{after_timestamp} ..."
|
76
|
+
ap customs
|
77
|
+
puts "# Total custom_json_operation: #{customs.values.sum}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
namespace :deleted do
|
82
|
+
desc 'Lists comments deleted grouped by author and date.'
|
83
|
+
task :comments, [:author, :days_ago, :minimum_deletes] do |t, args|
|
84
|
+
now = Time.now.utc
|
85
|
+
author = args[:author]
|
86
|
+
after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
|
87
|
+
minimum_deletes = (args[:minimum_deletes] || '1').to_i
|
88
|
+
|
89
|
+
delete_comments = HiveSQL::Tx::DeleteComment.all
|
90
|
+
|
91
|
+
if !!author || author == '%'
|
92
|
+
unless author == '%'
|
93
|
+
delete_comments = delete_comments.where(author: author)
|
94
|
+
end
|
95
|
+
elsif author =~ /.*%.*/
|
96
|
+
delete_comments = delete_comments.where('author LIKE ?', author)
|
97
|
+
end
|
98
|
+
|
99
|
+
delete_comments = delete_comments.where('timestamp > ?', after_timestamp)
|
100
|
+
rewards = HiveSQL::Vo::AuthorReward.where(author: delete_comments.select(:author), permlink: delete_comments.select(:permlink))
|
101
|
+
delete_comments = delete_comments.group('CAST(timestamp AS DATE)', :author)
|
102
|
+
delete_comments = delete_comments.order('cast_timestamp_as_date ASC')
|
103
|
+
|
104
|
+
delete_comments = delete_comments.count
|
105
|
+
|
106
|
+
if minimum_deletes > 1
|
107
|
+
delete_comments = delete_comments.select{|k, v| v >= minimum_deletes}
|
108
|
+
end
|
109
|
+
|
110
|
+
puts "# Daily deleted comment count by #{author.nil? ? 'all account authors' : author} since #{after_timestamp} ..."
|
111
|
+
ap delete_comments
|
112
|
+
puts "# Total deleted comments: #{delete_comments.values.sum}"
|
113
|
+
|
114
|
+
puts "# Author reward impact:"
|
115
|
+
puts "# HBD: #{rewards.sum(:hbd_payout)}"
|
116
|
+
puts "# HIVE: #{rewards.sum(:hive_payout)}"
|
117
|
+
puts "# VESTS: #{rewards.sum(:vesting_payout)}"
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
desc 'Lists sum of transfers grouped by date, from, and to.'
|
122
|
+
task :transfers, [:minimum_amount, :symbol, :days_ago] do |t, args|
|
123
|
+
now = Time.now.utc
|
124
|
+
minimum_amount = (args[:minimum_amount] || '1000000').to_f
|
125
|
+
symbol = (args[:symbol] || 'HIVE').upcase
|
126
|
+
after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
|
127
|
+
|
128
|
+
# Only type: transfer; ignore savings, vestings
|
129
|
+
transfers = HiveSQL::Tx::Transfer.where(type: 'transfer')
|
130
|
+
transfers = transfers.where('amount > ?', minimum_amount)
|
131
|
+
transfers = transfers.where('amount_symbol = ?', symbol)
|
132
|
+
transfers = transfers.where('timestamp > ?', after_timestamp)
|
133
|
+
transfers = transfers.group('CAST(timestamp AS DATE)', :from, :to)
|
134
|
+
transfers = transfers.order('cast_timestamp_as_date ASC')
|
135
|
+
|
136
|
+
puts "Daily transfer sum over #{'%.3f' % minimum_amount} #{symbol} since #{after_timestamp} ..."
|
137
|
+
ap transfers.sum(:amount)
|
138
|
+
end
|
139
|
+
|
140
|
+
desc 'Lists sum of powered up grouped by date, from, and to.'
|
141
|
+
task :powerup, [:minimum_amount, :symbol, :days_ago, :not_to_self] do |t, args|
|
142
|
+
now = Time.now.utc
|
143
|
+
minimum_amount = (args[:minimum_amount] || '500').to_f
|
144
|
+
symbol = (args[:symbol] || 'HIVE').upcase
|
145
|
+
after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
|
146
|
+
not_to_self = (args[:not_to_self] || 'false') == 'true'
|
147
|
+
|
148
|
+
minimum_amount = case symbol
|
149
|
+
when 'MVESTS' then minimum_amount * 1e6 #TODO
|
150
|
+
when 'VESTS' then minimum_amount # TODO
|
151
|
+
when 'HIVE' then minimum_amount
|
152
|
+
else; raise "Unknown symbol: #{symbol}"
|
153
|
+
end
|
154
|
+
|
155
|
+
# Only type: transfer; ignore savings, vestings
|
156
|
+
transfers = HiveSQL::Tx::Transfer.where(type: 'transfer_to_vesting')
|
157
|
+
transfers = transfers.where('amount > ?', minimum_amount)
|
158
|
+
transfers = transfers.where('amount_symbol = ?', 'HIVE')
|
159
|
+
transfers = transfers.where('timestamp > ?', after_timestamp)
|
160
|
+
transfers = transfers.group('CAST(timestamp AS DATE)', :from, :to)
|
161
|
+
transfers = transfers.order('cast_timestamp_as_date ASC')
|
162
|
+
|
163
|
+
transfers = transfers.sum(:amount)
|
164
|
+
|
165
|
+
if not_to_self
|
166
|
+
transfers = transfers.map do |k, v|
|
167
|
+
[k, v] if k[1] != k[2]
|
168
|
+
end.compact.to_h
|
169
|
+
end
|
170
|
+
|
171
|
+
puts "# Daily transfer sum over #{'%.3f' % minimum_amount} #{symbol} #{not_to_self ? '' : 'not to self '}since #{after_timestamp} ..."
|
172
|
+
ap transfers
|
173
|
+
puts "# Total #{symbol}: #{transfers.values.sum}"
|
174
|
+
end
|
175
|
+
|
176
|
+
desc 'Lists sum of powered down grouped by date, from, and to.'
|
177
|
+
task :powerdown, [:minimum_amount, :symbol, :days_ago, :not_to_self] do |t, args|
|
178
|
+
now = Time.now.utc
|
179
|
+
minimum_amount = (args[:minimum_amount] || '500').to_f
|
180
|
+
symbol = (args[:symbol] || 'HIVE').upcase
|
181
|
+
after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
|
182
|
+
not_to_self = (args[:not_to_self] || 'false') == 'true'
|
183
|
+
|
184
|
+
minimum_amount = case symbol
|
185
|
+
when 'MVESTS' then minimum_amount * 1e6 #TODO
|
186
|
+
when 'VESTS' then minimum_amount # TODO
|
187
|
+
when 'HIVE' then minimum_amount
|
188
|
+
else; raise "Unknown symbol: #{symbol}"
|
189
|
+
end
|
190
|
+
|
191
|
+
# Only type: transfer; ignore savings, vestings
|
192
|
+
transfers = HiveSQL::Tx::Transfer.where(type: 'transfer_to_vesting')
|
193
|
+
transfers = transfers.where('amount > ?', minimum_amount)
|
194
|
+
transfers = transfers.where('amount_symbol = ?', 'HIVE')
|
195
|
+
transfers = transfers.where('timestamp > ?', after_timestamp)
|
196
|
+
transfers = transfers.group('CAST(timestamp AS DATE)', :from, :to)
|
197
|
+
transfers = transfers.order('cast_timestamp_as_date ASC')
|
198
|
+
|
199
|
+
transfers = transfers.sum(:amount)
|
200
|
+
|
201
|
+
if not_to_self
|
202
|
+
transfers = transfers.map do |k, v|
|
203
|
+
[k, v] if k[1] != k[2]
|
204
|
+
end.compact.to_h
|
205
|
+
end
|
206
|
+
|
207
|
+
puts "# Daily transfer sum over #{'%.3f' % minimum_amount} #{symbol} #{not_to_self ? '' : 'not to self '}since #{after_timestamp} ..."
|
208
|
+
ap transfers
|
209
|
+
puts "# Total #{symbol}: #{transfers.values.sum}"
|
210
|
+
end
|
211
|
+
|
212
|
+
desc 'Lists apps grouped by date, app/version.'
|
213
|
+
task :apps, [:app, :days_ago] do |t, args|
|
214
|
+
now = Time.now.utc
|
215
|
+
app = args[:app]
|
216
|
+
after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
|
217
|
+
|
218
|
+
comments = HiveSQL::Comment.normalized_json
|
219
|
+
comments = comments.app(app) if !!app
|
220
|
+
comments = comments.where('created > ?', after_timestamp)
|
221
|
+
comments = comments.group('CAST(created AS DATE)', "JSON_VALUE(json_metadata, '$.app')")
|
222
|
+
comments = comments.order('cast_created_as_date ASC')
|
223
|
+
|
224
|
+
matching = " matching \"#{app}\"" if !!app
|
225
|
+
puts "Daily app#{matching} count since #{after_timestamp} ..."
|
226
|
+
ap comments.count(:all)
|
227
|
+
end
|
228
|
+
|
229
|
+
desc 'Lists app names grouped by date, app/version.'
|
230
|
+
task :app_names, [:app, :days_ago] do |t, args|
|
231
|
+
now = Time.now.utc
|
232
|
+
app = args[:app]
|
233
|
+
after_timestamp = now - ((args[:days_ago] || '7').to_f * 86400)
|
234
|
+
|
235
|
+
comments = HiveSQL::Comment.normalized_json
|
236
|
+
comments = comments.app(app) if !!app
|
237
|
+
comments = comments.where('created > ?', after_timestamp)
|
238
|
+
comments = comments.group('CAST(created AS DATE)', "JSON_VALUE(json_metadata, '$.app')")
|
239
|
+
comments = comments.order('cast_created_as_date ASC')
|
240
|
+
|
241
|
+
matching = " matching \"#{app}\"" if !!app
|
242
|
+
puts "# Daily app#{matching} count since #{after_timestamp} ..."
|
243
|
+
|
244
|
+
app_names = {}
|
245
|
+
|
246
|
+
comments.count(:all).each do |k, v|
|
247
|
+
date, app = k
|
248
|
+
if !!app && app.include?('/')
|
249
|
+
name, version = app.split('/')
|
250
|
+
app_names[[date, name]] ||= 0.0
|
251
|
+
app_names[[date, name]] += v
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
ap app_names
|
256
|
+
end
|
257
|
+
|
258
|
+
desc 'Do all crosschecks of given account.'
|
259
|
+
task :crosscheck, [:account] do |t, args|
|
260
|
+
account = args[:account]
|
261
|
+
|
262
|
+
Rake::Task["crosscheck:powerdowns"].invoke(account)
|
263
|
+
Rake::Task["crosscheck:powerups"].invoke(account)
|
264
|
+
Rake::Task["crosscheck:transfers"].invoke(account)
|
265
|
+
Rake::Task["crosscheck:vesting_from"].invoke(account)
|
266
|
+
Rake::Task["crosscheck:vesting_to"].invoke(account)
|
267
|
+
end
|
268
|
+
|
269
|
+
namespace :crosscheck do
|
270
|
+
desc 'List of accounts grouped by transfer count crosschecked by memo of given account.'
|
271
|
+
task :transfers, [:account] do |t, args|
|
272
|
+
exchanges = %w(bittrex poloniex openledger blocktrades deepcrypto8 gopax
|
273
|
+
binanceexchange teambitwala changelly hitbtc-exchange korbit roomofsatoshi
|
274
|
+
shapeshiftio huobi-withdrawal bithumbrecv2 user.dunamu hot.dunamu)
|
275
|
+
account = args[:account]
|
276
|
+
|
277
|
+
if account.nil? || account == ''
|
278
|
+
puts 'Account name required.'
|
279
|
+
exit
|
280
|
+
elsif exchanges.include? account
|
281
|
+
puts 'That procedure is not recommended.'
|
282
|
+
exit
|
283
|
+
end
|
284
|
+
|
285
|
+
all = HiveSQL::Tx::Transfer.where(type: 'transfer')
|
286
|
+
transfers = all.where.not(memo: '')
|
287
|
+
transfers = transfers.where(to: exchanges)
|
288
|
+
transfers = if account =~ /%/
|
289
|
+
table = HiveSQL::Tx::Transfer.arel_table
|
290
|
+
transfers.where(table[:from].matches(account))
|
291
|
+
else
|
292
|
+
transfers.where(from: account)
|
293
|
+
end
|
294
|
+
crosscheck_transfers = all.where(memo: transfers.select(:memo))
|
295
|
+
|
296
|
+
if transfers.none?
|
297
|
+
puts "No match."
|
298
|
+
else
|
299
|
+
from = transfers.pluck(:from).uniq.join(', ')
|
300
|
+
puts "Accounts grouped by transfer count using common memos as #{from} on common exchanges ..."
|
301
|
+
ap crosscheck_transfers.group(:from).order('count_all').count(:all)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
desc 'List of accounts grouped by vesting transfers from a given account'
|
306
|
+
task :vesting_from, [:account] do |t, args|
|
307
|
+
account = args[:account]
|
308
|
+
|
309
|
+
if account.nil? || account == ''
|
310
|
+
puts 'Account name required.'
|
311
|
+
exit
|
312
|
+
end
|
313
|
+
|
314
|
+
table = HiveSQL::Tx::Transfer.arel_table
|
315
|
+
all = HiveSQL::Tx::Transfer.where(type: 'transfer_to_vesting')
|
316
|
+
transfers = all.where(table[:from].not_eq(:to))
|
317
|
+
transfers = transfers.where.not(to: '')
|
318
|
+
transfers = if account =~ /%/
|
319
|
+
table = HiveSQL::Tx::Transfer.arel_table
|
320
|
+
transfers.where(table[:from].matches(account))
|
321
|
+
else
|
322
|
+
transfers.where(from: account)
|
323
|
+
end
|
324
|
+
|
325
|
+
if transfers.none?
|
326
|
+
puts "No match."
|
327
|
+
else
|
328
|
+
from = transfers.pluck(:from).uniq.join(', ')
|
329
|
+
puts "Accounts grouped by vesting transfer count from #{from} ..."
|
330
|
+
ap transfers.group(:to).order('count_all').count(:all)
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
desc 'List of accounts grouped by vesting transfers to a given account'
|
335
|
+
task :vesting_to, [:account] do |t, args|
|
336
|
+
account = args[:account]
|
337
|
+
|
338
|
+
if account.nil? || account == ''
|
339
|
+
puts 'Account name required.'
|
340
|
+
exit
|
341
|
+
end
|
342
|
+
|
343
|
+
table = HiveSQL::Tx::Transfer.arel_table
|
344
|
+
all = HiveSQL::Tx::Transfer.where(type: 'transfer_to_vesting')
|
345
|
+
transfers = all.where(table[:from].not_eq(table[:to]))
|
346
|
+
transfers = transfers.where.not(to: '')
|
347
|
+
transfers = if account =~ /%/
|
348
|
+
table = HiveSQL::Tx::Transfer.arel_table
|
349
|
+
transfers.where(table[:to].matches(account))
|
350
|
+
else
|
351
|
+
transfers.where(to: account)
|
352
|
+
end
|
353
|
+
|
354
|
+
if transfers.none?
|
355
|
+
puts "No match."
|
356
|
+
else
|
357
|
+
from = transfers.pluck(:to).uniq.join(', ')
|
358
|
+
puts "Accounts grouped by vesting transfer count to #{from} ..."
|
359
|
+
ap transfers.group(:from).order('count_all').count(:all)
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
desc 'List of accounts grouped by powerdown sums crosschecked by given account.'
|
364
|
+
task :powerdowns, [:account] do |t, args|
|
365
|
+
account = args[:account]
|
366
|
+
|
367
|
+
if account.nil? || account == ''
|
368
|
+
puts 'Account name required.'
|
369
|
+
exit
|
370
|
+
end
|
371
|
+
|
372
|
+
table = HiveSQL::Vo::FillVestingWithdraw.arel_table
|
373
|
+
all = HiveSQL::Vo::FillVestingWithdraw.where(table[:from_account].not_eq(table[:to_account]))
|
374
|
+
powerdowns = if account =~ /%/
|
375
|
+
all.where(table[:from_account].matches(account))
|
376
|
+
else
|
377
|
+
all.where(from_account: account)
|
378
|
+
end
|
379
|
+
|
380
|
+
if powerdowns.none?
|
381
|
+
puts "No match."
|
382
|
+
else
|
383
|
+
from = powerdowns.pluck(:from_account).uniq.join(', ')
|
384
|
+
puts "Powerdowns grouped by sum from #{from} ..."
|
385
|
+
ap powerdowns.group(:to_account).
|
386
|
+
order('sum_try_parse_replace_withdrawn_vests_as_float').
|
387
|
+
sum("TRY_PARSE(REPLACE(withdrawn, ' VESTS', '') AS float)")
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
desc 'List of accounts grouped by powerup sums crosschecked by given account.'
|
392
|
+
task :powerups, [:account] do |t, args|
|
393
|
+
account = args[:account]
|
394
|
+
|
395
|
+
if account.nil? || account == ''
|
396
|
+
puts 'Account name required.'
|
397
|
+
exit
|
398
|
+
end
|
399
|
+
|
400
|
+
table = HiveSQL::Vo::FillVestingWithdraw.arel_table
|
401
|
+
all = HiveSQL::Vo::FillVestingWithdraw.where(table[:from_account].not_eq(table[:to_account]))
|
402
|
+
powerups = if account =~ /%/
|
403
|
+
all.where(table[:to_account].matches(account))
|
404
|
+
else
|
405
|
+
all.where(to_account: account)
|
406
|
+
end
|
407
|
+
|
408
|
+
if powerups.none?
|
409
|
+
puts "No match."
|
410
|
+
else
|
411
|
+
to = powerups.pluck(:to_account).uniq.join(', ')
|
412
|
+
puts "Powerups grouped by sum to #{to} ..."
|
413
|
+
ap powerups.group(:from_account).
|
414
|
+
order('sum_try_parse_replace_withdrawn_vests_as_float').
|
415
|
+
sum("TRY_PARSE(REPLACE(withdrawn, ' VESTS', '') AS float)")
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
420
|
+
namespace :rewards do
|
421
|
+
desc 'Lists author rewards grouped by date.'
|
422
|
+
task :author, [:symbol, :days_ago, :author] do |t, args|
|
423
|
+
now = Time.now.utc
|
424
|
+
symbol = (args[:symbol] || 'HBD').upcase
|
425
|
+
after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
|
426
|
+
author = args[:author]
|
427
|
+
|
428
|
+
rewards = HiveSQL::Vo::AuthorReward
|
429
|
+
rewards = rewards.where('timestamp > ?', after_timestamp)
|
430
|
+
rewards = rewards.group('CAST(timestamp AS DATE)')
|
431
|
+
rewards = rewards.order('cast_timestamp_as_date ASC')
|
432
|
+
|
433
|
+
if !!author
|
434
|
+
if author =~ /%/
|
435
|
+
rewards = rewards.where("author LIKE ?", author)
|
436
|
+
else
|
437
|
+
rewards = rewards.where(author: author)
|
438
|
+
end
|
439
|
+
|
440
|
+
puts "Daily #{author} reward #{symbol} sum grouped by date since #{after_timestamp} ..."
|
441
|
+
else
|
442
|
+
puts "Daily reward #{symbol} sum grouped by date since #{after_timestamp} ..."
|
443
|
+
end
|
444
|
+
|
445
|
+
rewards = case symbol
|
446
|
+
when 'HBD' then rewards.sum(:hbd_payout)
|
447
|
+
when 'HIVE' then rewards.sum(:hive_payout)
|
448
|
+
when 'VESTS' then rewards.sum(:vesting_payout)
|
449
|
+
when 'MVESTS'
|
450
|
+
rewards.sum('vesting_payout / 1000000')
|
451
|
+
when 'HP'
|
452
|
+
properties = HiveSQL::DynamicGlobalProperties.first
|
453
|
+
total_vesting_fund_hive = properties.total_vesting_fund_hive.to_f
|
454
|
+
total_vesting_shares_mvest = properties.total_vesting_shares.to_f / 1e6
|
455
|
+
base_per_mvest = total_vesting_fund_hive / total_vesting_shares_mvest
|
456
|
+
|
457
|
+
rewards.sum("(vesting_payout / 1000000) * #{base_per_mvest}")
|
458
|
+
else; puts "Unknown symbol: #{symbol}. Symbols supported: HBD, HIVE, VESTS, MVESTS, HP"
|
459
|
+
end
|
460
|
+
|
461
|
+
ap rewards
|
462
|
+
sum = rewards.values.sum
|
463
|
+
puts "# Total rewards: %.3f %s (average: %.3f per day)" % [sum, symbol, (sum / rewards.size)]
|
464
|
+
end
|
465
|
+
|
466
|
+
desc 'Lists curation rewards grouped by date.'
|
467
|
+
task :curation, [:symbol, :days_ago, :curator] do |t, args|
|
468
|
+
now = Time.now.utc
|
469
|
+
symbol = (args[:symbol] || 'MVESTS').upcase
|
470
|
+
after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
|
471
|
+
curator = args[:curator]
|
472
|
+
|
473
|
+
rewards = HiveSQL::Vo::CurationReward
|
474
|
+
rewards = rewards.where('timestamp > ?', after_timestamp)
|
475
|
+
rewards = rewards.group('CAST(timestamp AS DATE)')
|
476
|
+
rewards = rewards.order('cast_timestamp_as_date ASC')
|
477
|
+
|
478
|
+
if !!curator
|
479
|
+
if curator =~ /%/
|
480
|
+
rewards = rewards.where("curator LIKE ?", curator)
|
481
|
+
else
|
482
|
+
rewards = rewards.where(curator: curator)
|
483
|
+
end
|
484
|
+
|
485
|
+
puts "Daily #{curator} reward #{symbol} sum grouped by date since #{after_timestamp} ..."
|
486
|
+
else
|
487
|
+
puts "Daily curation reward #{symbol} sum grouped by date since #{after_timestamp} ..."
|
488
|
+
end
|
489
|
+
|
490
|
+
rewards = case symbol
|
491
|
+
when 'VESTS'
|
492
|
+
rewards.sum("TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float)")
|
493
|
+
when 'MVESTS'
|
494
|
+
rewards.sum("TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float) / 1000000")
|
495
|
+
when 'HP'
|
496
|
+
properties = HiveSQL::DynamicGlobalProperties.first
|
497
|
+
total_vesting_fund_hive = properties.total_vesting_fund_hive.to_f
|
498
|
+
total_vesting_shares_mvest = properties.total_vesting_shares.to_f / 1e6
|
499
|
+
base_per_mvest = total_vesting_fund_hive / total_vesting_shares_mvest
|
500
|
+
|
501
|
+
rewards.sum("(TRY_PARSE(REPLACE(reward, ' VESTS', '') AS float) / 1000000) * #{base_per_mvest}")
|
502
|
+
else; puts "Unknown symbol: #{symbol}. Symbols supported: VESTS, MVESTS, HP"
|
503
|
+
end
|
504
|
+
|
505
|
+
ap rewards
|
506
|
+
sum = rewards.values.sum
|
507
|
+
puts "# Total rewards: %.3f %s (average: %.3f per day)" % [sum, symbol, (sum / rewards.size)]
|
508
|
+
end
|
509
|
+
end
|
510
|
+
|
511
|
+
desc 'Lists proxied grouped by month.'
|
512
|
+
task :proxied, [:days_ago] do |t, args|
|
513
|
+
now = Time.now.utc
|
514
|
+
after_timestamp = now - ((args[:days_ago] || '7').to_i * 86400)
|
515
|
+
|
516
|
+
proxied = HiveSQL::Tx::AccountWitnessProxy
|
517
|
+
proxied = proxied.where('timestamp > ?', after_timestamp)
|
518
|
+
proxied = proxied.group("FORMAT(timestamp, 'yyyy-MM')", :proxy)
|
519
|
+
proxied = proxied.order('format_timestamp_yyyy_mm ASC')
|
520
|
+
|
521
|
+
puts "Daily proxied grouped by month since #{after_timestamp} ..."
|
522
|
+
|
523
|
+
ap proxied.count(:all)
|
524
|
+
end
|
525
|
+
|
526
|
+
desc <<~EOF
|
527
|
+
Claimed Rewards.
|
528
|
+
Use the "account_name" of a user or '%' to match on any user.
|
529
|
+
EOF
|
530
|
+
task :claimed, [:account_name, :days_ago, :symbol] do |t, args|
|
531
|
+
now = Time.now.utc
|
532
|
+
account_name = args[:account_name] || '%'
|
533
|
+
after_timestamp = now - ((args[:days_ago] || '30').to_i * 86400)
|
534
|
+
symbol = (args[:symbol] || 'vests').downcase.to_sym
|
535
|
+
claims = HiveSQL::Tx::ClaimRewardBalance.where('timestamp > ?', after_timestamp)
|
536
|
+
|
537
|
+
claims = if account_name =~ /%/
|
538
|
+
claims.where('account LIKE ?', account_name)
|
539
|
+
else
|
540
|
+
claims.where(account: account_name)
|
541
|
+
end
|
542
|
+
|
543
|
+
claims = case symbol
|
544
|
+
when :vests then claims.where("reward_vests > 0")
|
545
|
+
when :mvests then claims.where("reward_vests > 0")
|
546
|
+
when :hive then claims.where("reward_hive > 0")
|
547
|
+
when :hbd then claims.where("reward_hbd > 0")
|
548
|
+
else; raise "Unknown symbol: #{symbol.to_s.upcase} (allowed: VESTS, MVESTS, HIVE, HBD)"
|
549
|
+
end
|
550
|
+
|
551
|
+
claims = claims.group("FORMAT(timestamp, 'yyyy-MM')")
|
552
|
+
claims = claims.order('format_timestamp_yyyy_mm ASC')
|
553
|
+
|
554
|
+
claims = case symbol
|
555
|
+
when :vests then claims.sum(:reward_vests)
|
556
|
+
when :mvests then claims.sum('reward_vests / 1000000')
|
557
|
+
when :hive then claims.sum(:reward_hive)
|
558
|
+
when :hbd then claims.sum(:reward_hbd)
|
559
|
+
end
|
560
|
+
|
561
|
+
puts "# Claimed rewards in #{symbol.to_s.upcase} sum grouped by month ..."
|
562
|
+
|
563
|
+
ap claims
|
564
|
+
puts "# Total claimed #{symbol}: #{claims.values.sum}"
|
565
|
+
end
|
566
|
+
|
567
|
+
desc <<~EOF
|
568
|
+
Balance for given parties.
|
569
|
+
Where "party_a" is the first account, "party_b" is the second account and "symbol" is a valid native symbol.
|
570
|
+
EOF
|
571
|
+
task :balance, [:party_a, :party_b, :symbol] do |t, args|
|
572
|
+
party_a = args[:party_a]
|
573
|
+
party_b = args[:party_b]
|
574
|
+
symbol = args[:symbol].upcase
|
575
|
+
|
576
|
+
balance_a = HiveSQL::Tx::Transfer.where(to: party_a, from: party_b, amount_symbol: symbol).sum(:amount).to_f
|
577
|
+
balance_b = HiveSQL::Tx::Transfer.where(to: party_b, from: party_a, amount_symbol: symbol).sum(:amount).to_f
|
578
|
+
|
579
|
+
puts "#{party_a}: %.3f #{symbol}, difference: %.3f #{symbol}" % [balance_a, (balance_a - balance_b)]
|
580
|
+
puts "#{party_b}: %.3f #{symbol}, difference: %.3f #{symbol}" % [balance_b, (balance_b - balance_a)]
|
581
|
+
end
|
582
|
+
|
583
|
+
desc <<~EOF
|
584
|
+
Top comments by what ...
|
585
|
+
Allowed \"what\" options: voter upvoted downvoted
|
586
|
+
EOF
|
587
|
+
task :top, [:what, :limit] do |t, args|
|
588
|
+
what = args[:what].to_s.downcase.to_sym
|
589
|
+
limit = (args[:limit] || '10').to_i
|
590
|
+
since = 1.week.ago
|
591
|
+
|
592
|
+
case what
|
593
|
+
when :voter
|
594
|
+
votes = HiveSQL::Tx::Vote.after(since)
|
595
|
+
votes = votes.group(:voter)
|
596
|
+
votes = votes.order('count_all DESC')
|
597
|
+
votes = votes.limit(limit)
|
598
|
+
|
599
|
+
ap votes.count
|
600
|
+
when :upvoted, :downvoted
|
601
|
+
comments = HiveSQL::Comment.after(since)
|
602
|
+
comments = if what == :upvoted
|
603
|
+
comments.where('net_rshares > 0')
|
604
|
+
comments = comments.order('sum_net_rshares DESC')
|
605
|
+
elsif what == :downvoted
|
606
|
+
comments.where('net_rshares < 0')
|
607
|
+
comments = comments.order('sum_net_rshares ASC')
|
608
|
+
end
|
609
|
+
|
610
|
+
comments = comments.group(:author, :permlink, :created)
|
611
|
+
comments = comments.limit(limit)
|
612
|
+
|
613
|
+
comments = comments.sum(:net_rshares)
|
614
|
+
|
615
|
+
comments.each do |k, v|
|
616
|
+
url = "https://hive.blog/@#{k[0]}/#{k[1]}"
|
617
|
+
created = (Time.now - k[2]) / 60 / 60 / 24
|
618
|
+
|
619
|
+
puts "#{v}; #{created.round(2)} days ago: #{url}"
|
620
|
+
end
|
621
|
+
else
|
622
|
+
exec 'rake -D top | head -3'
|
623
|
+
end
|
624
|
+
end
|
625
|
+
|
626
|
+
desc <<~EOF
|
627
|
+
Top tags by pending_payout_value.
|
628
|
+
EOF
|
629
|
+
task :top_tags, [:limit] do |t, args|
|
630
|
+
limit = (args[:limit] || '100').to_i
|
631
|
+
since = 1.week.ago
|
632
|
+
|
633
|
+
comments = HiveSQL::Comment.after(since)
|
634
|
+
comments = comments.joins(:tags)
|
635
|
+
comments = comments.where('pending_payout_value > 0')
|
636
|
+
comments = comments.order('sum_pending_payout_value DESC')
|
637
|
+
|
638
|
+
comments = comments.group('LOWER(tags.tag)')
|
639
|
+
comments = comments.limit(limit)
|
640
|
+
|
641
|
+
comments = comments.sum(:pending_payout_value)
|
642
|
+
|
643
|
+
comments.each do |k, v|
|
644
|
+
url = "https://hive.blog/#{k}"
|
645
|
+
|
646
|
+
puts "#{v}; #{url}"
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
650
|
+
desc 'Lists sum of proposal pay grouped by date, from, and to.'
|
651
|
+
task :proposal_pay, [:minimum_payment, :days_ago] do |t, args|
|
652
|
+
now = Time.now.utc
|
653
|
+
minimum_payment = (args[:minimum_payment] || '0.001').to_f
|
654
|
+
symbol = (args[:symbol] || 'HBD').upcase
|
655
|
+
days_ago = (args[:days_ago] || '30').to_i
|
656
|
+
after_timestamp = now - days_ago * 86400
|
657
|
+
|
658
|
+
payments = HiveSQL::Vo::ProposalPay.where.not(receiver: ['steem.dao', 'hive.fund'])
|
659
|
+
payments = payments.where('payment > ?', minimum_payment)
|
660
|
+
payments = payments.where('payment_symbol = ?', symbol)
|
661
|
+
payments = payments.where('timestamp > ?', after_timestamp)
|
662
|
+
payments = payments.group('CAST(timestamp AS DATE)', :receiver)
|
663
|
+
payments = payments.order('cast_timestamp_as_date ASC')
|
664
|
+
|
665
|
+
puts "Daily payment sum over #{'%.3f' % minimum_payment} #{symbol} since #{after_timestamp} ..."
|
666
|
+
ap payments.sum(:payment)
|
667
|
+
|
668
|
+
average_daily_payments = payments.sum(:payment).values.sum / days_ago
|
669
|
+
puts "Average daily payments: #{'%.3f' % average_daily_payments} #{symbol}"
|
670
|
+
end
|
671
|
+
|
672
|
+
desc 'Lists sum of HBD interest grouped by date, from, and to.'
|
673
|
+
task :interest, [:minimum_payment, :days_ago] do |t, args|
|
674
|
+
now = Time.now.utc
|
675
|
+
minimum_payment = (args[:minimum_payment] || '0.001').to_f
|
676
|
+
days_ago = (args[:days_ago] || '30').to_i
|
677
|
+
after_timestamp = now - days_ago * 86400
|
678
|
+
|
679
|
+
payments = HiveSQL::Vo::Interest.all
|
680
|
+
payments = payments.where('Interest > ?', minimum_payment)
|
681
|
+
payments = payments.where('timestamp > ?', after_timestamp)
|
682
|
+
duration = payments.minimum(:timestamp)
|
683
|
+
|
684
|
+
payments = payments.group('CAST(timestamp AS DATE)')
|
685
|
+
payments = payments.order('cast_timestamp_as_date ASC')
|
686
|
+
|
687
|
+
puts "# Daily interest payment sum #{'%.3f HBD' % minimum_payment} and over, since #{after_timestamp} ..."
|
688
|
+
ap payments.sum(:Interest)
|
689
|
+
|
690
|
+
actual_days = ((((Time.now - duration)) / 60) / 60) / 24
|
691
|
+
interst_sum = payments.sum(:Interest).values.sum
|
692
|
+
average_daily_payments = interst_sum / actual_days
|
693
|
+
puts "Total interest paid for period #{'%.3f HBD' % interst_sum}; average daily payments: #{'%.3f HBD' % average_daily_payments} (days: #{actual_days})"
|
694
|
+
end
|
695
|
+
|
696
|
+
# Doesn't look like this table exists.
|
697
|
+
desc 'List conversion HBD conversion request sums grouped by day.'
|
698
|
+
task :convert, [:days_ago] do |t, args|
|
699
|
+
now = Time.now.utc
|
700
|
+
after_timestamp = now - ((args[:days_ago] || '3.5').to_f * 86400)
|
701
|
+
|
702
|
+
converts = HiveSQL::Vo::FillConvertRequest
|
703
|
+
converts = converts.where('timestamp > ?', after_timestamp)
|
704
|
+
converts = converts.group('CAST(timestamp AS DATE)')
|
705
|
+
converts = converts.order('cast_timestamp_as_date ASC')
|
706
|
+
|
707
|
+
puts "# Daily HBD conversion requests sum grouped by date since #{after_timestamp} ..."
|
708
|
+
ap converts.sum(:amount_in)
|
709
|
+
end
|
710
|
+
|
711
|
+
# Doesn't look like this table exists.
|
712
|
+
desc 'List daily activity of account, for specified days (default 90)'
|
713
|
+
task :activity, [:account_name, :days_ago] do |t, args|
|
714
|
+
now = Time.now.utc
|
715
|
+
after_timestamp = now - ((args[:days_ago] || '90').to_f * 86400)
|
716
|
+
account_name = args[:account_name]
|
717
|
+
|
718
|
+
trx = HiveSQL::Transaction.by(account_name)
|
719
|
+
trx = trx.joins(:block).where('timestamp > ?', after_timestamp)
|
720
|
+
trx = trx.group('type')
|
721
|
+
trx = trx.order('count_type ASC')
|
722
|
+
|
723
|
+
puts "# Daily transactions by #{account_name} for type count grouped by type since #{after_timestamp} ..."
|
724
|
+
ap trx.count(:type)
|
725
|
+
end
|
726
|
+
|
727
|
+
namespace :witnesses do
|
728
|
+
desc 'Count witnesses that have signed blocks, group by day.'
|
729
|
+
task :count, [:days_ago] do |t, args|
|
730
|
+
now = Time.now.utc
|
731
|
+
days_ago = (args[:days_ago] || '3.5').to_f
|
732
|
+
after_timestamp = now - (days_ago * 86400)
|
733
|
+
|
734
|
+
blocks = HiveSQL::Block
|
735
|
+
blocks = blocks.where('timestamp > ?', after_timestamp)
|
736
|
+
duration = blocks.minimum(:timestamp)
|
737
|
+
total_witness_count = blocks.distinct.count(:witness)
|
738
|
+
blocks = blocks.group('CAST(timestamp AS DATE)')
|
739
|
+
blocks = blocks.order('cast_timestamp_as_date ASC')
|
740
|
+
|
741
|
+
actual_days = ((((Time.now - duration)) / 60) / 60) / 24
|
742
|
+
|
743
|
+
puts "Witness count that signed blocks grouped by date since #{after_timestamp} ..."
|
744
|
+
ap blocks.distinct.count(:witness)
|
745
|
+
puts "# Total unique witnesses: %d (average: %.1f per day)" % [total_witness_count, (blocks.distinct.count(:witness).values.sum) / actual_days]
|
746
|
+
end
|
747
|
+
|
748
|
+
desc 'Witness accounts that have signed blocks, group by day.'
|
749
|
+
task :accounts, [:days_ago] do |t, args|
|
750
|
+
now = Time.now.utc
|
751
|
+
days_ago = (args[:days_ago] || '3.5').to_f
|
752
|
+
after_timestamp = now - (days_ago * 86400)
|
753
|
+
|
754
|
+
blocks = HiveSQL::Block
|
755
|
+
blocks = blocks.where('timestamp > ?', after_timestamp)
|
756
|
+
duration = blocks.minimum(:timestamp)
|
757
|
+
total_witness_count = blocks.distinct.count(:witness)
|
758
|
+
blocks = blocks.group(:witness)
|
759
|
+
blocks = blocks.order('1 ASC')
|
760
|
+
|
761
|
+
actual_days = ((((Time.now - duration)) / 60) / 60) / 24
|
762
|
+
|
763
|
+
puts "Witness count that signed blocks grouped by date since #{after_timestamp} ..."
|
764
|
+
ap blocks.distinct.count(:all)
|
765
|
+
puts "# Total unique witnesses: %d" % [total_witness_count]
|
766
|
+
end
|
767
|
+
|
768
|
+
desc 'New witness accounts that have signed blocks, group by day.'
|
769
|
+
task :new_accounts, [:days_ago] do |t, args|
|
770
|
+
now = Time.now.utc
|
771
|
+
days_ago = (args[:days_ago] || '3.5').to_f
|
772
|
+
after_timestamp = now - (days_ago * 86400)
|
773
|
+
|
774
|
+
blocks = HiveSQL::Block
|
775
|
+
previous_blocks = blocks.where('timestamp <= ?', after_timestamp).limit(9600) # about one day of blocks
|
776
|
+
previous_blocks = previous_blocks.order(block_num: :desc)
|
777
|
+
blocks = blocks.where('timestamp > ?', after_timestamp).where.not(witness: previous_blocks.select(:witness))
|
778
|
+
duration = blocks.minimum(:timestamp)
|
779
|
+
total_witness_count = blocks.distinct.count(:witness)
|
780
|
+
blocks = blocks.group(:witness)
|
781
|
+
blocks = blocks.order('1 ASC')
|
782
|
+
|
783
|
+
actual_days = ((((Time.now - duration)) / 60) / 60) / 24
|
784
|
+
|
785
|
+
puts "New witness count that signed blocks grouped by date since #{after_timestamp} ..."
|
786
|
+
ap blocks.distinct.count(:all)
|
787
|
+
puts "# Total unique witnesses: %d" % [total_witness_count]
|
788
|
+
end
|
789
|
+
end
|
790
|
+
|
791
|
+
desc 'Build a new version of the hive_sql gem.'
|
792
|
+
task :build do
|
793
|
+
exec 'gem build hive_sql.gemspec'
|
794
|
+
end
|
795
|
+
|
796
|
+
desc 'Publish the current version of the hive_sql gem.'
|
797
|
+
task :push do
|
798
|
+
exec "gem push hive_sql-#{HiveSQL::VERSION}.gem"
|
799
|
+
end
|
800
|
+
|
801
|
+
# We're not going to yank on a regular basis, but this is how it's done if you
|
802
|
+
# really want a task for that for some reason.
|
803
|
+
|
804
|
+
# desc 'Yank the current version of the hive_sql gem.'
|
805
|
+
# task :yank do
|
806
|
+
# exec "gem yank hive_sql -v #{HiveSQL::VERSION}"
|
807
|
+
# end
|