meeseeker 1.0.0 → 2.0.0.pre.1
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/README.md +116 -98
- data/Rakefile +121 -44
- data/lib/meeseeker.rb +178 -6
- data/lib/meeseeker/block_follower_job.rb +33 -17
- data/lib/meeseeker/hive_engine.rb +20 -0
- data/lib/meeseeker/steem_engine/agent.rb +33 -19
- data/lib/meeseeker/steem_engine/follower_job.rb +31 -14
- data/lib/meeseeker/version.rb +1 -1
- data/lib/meeseeker/witness_schedule_job.rb +6 -2
- data/meeseeker.gemspec +1 -0
- data/test/meeseeker/meeseeker_test.rb +247 -20
- data/test/test_helper.rb +10 -0
- metadata +29 -9
data/lib/meeseeker/version.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
module Meeseeker
|
2
2
|
class WitnessScheduleJob
|
3
3
|
def perform(options = {})
|
4
|
-
|
4
|
+
chain = (options[:chain] || 'hive').to_sym
|
5
|
+
chain_key_prefix = chain.to_s if !!options[:chain]
|
6
|
+
chain_key_prefix ||= Meeseeker.default_chain_key_prefix
|
7
|
+
url = Meeseeker.default_url(chain_key_prefix)
|
8
|
+
database_api = Meeseeker.database_api_class(chain_key_prefix).new(url: url)
|
5
9
|
redis = Meeseeker.redis
|
6
10
|
mode = options.delete(:mode) || Meeseeker.stream_mode
|
7
11
|
schedule = nil
|
@@ -53,7 +57,7 @@ module Meeseeker
|
|
53
57
|
|
54
58
|
if next_shuffle_block_num != last_shuffle_block_num
|
55
59
|
puts "next_shuffle_block_num: #{next_shuffle_block_num}; current_shuffled_witnesses: #{schedule.current_shuffled_witnesses.join(', ')}"
|
56
|
-
redis.publish(
|
60
|
+
redis.publish("#{chain_key_prefix}:witness:schedule", schedule.to_json)
|
57
61
|
last_shuffle_block_num = next_shuffle_block_num
|
58
62
|
end
|
59
63
|
|
data/meeseeker.gemspec
CHANGED
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
|
32
32
|
s.add_dependency 'redis', '~> 4.1', '>= 4.1.0'
|
33
33
|
s.add_dependency 'steem-ruby', '~> 0.9', '>= 0.9.4'
|
34
|
+
s.add_dependency 'hive-ruby', '~> 1.0.0.pre-1', '>= 1.0.0.pre-1'
|
34
35
|
s.add_dependency 'mechanize', '~> 2.7', '>= 2.7.6'
|
35
36
|
s.add_dependency 'rb-readline', '~> 0.5', '>= 0.5.5'
|
36
37
|
end
|
@@ -4,38 +4,265 @@ require 'rake'
|
|
4
4
|
module Meeseeker
|
5
5
|
class MeeseekerTest < Meeseeker::Test
|
6
6
|
def setup
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
Dir.chdir(pwd)
|
7
|
+
@max_blocks = 30 # must be at least 15 to get past irreversible
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_verify_hive_jobs
|
11
|
+
chain = 'hive'
|
12
|
+
check_keys(chain)
|
13
|
+
keys = []
|
15
14
|
|
16
15
|
begin
|
17
|
-
|
18
|
-
|
16
|
+
Rake::Task['verify:block_org'].reenable
|
17
|
+
assert Rake::Task['verify:block_org'].invoke('hive', @max_blocks)
|
18
|
+
rescue SystemExit => e
|
19
|
+
puts 'Exited.'
|
20
|
+
rescue Redis::TimeoutError => e
|
21
|
+
skip 'Timed out.'
|
22
|
+
end
|
23
|
+
|
24
|
+
begin
|
25
|
+
Rake::Task['verify:witness:schedule'].reenable
|
26
|
+
assert Rake::Task['verify:witness:schedule'].invoke('hive', @max_blocks)
|
27
|
+
rescue SystemExit => e
|
28
|
+
puts 'Exited.'
|
29
|
+
rescue Redis::TimeoutError => e
|
30
|
+
skip 'Timed out.'
|
31
|
+
end
|
32
|
+
|
33
|
+
block_api = Hive::BlockApi.new(url: 'http://anyx.io')
|
34
|
+
keys = Meeseeker.redis.keys('hive:*')
|
35
|
+
data = keys.map do |key|
|
36
|
+
next if key == 'hive:meeseeker:last_block_num'
|
37
|
+
|
38
|
+
n, b, t, i, o = key.split(':')
|
39
|
+
|
40
|
+
assert_equal 'hive', n, "expected hive key, got: #{key}"
|
41
|
+
|
42
|
+
[b, t]
|
43
|
+
end.compact.sample(10).to_h
|
44
|
+
|
45
|
+
assert data.any?, 'expect hive data'
|
46
|
+
|
47
|
+
data.each do |b, t|
|
48
|
+
block_api.get_block(block_num: b) do |result|
|
49
|
+
block = result.block
|
50
|
+
|
51
|
+
refute_nil block, "did not expect nil block (#{b})"
|
52
|
+
|
53
|
+
if !!block.transaction_ids
|
54
|
+
assert block.transaction_ids.include?(t), "Could not find hive trx_id (#{t}) in block (#{b})."
|
55
|
+
else
|
56
|
+
puts "Skipped check for hive trx_id (#{t}) in block (#{b}) because API does not support lookup."
|
57
|
+
end
|
19
58
|
end
|
20
|
-
|
21
|
-
|
59
|
+
end
|
60
|
+
|
61
|
+
if keys.any?
|
62
|
+
dropped = Meeseeker.redis.del(*keys)
|
63
|
+
puts "Dropped #{dropped} keys."
|
64
|
+
else
|
65
|
+
fail 'No keys.'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_verify_steem_jobs
|
70
|
+
chain = 'steem'
|
71
|
+
check_keys(chain)
|
72
|
+
keys = []
|
73
|
+
|
74
|
+
begin
|
75
|
+
Rake::Task['verify:block_org'].reenable
|
76
|
+
assert Rake::Task['verify:block_org'].invoke('steem', @max_blocks)
|
77
|
+
rescue SystemExit => e
|
78
|
+
puts 'Exited.'
|
79
|
+
rescue Redis::TimeoutError => e
|
80
|
+
skip 'Timed out.'
|
81
|
+
end
|
82
|
+
|
83
|
+
begin
|
84
|
+
Rake::Task['verify:witness:schedule'].reenable
|
85
|
+
assert Rake::Task['verify:witness:schedule'].invoke('steem', @max_blocks)
|
86
|
+
rescue SystemExit => e
|
87
|
+
puts 'Exited.'
|
88
|
+
rescue Redis::TimeoutError => e
|
89
|
+
skip 'Timed out.'
|
90
|
+
end
|
91
|
+
|
92
|
+
block_api = Steem::BlockApi.new
|
93
|
+
keys = Meeseeker.redis.keys('steem:*')
|
94
|
+
data = keys.map do |key|
|
95
|
+
next if key == 'steem:meeseeker:last_block_num'
|
22
96
|
|
23
|
-
|
97
|
+
n, b, t, i, o = key.split(':')
|
98
|
+
|
99
|
+
assert_equal 'steem', n, "expected steem key, got: #{key}"
|
100
|
+
|
101
|
+
[b, t]
|
102
|
+
end.compact.sample(10).to_h
|
103
|
+
|
104
|
+
assert data.any?, 'expect steem data'
|
105
|
+
|
106
|
+
data.each do |b, t|
|
107
|
+
block_api.get_block(block_num: b) do |result|
|
108
|
+
block = result.block
|
109
|
+
|
110
|
+
refute_nil block, "did not expect nil block (#{b})"
|
111
|
+
|
112
|
+
if !!block.transaction_ids
|
113
|
+
assert block.transaction_ids.include?(t), "Could not find steem trx_id (#{t}) in block (#{b})."
|
114
|
+
else
|
115
|
+
puts "Skipped check for steem trx_id (#{t}) in block (#{b}) because API does not support lookup."
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
if keys.any?
|
121
|
+
dropped = Meeseeker.redis.del(*keys)
|
122
|
+
puts "Dropped #{dropped} keys."
|
123
|
+
else
|
124
|
+
fail 'No keys.'
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_verify_steem_engine_jobs
|
129
|
+
chain = 'steem_engine'
|
130
|
+
check_keys(chain)
|
131
|
+
keys = []
|
132
|
+
|
133
|
+
begin
|
134
|
+
Rake::Task['verify:steem_engine_block_org'].reenable
|
135
|
+
Rake::Task['verify:engine_block_org'].reenable
|
136
|
+
assert Rake::Task['verify:steem_engine_block_org'].invoke(@max_blocks)
|
137
|
+
rescue SystemExit => e
|
138
|
+
puts 'Exited.'
|
139
|
+
rescue Redis::TimeoutError => e
|
140
|
+
skip 'Timed out.'
|
141
|
+
end
|
142
|
+
|
143
|
+
begin
|
144
|
+
Rake::Task['verify:steem_engine_ref_blocks'].reenable
|
145
|
+
Rake::Task['verify:engine_ref_blocks'].reenable
|
146
|
+
assert Rake::Task['verify:steem_engine_ref_blocks'].invoke(@max_blocks)
|
147
|
+
rescue SystemExit => e
|
148
|
+
puts 'Exited.'
|
149
|
+
rescue Redis::TimeoutError => e
|
150
|
+
skip 'Timed out.'
|
151
|
+
end
|
152
|
+
|
153
|
+
agent = Meeseeker::SteemEngine::Agent.new
|
154
|
+
keys = Meeseeker.redis.keys('steem_engine:*')
|
155
|
+
data = keys.map do |key|
|
156
|
+
n, b, t, i, o = key.split(':')
|
157
|
+
|
158
|
+
assert_equal chain, n, "expected steem_engine key, got: #{key}"
|
159
|
+
|
160
|
+
next if t == Meeseeker::VIRTUAL_TRX_ID
|
161
|
+
|
162
|
+
[b, t]
|
163
|
+
end.compact.sample(10).to_h
|
164
|
+
|
165
|
+
assert data.any?, 'expect steem_engine data'
|
166
|
+
|
167
|
+
data.each do |b, t|
|
168
|
+
block = agent.block(b)
|
169
|
+
refute_nil block, "did not expect nil block (#{b})"
|
170
|
+
|
171
|
+
count = block['transactions'].select do |trx|
|
172
|
+
trx['transactionId'].include? t
|
173
|
+
end.size
|
174
|
+
|
175
|
+
assert count > 0, "Could not find steem_engine trx_id (#{t}) in block (#{b})."
|
176
|
+
end
|
177
|
+
|
178
|
+
agent.shutdown
|
179
|
+
|
180
|
+
if keys.any?
|
181
|
+
dropped = Meeseeker.redis.del(*keys)
|
182
|
+
puts "Dropped #{dropped} keys."
|
183
|
+
else
|
184
|
+
fail 'No keys.'
|
24
185
|
end
|
25
186
|
end
|
26
187
|
|
27
|
-
def
|
28
|
-
|
188
|
+
def test_verify_hive_engine_jobs
|
189
|
+
chain = 'hive_engine'
|
190
|
+
check_keys(chain)
|
191
|
+
keys = []
|
192
|
+
|
193
|
+
begin
|
194
|
+
Rake::Task['verify:hive_engine_block_org'].reenable
|
195
|
+
Rake::Task['verify:engine_block_org'].reenable
|
196
|
+
assert Rake::Task['verify:hive_engine_block_org'].invoke(@max_blocks)
|
197
|
+
rescue SystemExit => e
|
198
|
+
puts 'Exited.'
|
199
|
+
rescue Redis::TimeoutError => e
|
200
|
+
skip 'Timed out.'
|
201
|
+
end
|
29
202
|
|
30
203
|
begin
|
31
|
-
|
32
|
-
|
33
|
-
assert Rake::Task['verify:
|
204
|
+
Rake::Task['verify:hive_engine_ref_blocks'].reenable
|
205
|
+
Rake::Task['verify:engine_ref_blocks'].reenable
|
206
|
+
assert Rake::Task['verify:hive_engine_ref_blocks'].invoke(@max_blocks)
|
207
|
+
rescue SystemExit => e
|
208
|
+
puts 'Exited.'
|
34
209
|
rescue Redis::TimeoutError => e
|
35
|
-
skip
|
210
|
+
skip 'Timed out.'
|
36
211
|
end
|
37
212
|
|
38
|
-
|
213
|
+
agent = Meeseeker::HiveEngine::Agent.new
|
214
|
+
keys = Meeseeker.redis.keys('hive_engine:*')
|
215
|
+
data = keys.map do |key|
|
216
|
+
n, b, t, i, o = key.split(':')
|
217
|
+
|
218
|
+
assert_equal chain, n, "expected hive_engine key, got: #{key}"
|
219
|
+
|
220
|
+
next if t == Meeseeker::VIRTUAL_TRX_ID
|
221
|
+
|
222
|
+
[b, t]
|
223
|
+
end.compact.sample(10).to_h
|
224
|
+
|
225
|
+
assert data.any?, 'expect hive_engine data'
|
226
|
+
|
227
|
+
data.each do |b, t|
|
228
|
+
block = agent.block(b)
|
229
|
+
refute_nil block, "did not expect nil block (#{b})"
|
230
|
+
|
231
|
+
count = block['transactions'].select do |trx|
|
232
|
+
trx['transactionId'].include? t
|
233
|
+
end.size
|
234
|
+
|
235
|
+
assert count > 0, "Could not find hive_engine trx_id (#{t}) in block (#{b})."
|
236
|
+
end
|
237
|
+
|
238
|
+
agent.shutdown
|
239
|
+
|
240
|
+
if keys.any?
|
241
|
+
dropped = Meeseeker.redis.del(*keys)
|
242
|
+
puts "Dropped #{dropped} keys."
|
243
|
+
else
|
244
|
+
fail 'No keys.'
|
245
|
+
end
|
246
|
+
end
|
247
|
+
private
|
248
|
+
def check_keys(chain)
|
249
|
+
chain = chain_key_prefix = chain.to_s
|
250
|
+
Meeseeker.node_url = case chain.to_sym
|
251
|
+
when :hive_engine then Meeseeker.shuffle_node_url('hive')
|
252
|
+
when :steem_engine then Meeseeker.shuffle_node_url('steem')
|
253
|
+
else
|
254
|
+
Meeseeker.shuffle_node_url(chain.to_s)
|
255
|
+
end
|
256
|
+
|
257
|
+
begin
|
258
|
+
if !!Meeseeker.redis.get(chain_key_prefix + Meeseeker::LAST_BLOCK_NUM_KEY_SUFFIX)
|
259
|
+
fail "Found existing keys. Please use 'rake reset' to enable this test."
|
260
|
+
end
|
261
|
+
rescue Redis::CannotConnectError => e
|
262
|
+
warn "Cannot connect to redis, using MockRedis instead."
|
263
|
+
|
264
|
+
Meeseeker.redis = MockRedis.new
|
265
|
+
end
|
39
266
|
end
|
40
267
|
end
|
41
268
|
end
|
data/test/test_helper.rb
CHANGED
@@ -13,6 +13,16 @@ require 'minitest/hell'
|
|
13
13
|
require 'minitest/proveit'
|
14
14
|
require 'pry'
|
15
15
|
|
16
|
+
# In order to test Rakefile:
|
17
|
+
gem_dir = File.expand_path("..", File.dirname(__FILE__))
|
18
|
+
$LOAD_PATH.unshift gem_dir
|
19
|
+
|
20
|
+
pwd = Dir.pwd
|
21
|
+
Dir.chdir(gem_dir)
|
22
|
+
Rake.application.init
|
23
|
+
Rake.application.load_rakefile
|
24
|
+
Dir.chdir(pwd)
|
25
|
+
|
16
26
|
class Minitest::Test
|
17
27
|
parallelize_me!
|
18
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meeseeker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0.pre.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Martin
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -210,6 +210,26 @@ dependencies:
|
|
210
210
|
- - ">="
|
211
211
|
- !ruby/object:Gem::Version
|
212
212
|
version: 0.9.4
|
213
|
+
- !ruby/object:Gem::Dependency
|
214
|
+
name: hive-ruby
|
215
|
+
requirement: !ruby/object:Gem::Requirement
|
216
|
+
requirements:
|
217
|
+
- - ">="
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
version: 1.0.0.pre.pre.1
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 1.0.0.pre.pre.1
|
223
|
+
type: :runtime
|
224
|
+
prerelease: false
|
225
|
+
version_requirements: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - ">="
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: 1.0.0.pre.pre.1
|
230
|
+
- - "~>"
|
231
|
+
- !ruby/object:Gem::Version
|
232
|
+
version: 1.0.0.pre.pre.1
|
213
233
|
- !ruby/object:Gem::Dependency
|
214
234
|
name: mechanize
|
215
235
|
requirement: !ruby/object:Gem::Requirement
|
@@ -267,6 +287,7 @@ files:
|
|
267
287
|
- bin/meeseeker
|
268
288
|
- lib/meeseeker.rb
|
269
289
|
- lib/meeseeker/block_follower_job.rb
|
290
|
+
- lib/meeseeker/hive_engine.rb
|
270
291
|
- lib/meeseeker/steem_engine/agent.rb
|
271
292
|
- lib/meeseeker/steem_engine/follower_job.rb
|
272
293
|
- lib/meeseeker/version.rb
|
@@ -279,7 +300,7 @@ licenses:
|
|
279
300
|
- CC0-1.0
|
280
301
|
metadata:
|
281
302
|
source_code_uri: https://github.com/inertia186/meeseeker
|
282
|
-
post_install_message:
|
303
|
+
post_install_message:
|
283
304
|
rdoc_options: []
|
284
305
|
require_paths:
|
285
306
|
- lib
|
@@ -290,13 +311,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
290
311
|
version: '0'
|
291
312
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
292
313
|
requirements:
|
293
|
-
- - "
|
314
|
+
- - ">"
|
294
315
|
- !ruby/object:Gem::Version
|
295
|
-
version:
|
316
|
+
version: 1.3.1
|
296
317
|
requirements: []
|
297
|
-
|
298
|
-
|
299
|
-
signing_key:
|
318
|
+
rubygems_version: 3.0.8
|
319
|
+
signing_key:
|
300
320
|
specification_version: 4
|
301
321
|
summary: Redis based block follower is an efficient way for multiple apps to stream
|
302
322
|
the Steem Blockchain.
|