meeseeker 0.0.5 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +52 -5
- data/Rakefile +140 -5
- data/bin/meeseeker +2 -2
- data/lib/meeseeker.rb +6 -2
- data/lib/meeseeker/steem_engine/agent.rb +60 -0
- data/lib/meeseeker/steem_engine/follower_job.rb +107 -0
- data/lib/meeseeker/version.rb +2 -1
- data/meeseeker.gemspec +1 -0
- data/test/meeseeker/meeseeker_test.rb +1 -0
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ad89ce6d8e55cafd5dcca2f0ddc2455c23ece9dab83c2d5e1a3f0a59df6c6a4a
|
4
|
+
data.tar.gz: e709c970eddc2c22c92d6f9482757305b851efc9603ccc725892e1feeb5a966d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a443c55716a8b6c605cb8cd5e72aee8008ba12f5641df0d1dd717e7db2535b4df9895b3d011ca07ab4c80df8164806243ff41eb82de68aa1fdfd0ce76962356
|
7
|
+
data.tar.gz: 53d277d9d1a8c848691bee1c4ecf6406ca61987a3b5010c657bad7485b87a25fd579fef8d7fc06108c2e06b91b50b97ff4b94e70414b2d2afefb1e2c7390b5dd
|
data/README.md
CHANGED
@@ -288,13 +288,52 @@ Or to get all ops for a particular transaction:
|
|
288
288
|
redis-cli --scan --pattern 'steem:*:31ecb9c85e9eabd7ca2460fdb4f3ce4a7ca6ec32:*'
|
289
289
|
```
|
290
290
|
|
291
|
-
|
291
|
+
### Steem Engine Support
|
292
292
|
|
293
|
-
|
294
|
-
<img src="https://i.imgur.com/Y3Sa2GW.jpg" />
|
295
|
-
</center>
|
293
|
+
As of `v0.0.6`, meeseeker can also follow the Steem Engine side-chain. This is optional and requires a separate process.
|
296
294
|
|
297
|
-
|
295
|
+
To sync Steem Engine to your local redis source (also defaults to `redis://127.0.0.1:6379/0`):
|
296
|
+
|
297
|
+
```bash
|
298
|
+
meeseeker sync steem_engine
|
299
|
+
```
|
300
|
+
|
301
|
+
When running `meeseeker sync steem_engine`, the following channels are available:
|
302
|
+
|
303
|
+
* `steem_engine:block`
|
304
|
+
* `steem_engine:transaction`
|
305
|
+
* `steem_engine:market:buy`
|
306
|
+
* `steem_engine:market:cancel`
|
307
|
+
* `steem_engine:market:sell`
|
308
|
+
* `steem_engine:sscstore:buy`
|
309
|
+
* `steem_engine:steempegged:buy`
|
310
|
+
* `steem_engine:steempegged:removeWithdrawal`
|
311
|
+
* `steem_engine:steempegged:withdraw`
|
312
|
+
* `steem_engine:tokens:create`
|
313
|
+
* `steem_engine:tokens:issue`
|
314
|
+
* `steem_engine:tokens:transfer`
|
315
|
+
* `steem_engine:tokens:updateMetadata`
|
316
|
+
* `steem_engine:tokens:updateUrl`
|
317
|
+
|
318
|
+
The above "channel/action" patterns are the ones that are known that the time of writing. In addition, if a new contract is added or updated, meeseeker will automatically publish to these corresponding channels as they appear, without needing to update or even restart meeseeker.
|
319
|
+
|
320
|
+
See main section on [Using `SUBSCRIBE`](#using-subscribe).
|
321
|
+
|
322
|
+
Once your SteemEngine sync has started, you can begin doing queries against redis, for example, in the `redis-cli`:
|
323
|
+
|
324
|
+
```bash
|
325
|
+
redis-cli --scan --pattern 'steem_engine:*:tokens:transfer'
|
326
|
+
```
|
327
|
+
|
328
|
+
This returns the keys, for example:
|
329
|
+
|
330
|
+
```
|
331
|
+
steem_engine:18000:d414373db84e6a642f289641ea1433fda22b8a4d:0:tokens:transfer
|
332
|
+
steem_engine:18004:c9e06c8449d2d04b4a0a31ec7b80d2f62009a5f0:0:tokens:transfer
|
333
|
+
steem_engine:17994:faf097391760ad896b19d5854e2822f62dee284b:0:tokens:transfer
|
334
|
+
```
|
335
|
+
|
336
|
+
See main section on [Using `SCAN`](#using-scan).
|
298
337
|
|
299
338
|
### Docker
|
300
339
|
|
@@ -316,6 +355,14 @@ docker run \
|
|
316
355
|
|
317
356
|
Also see: https://hub.docker.com/r/inertia/meeseeker/
|
318
357
|
|
358
|
+
---
|
359
|
+
|
360
|
+
<center>
|
361
|
+
<img src="https://i.imgur.com/Y3Sa2GW.jpg" />
|
362
|
+
</center>
|
363
|
+
|
364
|
+
See some of my previous Ruby How To posts in: [#radiator](https://steemit.com/created/radiator) [#ruby](https://steemit.com/created/ruby)
|
365
|
+
|
319
366
|
## Get in touch!
|
320
367
|
|
321
368
|
If you're using Radiator, I'd love to hear from you. Drop me a line and tell me what you think! I'm @inertia on STEEM.
|
data/Rakefile
CHANGED
@@ -31,6 +31,16 @@ task :push do
|
|
31
31
|
exec "gem push meeseeker-#{Meeseeker::VERSION}.gem"
|
32
32
|
end
|
33
33
|
|
34
|
+
desc 'Build a new version of the meeseeker docker image.'
|
35
|
+
task :docker_build do
|
36
|
+
exec 'docker build -t inertia/meeseeker:latest .'
|
37
|
+
end
|
38
|
+
|
39
|
+
desc 'Publish the current version of the meeseeker docker image.'
|
40
|
+
task :docker_push do
|
41
|
+
exec 'docker push inertia/meeseeker:latest'
|
42
|
+
end
|
43
|
+
|
34
44
|
task :check_schema do
|
35
45
|
begin
|
36
46
|
abort 'Unable to ping redis source.' unless Meeseeker.redis.ping == 'PONG'
|
@@ -41,8 +51,17 @@ task :check_schema do
|
|
41
51
|
end
|
42
52
|
end
|
43
53
|
|
44
|
-
task(:sync, [:at_block_num] => [:check_schema]) do |t, args|
|
45
|
-
|
54
|
+
task(:sync, [:chain, :at_block_num] => [:check_schema]) do |t, args|
|
55
|
+
chain = (args[:chain] || 'steem').to_sym
|
56
|
+
|
57
|
+
job = case chain
|
58
|
+
when :steem
|
59
|
+
Meeseeker::BlockFollowerJob.new
|
60
|
+
when :steem_engine
|
61
|
+
Meeseeker::SteemEngine::FollowerJob.new
|
62
|
+
else; abort("Unknown chain: #{chain}")
|
63
|
+
end
|
64
|
+
|
46
65
|
job.perform(at_block_num: args[:at_block_num])
|
47
66
|
end
|
48
67
|
|
@@ -54,11 +73,13 @@ namespace :witness do
|
|
54
73
|
end
|
55
74
|
end
|
56
75
|
|
57
|
-
task(:find, [:what, :key] => [:check_schema]) do |t, args|
|
76
|
+
task(:find, [:what, :key, :chain] => [:check_schema]) do |t, args|
|
77
|
+
chain = (args[:chain] || 'steem').downcase.to_sym
|
58
78
|
redis = Meeseeker.redis
|
79
|
+
|
59
80
|
match = case args[:what].downcase.to_sym
|
60
|
-
when :block then "
|
61
|
-
when :trx then "
|
81
|
+
when :block then "#{chain}:#{args[:key]}:*"
|
82
|
+
when :trx then "#{chain}:*:#{args[:key]}:*"
|
62
83
|
else; abort "Unknown lookup using #{args}"
|
63
84
|
end
|
64
85
|
|
@@ -74,6 +95,7 @@ end
|
|
74
95
|
task reset: [:check_schema] do
|
75
96
|
print 'Dropping keys ...'
|
76
97
|
keys = Meeseeker.redis.keys('steem:*')
|
98
|
+
keys += Meeseeker.redis.keys('steem_engine:*')
|
77
99
|
|
78
100
|
if keys.any?
|
79
101
|
print " found #{keys.size} keys ..."
|
@@ -221,6 +243,119 @@ namespace :verify do
|
|
221
243
|
end
|
222
244
|
end
|
223
245
|
|
246
|
+
desc 'Verifies Steem Engine transactions land where they should.'
|
247
|
+
task :steem_engine_block_org, [:max_blocks] do |t, args|
|
248
|
+
max_blocks = args[:max_blocks]
|
249
|
+
node_url = ENV.fetch('MEESEEKER_STEEM_ENGINE_NODE_URL', 'https://api.steem-engine.com/rpc')
|
250
|
+
agent = Meeseeker::SteemEngine::Agent.new(url: node_url)
|
251
|
+
until_block_num = if !!max_blocks
|
252
|
+
agent.latest_block_info['blockNumber']
|
253
|
+
end
|
254
|
+
|
255
|
+
Thread.new do
|
256
|
+
job = Meeseeker::SteemEngine::FollowerJob.new
|
257
|
+
|
258
|
+
loop do
|
259
|
+
begin
|
260
|
+
at_block_num = agent.latest_block_info["blockNumber"] - max_blocks.to_i
|
261
|
+
at_block_num = [at_block_num, 1].max
|
262
|
+
job.perform(at_block_num: at_block_num, until_block_num: until_block_num)
|
263
|
+
rescue => e
|
264
|
+
puts e.inspect
|
265
|
+
sleep 5
|
266
|
+
end
|
267
|
+
|
268
|
+
break # success
|
269
|
+
end
|
270
|
+
|
271
|
+
puts 'Background sync finished ...'
|
272
|
+
end
|
273
|
+
|
274
|
+
begin
|
275
|
+
block_channel = 'steem_engine:block'
|
276
|
+
redis_url = ENV.fetch('MEESEEKER_REDIS_URL', 'redis://127.0.0.1:6379/0')
|
277
|
+
subscription = Redis.new(url: redis_url)
|
278
|
+
ctx = Redis.new(url: redis_url)
|
279
|
+
timeout = (max_blocks).to_i * 3
|
280
|
+
|
281
|
+
subscribe_mode, subscribe_args = if timeout > 0
|
282
|
+
[:subscribe_with_timeout, [timeout, [block_channel]]]
|
283
|
+
else
|
284
|
+
[:subscribe, [[block_channel]]]
|
285
|
+
end
|
286
|
+
|
287
|
+
subscription.send(subscribe_mode, *subscribe_args) do |on|
|
288
|
+
on.subscribe do |channel, subscriptions|
|
289
|
+
puts "Subscribed to ##{channel} (subscriptions: #{subscriptions})"
|
290
|
+
end
|
291
|
+
|
292
|
+
on.message do |channel, message|
|
293
|
+
payload = JSON[message]
|
294
|
+
block_num = payload['block_num']
|
295
|
+
next_block_num = block_num + 1
|
296
|
+
|
297
|
+
if !!max_blocks
|
298
|
+
if block_num >= until_block_num
|
299
|
+
# We're done trailing blocks. Typically, this is used by unit
|
300
|
+
# tests so the test can halt.
|
301
|
+
|
302
|
+
subscription.unsubscribe
|
303
|
+
next
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
while ctx.keys("steem_engine:#{next_block_num}:*").size == 0
|
308
|
+
# This ensures at least the next block has been indexed before
|
309
|
+
# proceeding.
|
310
|
+
|
311
|
+
puts "Waiting for block: #{next_block_num} ..."
|
312
|
+
sleep 6
|
313
|
+
end
|
314
|
+
|
315
|
+
# In theory, we should have all the keys using this pattern.
|
316
|
+
keys = ctx.keys("steem_engine:#{block_num}:*")
|
317
|
+
|
318
|
+
# If we have all the keys, we should also have all transaction ids.
|
319
|
+
expected_ids = keys.map { |k| k.split(':')[2] }.uniq
|
320
|
+
actual_ids = nil
|
321
|
+
|
322
|
+
agent.block(block_num).tap do |block|
|
323
|
+
raise 'Got empty block result.' if block.nil?
|
324
|
+
|
325
|
+
actual_ids = block['transactions'].map{|trx| trx['transactionId'].split('-').first}.uniq
|
326
|
+
end
|
327
|
+
|
328
|
+
# We do an intersection to make sure there's no difference between
|
329
|
+
# the two copies, regardless of order, as opposed to just checking that
|
330
|
+
# the lengths match.
|
331
|
+
|
332
|
+
(actual_ids & expected_ids).tap do |intersection|
|
333
|
+
all_sizes = [intersection.size, expected_ids.size, actual_ids.size]
|
334
|
+
puts 'intersection: %d; expected: %d; actual: %d' % all_sizes
|
335
|
+
|
336
|
+
if all_sizes.min != all_sizes.max
|
337
|
+
puts "Expected transaction ids:"
|
338
|
+
puts expected_ids
|
339
|
+
puts "Actual transaction ids:"
|
340
|
+
puts actual_ids
|
341
|
+
|
342
|
+
puts "actual_ids minus expected:"
|
343
|
+
puts actual_ids - expected_ids
|
344
|
+
puts "expected_ids minus actual:"
|
345
|
+
puts expected_ids - actual_ids
|
346
|
+
|
347
|
+
exit(-1)
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
on.unsubscribe do |channel, subscriptions|
|
353
|
+
puts "Unsubscribed from ##{channel} (subscriptions: #{subscriptions})"
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
224
359
|
namespace :witness do
|
225
360
|
desc 'Verifies witnessses in the schedule produced a block.'
|
226
361
|
task :schedule, [:max_blocks] do |t, args|
|
data/bin/meeseeker
CHANGED
@@ -23,7 +23,7 @@ when 'sync', 'witness:schedule'
|
|
23
23
|
max_backoff = 30
|
24
24
|
|
25
25
|
loop do; begin
|
26
|
-
Rake::Task[ARGV[0]].invoke(ARGV[1])
|
26
|
+
Rake::Task[ARGV[0]].invoke(*ARGV[1..-1])
|
27
27
|
rescue => e
|
28
28
|
puts "Error: #{e.inspect}"
|
29
29
|
backoff = [backoff, max_backoff].min
|
@@ -35,7 +35,7 @@ when 'find' then Rake::Task['find'].invoke(*ARGV[1..-1])
|
|
35
35
|
when 'reset' then Rake::Task['reset'].invoke
|
36
36
|
else
|
37
37
|
puts "\nBegin/resume sync:"
|
38
|
-
puts "\t#{filename} sync\n\n"
|
38
|
+
puts "\t#{filename} sync [chain] [block_num]\n\n"
|
39
39
|
puts "Publish witness schedule:"
|
40
40
|
puts "\t#{filename} witness:schedule\n\n"
|
41
41
|
puts "Start in the ruby console:"
|
data/lib/meeseeker.rb
CHANGED
@@ -4,13 +4,17 @@ require 'steem'
|
|
4
4
|
require 'meeseeker/version'
|
5
5
|
require 'meeseeker/block_follower_job'
|
6
6
|
require 'meeseeker/witness_schedule_job'
|
7
|
+
require 'meeseeker/steem_engine/agent'
|
8
|
+
require 'meeseeker/steem_engine/follower_job'
|
7
9
|
|
8
10
|
module Meeseeker
|
9
11
|
LAST_BLOCK_NUM_KEY = 'steem:meeseeker:last_block_num'
|
12
|
+
LAST_STEEM_ENGINE_BLOCK_NUM_KEY = 'steem:meeseeker:last_steem_engine_block_num'
|
10
13
|
BLOCKS_PER_DAY = 28800
|
11
14
|
VIRTUAL_TRX_ID = '0000000000000000000000000000000000000000'
|
12
15
|
@redis = Redis.new(url: ENV.fetch('MEESEEKER_REDIS_URL', 'redis://127.0.0.1:6379/0'))
|
13
16
|
@node_url = ENV.fetch('MEESEEKER_NODE_URL', 'https://api.steemit.com')
|
17
|
+
@steem_engine_node_url = ENV.fetch('MEESEEKER_STEEM_ENGINE_NODE_URL', 'https://api.steem-engine.com/rpc')
|
14
18
|
@stream_mode = ENV.fetch('MEESEEKER_STREAM_MODE', 'head').downcase.to_sym
|
15
19
|
@include_virtual = ENV.fetch('MEESEEKER_INCLUDE_VIRTUAL', 'true').downcase == 'true'
|
16
20
|
@include_block_header = ENV.fetch('MEESEEKER_INCLUDE_BLOCK_HEADER', 'true').downcase == 'true'
|
@@ -19,6 +23,6 @@ module Meeseeker
|
|
19
23
|
|
20
24
|
extend self
|
21
25
|
|
22
|
-
attr_accessor :redis, :node_url, :
|
23
|
-
:include_block_header, :publish_op_custom_id
|
26
|
+
attr_accessor :redis, :node_url, :steem_engine_node_url, :expire_keys,
|
27
|
+
:stream_mode, :include_virtual, :include_block_header, :publish_op_custom_id
|
24
28
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'mechanize'
|
2
|
+
|
3
|
+
module Meeseeker::SteemEngine
|
4
|
+
class Agent < Mechanize
|
5
|
+
POST_HEADERS = {
|
6
|
+
'Content-Type' => 'application/json; charset=utf-8',
|
7
|
+
'User-Agent' => Meeseeker::AGENT_ID
|
8
|
+
}
|
9
|
+
|
10
|
+
def initialize(options = {})
|
11
|
+
super
|
12
|
+
|
13
|
+
self.user_agent = Meeseeker::AGENT_ID
|
14
|
+
self.max_history = 0
|
15
|
+
self.default_encoding = 'UTF-8'
|
16
|
+
|
17
|
+
@node_url = options[:url] || Meeseeker::steem_engine_node_url
|
18
|
+
end
|
19
|
+
|
20
|
+
def blockchain_uri
|
21
|
+
@blockchain_uri ||= URI.parse(@node_url + '/blockchain')
|
22
|
+
end
|
23
|
+
|
24
|
+
def blockchain_http_post
|
25
|
+
@http_post ||= Net::HTTP::Post.new(blockchain_uri.request_uri, POST_HEADERS)
|
26
|
+
end
|
27
|
+
|
28
|
+
def latest_block_info
|
29
|
+
request_body = {
|
30
|
+
jsonrpc: "2.0",
|
31
|
+
method: :getLatestBlockInfo,
|
32
|
+
id: rpc_id
|
33
|
+
}.to_json
|
34
|
+
|
35
|
+
response = request_with_entity :post, blockchain_uri, request_body, POST_HEADERS
|
36
|
+
|
37
|
+
JSON[response.body]["result"]
|
38
|
+
end
|
39
|
+
|
40
|
+
def block(block_num)
|
41
|
+
request_body = {
|
42
|
+
jsonrpc: "2.0",
|
43
|
+
method: :getBlockInfo,
|
44
|
+
params: {
|
45
|
+
blockNumber: block_num
|
46
|
+
},
|
47
|
+
id: rpc_id
|
48
|
+
}.to_json
|
49
|
+
|
50
|
+
response = request_with_entity :post, blockchain_uri, request_body, POST_HEADERS
|
51
|
+
|
52
|
+
JSON[response.body]["result"]
|
53
|
+
end
|
54
|
+
private
|
55
|
+
def rpc_id
|
56
|
+
@rpc_id ||= 0
|
57
|
+
@rpc_id = @rpc_id + 1
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
module Meeseeker::SteemEngine
|
2
|
+
class FollowerJob
|
3
|
+
def perform(options = {})
|
4
|
+
redis = Meeseeker.redis
|
5
|
+
last_key_prefix = nil
|
6
|
+
trx_index = 0
|
7
|
+
current_block_num = nil
|
8
|
+
block_transactions = []
|
9
|
+
|
10
|
+
stream_transactions(options) do |transaction, block|
|
11
|
+
begin
|
12
|
+
trx_id = transaction['transactionId'].split('-').first
|
13
|
+
block_num = block['blockNumber']
|
14
|
+
current_key_prefix = "steem_engine:#{block_num}:#{trx_id}"
|
15
|
+
contract = transaction['contract']
|
16
|
+
action = transaction['action']
|
17
|
+
|
18
|
+
if current_key_prefix == last_key_prefix
|
19
|
+
trx_index += 1
|
20
|
+
else
|
21
|
+
if !!last_key_prefix
|
22
|
+
n, b, t = last_key_prefix.split(':')
|
23
|
+
transaction_payload = {
|
24
|
+
block_num: b.to_i,
|
25
|
+
transaction_id: t,
|
26
|
+
transaction_num: block_transactions.size
|
27
|
+
}
|
28
|
+
|
29
|
+
block_transactions << trx_id
|
30
|
+
redis.publish('steem_engine:transaction', transaction_payload.to_json)
|
31
|
+
end
|
32
|
+
|
33
|
+
last_key_prefix = "steem_engine:#{block_num}:#{trx_id}"
|
34
|
+
trx_index = 0
|
35
|
+
end
|
36
|
+
|
37
|
+
key = "#{current_key_prefix}:#{trx_index}:#{contract}:#{action}"
|
38
|
+
puts key
|
39
|
+
end
|
40
|
+
|
41
|
+
redis.set(key, transaction.to_json)
|
42
|
+
redis.expire(key, Meeseeker.expire_keys) unless Meeseeker.expire_keys == -1
|
43
|
+
|
44
|
+
if current_block_num != block_num
|
45
|
+
block_transactions = []
|
46
|
+
block_payload = {
|
47
|
+
block_num: block_num
|
48
|
+
}
|
49
|
+
|
50
|
+
redis.set(Meeseeker::LAST_STEEM_ENGINE_BLOCK_NUM_KEY, block_num)
|
51
|
+
redis.publish('steem_engine:block', block_payload.to_json)
|
52
|
+
current_block_num = block_num
|
53
|
+
end
|
54
|
+
|
55
|
+
redis.publish("steem_engine:#{contract}:#{action}", {key: key}.to_json)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
private
|
59
|
+
def stream_transactions(options = {}, &block)
|
60
|
+
redis = Meeseeker.redis
|
61
|
+
last_block_num = nil
|
62
|
+
agent = Agent.new
|
63
|
+
|
64
|
+
if !!options[:at_block_num]
|
65
|
+
last_block_num = options[:at_block_num].to_i
|
66
|
+
else
|
67
|
+
last_block_num = redis.get(Meeseeker::LAST_STEEM_ENGINE_BLOCK_NUM_KEY).to_i + 1
|
68
|
+
block_info = agent.latest_block_info
|
69
|
+
block_num = block_info['blockNumber']
|
70
|
+
|
71
|
+
last_block = agent.block(last_block_num)
|
72
|
+
last_block_timestamp = Time.parse(last_block['timestamp'] + 'Z')
|
73
|
+
|
74
|
+
if Meeseeker.expire_keys == -1
|
75
|
+
last_block_num = [last_block_num, block_num].max
|
76
|
+
|
77
|
+
puts "Sync Steem Engine from: #{last_block_num}"
|
78
|
+
elsif Time.now.utc - last_block_timestamp > Meeseeker.expire_keys
|
79
|
+
last_block_num = block_num + 1
|
80
|
+
|
81
|
+
puts 'Starting new Steem Engine sync.'
|
82
|
+
else
|
83
|
+
puts "Resuming from Steem Engine block #{last_block_num} ..."
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
block_num = last_block_num
|
88
|
+
|
89
|
+
loop do
|
90
|
+
block = agent.block(block_num)
|
91
|
+
|
92
|
+
if block.nil?
|
93
|
+
sleep 3 # sleep for one mainnet block interval
|
94
|
+
redo
|
95
|
+
end
|
96
|
+
|
97
|
+
transactions = block['transactions']
|
98
|
+
|
99
|
+
transactions.each do |transaction|
|
100
|
+
yield transaction.merge(timestamp: block['timestamp']), block
|
101
|
+
end
|
102
|
+
|
103
|
+
block_num = block_num + 1
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
data/lib/meeseeker/version.rb
CHANGED
data/meeseeker.gemspec
CHANGED
@@ -26,6 +26,7 @@ Gem::Specification.new do |s|
|
|
26
26
|
s.add_development_dependency 'minitest-proveit', '~> 1.0', '>= 1.0.0'
|
27
27
|
s.add_development_dependency 'simplecov', '~> 0.15', '>= 0.15.1'
|
28
28
|
s.add_development_dependency 'pry', '~> 0.11', '>= 0.11.3'
|
29
|
+
s.add_development_dependency 'irb', '~> 1.0', '>= 1.0.0'
|
29
30
|
|
30
31
|
s.add_dependency 'redis', '~> 4.1', '>= 4.1.0'
|
31
32
|
s.add_dependency 'steem-mechanize', '~> 0.0', '>= 0.0.5'
|
@@ -22,6 +22,7 @@ module Meeseeker
|
|
22
22
|
max_blocks = 30 # must be at least 15 to get past irreversible
|
23
23
|
|
24
24
|
assert Rake::Task['verify:block_org'].invoke(max_blocks)
|
25
|
+
assert Rake::Task['verify:steem_engine_block_org'].invoke(max_blocks)
|
25
26
|
assert Rake::Task['verify:witness:schedule'].invoke(max_blocks)
|
26
27
|
|
27
28
|
Rake::Task['reset'].invoke
|
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: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Martin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-03-
|
11
|
+
date: 2019-03-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -130,6 +130,26 @@ dependencies:
|
|
130
130
|
- - ">="
|
131
131
|
- !ruby/object:Gem::Version
|
132
132
|
version: 0.11.3
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: irb
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - "~>"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '1.0'
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 1.0.0
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '1.0'
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 1.0.0
|
133
153
|
- !ruby/object:Gem::Dependency
|
134
154
|
name: redis
|
135
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,6 +227,8 @@ files:
|
|
207
227
|
- bin/meeseeker
|
208
228
|
- lib/meeseeker.rb
|
209
229
|
- lib/meeseeker/block_follower_job.rb
|
230
|
+
- lib/meeseeker/steem_engine/agent.rb
|
231
|
+
- lib/meeseeker/steem_engine/follower_job.rb
|
210
232
|
- lib/meeseeker/version.rb
|
211
233
|
- lib/meeseeker/witness_schedule_job.rb
|
212
234
|
- meeseeker.gemspec
|