peerplays-ruby 1.0.0.pre.1 → 1.0.0.pre.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +76 -4
- data/Rakefile +97 -0
- data/lib/peerplays.rb +8 -0
- data/lib/peerplays/operation.rb +132 -0
- data/lib/peerplays/stream.rb +304 -0
- data/lib/peerplays/version.rb +1 -1
- metadata +8 -8
- data/Gemfile.lock +0 -84
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f854fa06f98effe1539d5c5dff3f4777275f771f395b17476207c9e98df07ecf
|
4
|
+
data.tar.gz: 9a2e1a64849d887d0b772a9719ff70483caea5bca7205c6d652382b52f96f13d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a1b688fa1f02a212b520f91e856b80f4973410e3da568e07b3a07738c11618818ee01db7485732f352287d596374c09b8033883f6511594b952cee41da278688
|
7
|
+
data.tar.gz: ce0ccbe319ce3e3289b624ee0db760369486f52c8221df41e18df3ae44ea778682e750e50866fdfa67b074dfb4a075864eff9e478ddf7eeaad813125ceb590e4
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -28,7 +28,7 @@ To add the gem as a dependency to your project with [Bundler](http://bundler.io/
|
|
28
28
|
gem 'peerplays-ruby', require: 'peerplays'
|
29
29
|
```
|
30
30
|
|
31
|
-
|
31
|
+
## Get Accounts
|
32
32
|
|
33
33
|
```ruby
|
34
34
|
require 'peerplays'
|
@@ -42,7 +42,7 @@ api.get_accounts(['init1']) do |result|
|
|
42
42
|
end
|
43
43
|
```
|
44
44
|
|
45
|
-
|
45
|
+
## Set API Node
|
46
46
|
|
47
47
|
To set an alternative node, pass it as an argument, e.g.:
|
48
48
|
|
@@ -50,14 +50,86 @@ To set an alternative node, pass it as an argument, e.g.:
|
|
50
50
|
api = Peerplays::DatabaseApi.new(url: 'wss://ppyws.roelandp.nl/ws')
|
51
51
|
```
|
52
52
|
|
53
|
-
|
53
|
+
## Streaming
|
54
|
+
|
55
|
+
To start a stream from the last irreversible block:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
stream = Peerplays::Stream.new
|
59
|
+
|
60
|
+
stream.operations do |op_type, op_value|
|
61
|
+
puts "#{op_type}: #{op_value}"
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
To start a stream from the head block:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
stream = Peerplays::Stream.new(mode: :head)
|
69
|
+
|
70
|
+
stream.operations do |op_type, op_value|
|
71
|
+
puts "#{op_type}: #{op_value}"
|
72
|
+
end
|
73
|
+
```
|
74
|
+
|
75
|
+
To start a stream from a specific block number, pass it as an argument:
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
stream = Peerplays::Stream.new
|
79
|
+
|
80
|
+
stream.operations(at_block_num: 9001) do |op_type, op_value|
|
81
|
+
puts "#{op_type}: #{op_value}"
|
82
|
+
end
|
83
|
+
```
|
84
|
+
|
85
|
+
You can also grab the related block number for each operation:
|
86
|
+
|
87
|
+
```ruby
|
88
|
+
stream = Peerplays::Stream.new
|
89
|
+
|
90
|
+
stream.operations do |op_type, op_value, block_num|
|
91
|
+
puts "#{block_num} :: #{op_type}: #{op_value}"
|
92
|
+
end
|
93
|
+
```
|
94
|
+
|
95
|
+
To stream only certain operations:
|
96
|
+
|
97
|
+
```ruby
|
98
|
+
stream = Peerplays::Stream.new
|
99
|
+
|
100
|
+
stream.operations(types: :transfer) do |op_type, op_value|
|
101
|
+
puts "#{op_type}: #{op_value}"
|
102
|
+
end
|
103
|
+
```
|
104
|
+
|
105
|
+
Or pass an array of certain operations:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
stream = Peerplays::Stream.new
|
109
|
+
|
110
|
+
stream.operations(types: [:account_create, :account_update]) do |op_type, op_value|
|
111
|
+
puts "#{op_type}: #{op_value}"
|
112
|
+
end
|
113
|
+
```
|
114
|
+
|
115
|
+
Or (optionally) just pass the operation(s) you want as the only arguments. This is semantic sugar for when you want specific types and take all of the defaults.
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
stream = Peerplays::Stream.new
|
119
|
+
|
120
|
+
stream.operations(:transfer) do |op_type, op_value|
|
121
|
+
puts "#{op_type}: #{op_value}"
|
122
|
+
end
|
123
|
+
```
|
124
|
+
|
125
|
+
## Reference
|
54
126
|
|
55
127
|
For lists of available methods provided by this gem:
|
56
128
|
|
57
129
|
* https://www.peerplays.tech/api/peerplays-core-api
|
58
130
|
* https://www.peerplays.tech/api/peerplays-wallet-api
|
59
131
|
|
60
|
-
|
132
|
+
## Tests
|
61
133
|
|
62
134
|
* Clone the client repository into a directory of your choice:
|
63
135
|
* `git clone git@gitlab.com:PBSA/PeerplaysIO/tools-libs/ruby-peerplays.git`
|
data/Rakefile
CHANGED
@@ -2,6 +2,7 @@ require 'bundler/gem_tasks'
|
|
2
2
|
require 'rake/testtask'
|
3
3
|
require 'yard'
|
4
4
|
require 'peerplays'
|
5
|
+
require 'time'
|
5
6
|
|
6
7
|
Rake::TestTask.new(:test) do |t|
|
7
8
|
t.libs << 'test'
|
@@ -24,3 +25,99 @@ desc 'Ruby console with peerplays already required.'
|
|
24
25
|
task :console do
|
25
26
|
exec 'irb -r peerplays -r awesome_print -I ./lib'
|
26
27
|
end
|
28
|
+
|
29
|
+
namespace :stream do
|
30
|
+
desc 'Test the ability to stream a block range.'
|
31
|
+
task :block_range, [:mode, :at_block_num] do |t, args|
|
32
|
+
mode = (args[:mode] || 'irreversible').to_sym
|
33
|
+
first_block_num = args[:at_block_num].to_i if !!args[:at_block_num]
|
34
|
+
stream = Peerplays::Stream.new(url: ENV['TEST_NODE'], mode: mode)
|
35
|
+
api = Peerplays::DatabaseApi.new(url: ENV['TEST_NODE'])
|
36
|
+
last_block_num = nil
|
37
|
+
last_timestamp = nil
|
38
|
+
range_complete = false
|
39
|
+
|
40
|
+
api.get_dynamic_global_properties do |properties|
|
41
|
+
current_block_num = if mode == :head
|
42
|
+
properties.head_block_number
|
43
|
+
else
|
44
|
+
properties.last_irreversible_block_num
|
45
|
+
end
|
46
|
+
|
47
|
+
# First pass replays latest a random number of blocks to test chunking.
|
48
|
+
first_block_num ||= current_block_num - (rand * 200).to_i
|
49
|
+
|
50
|
+
range = first_block_num..current_block_num
|
51
|
+
puts "Initial block range: #{range.size}"
|
52
|
+
|
53
|
+
stream.blocks(at_block_num: range.first) do |block, block_num|
|
54
|
+
current_timestamp = Time.parse(block.timestamp + 'Z')
|
55
|
+
|
56
|
+
if !range_complete && block_num > range.last
|
57
|
+
puts 'Done with initial range.'
|
58
|
+
range_complete = true
|
59
|
+
end
|
60
|
+
|
61
|
+
if !!last_timestamp && block_num != last_block_num + 1
|
62
|
+
puts "Bug: Last block number was #{last_block_num} then jumped to: #{block_num}"
|
63
|
+
exit
|
64
|
+
end
|
65
|
+
|
66
|
+
if !!last_timestamp && current_timestamp < last_timestamp
|
67
|
+
puts "Bug: Went back in time. Last timestamp was #{last_timestamp}, then jumped back to #{current_timestamp}"
|
68
|
+
exit
|
69
|
+
end
|
70
|
+
|
71
|
+
puts "\t#{block_num} Timestamp: #{current_timestamp}, witness: #{block.witness}"
|
72
|
+
last_block_num = block_num
|
73
|
+
last_timestamp = current_timestamp
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
desc 'Test the ability to stream a block range of transactions.'
|
79
|
+
task :trx_range, [:mode, :at_block_num] do |t, args|
|
80
|
+
mode = (args[:mode] || 'irreversible').to_sym
|
81
|
+
first_block_num = args[:at_block_num].to_i if !!args[:at_block_num]
|
82
|
+
stream = Peerplays::Stream.new(url: ENV['TEST_NODE'], mode: mode)
|
83
|
+
api = Peerplays::DatabaseApi.new(url: ENV['TEST_NODE'])
|
84
|
+
|
85
|
+
api.get_dynamic_global_properties do |properties|
|
86
|
+
current_block_num = if mode == :head
|
87
|
+
properties.head_block_number
|
88
|
+
else
|
89
|
+
properties.last_irreversible_block_num
|
90
|
+
end
|
91
|
+
|
92
|
+
# First pass replays latest a random number of blocks to test chunking.
|
93
|
+
first_block_num ||= current_block_num - (rand * 200).to_i
|
94
|
+
|
95
|
+
stream.transactions(at_block_num: first_block_num) do |trx, block_num|
|
96
|
+
puts "#{block_num} :: ops: #{trx.operations.map{|op| Peerplays::Operation::IDS[op[0]]}.join(', ')}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
desc 'Test the ability to stream a block range of operations.'
|
102
|
+
task :op_range, [:mode, :at_block_num] do |t, args|
|
103
|
+
mode = (args[:mode] || 'irreversible').to_sym
|
104
|
+
first_block_num = args[:at_block_num].to_i if !!args[:at_block_num]
|
105
|
+
stream = Peerplays::Stream.new(url: ENV['TEST_NODE'], mode: mode)
|
106
|
+
api = Peerplays::DatabaseApi.new(url: ENV['TEST_NODE'])
|
107
|
+
|
108
|
+
api.get_dynamic_global_properties do |properties|
|
109
|
+
current_block_num = if mode == :head
|
110
|
+
properties.head_block_number
|
111
|
+
else
|
112
|
+
properties.last_irreversible_block_num
|
113
|
+
end
|
114
|
+
|
115
|
+
# First pass replays latest a random number of blocks to test chunking.
|
116
|
+
first_block_num ||= current_block_num - (rand * 200).to_i
|
117
|
+
|
118
|
+
stream.operations(at_block_num: first_block_num) do |op_type, op_value, block_num|
|
119
|
+
puts "#{block_num} :: op: #{op_type}"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
data/lib/peerplays.rb
CHANGED
@@ -16,6 +16,14 @@ require 'peerplays/network_broadcast_api'
|
|
16
16
|
require 'peerplays/network_node_api'
|
17
17
|
require 'peerplays/orders_api'
|
18
18
|
require 'peerplays/wallet_api'
|
19
|
+
require 'peerplays/stream'
|
20
|
+
require 'peerplays/utils'
|
21
|
+
require 'peerplays/mixins/jsonable'
|
22
|
+
require 'peerplays/mixins/serializable'
|
23
|
+
require 'peerplays/operation'
|
24
|
+
require 'peerplays/operation/transfer'
|
25
|
+
require 'peerplays/transaction'
|
26
|
+
require 'peerplays/transaction_builder'
|
19
27
|
|
20
28
|
module Peerplays
|
21
29
|
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
module Peerplays
|
2
|
+
class Operation
|
3
|
+
include JSONable
|
4
|
+
include Serializable
|
5
|
+
include Utils
|
6
|
+
|
7
|
+
# IDs derrived from:
|
8
|
+
# https://gitlab.com/PBSA/peerplays/-/blob/master/libraries/chain/include/graphene/chain/protocol/operations.hpp#L57-138
|
9
|
+
|
10
|
+
IDS = [
|
11
|
+
:transfer_operation,
|
12
|
+
:limit_order_create_operation,
|
13
|
+
:limit_order_cancel_operation,
|
14
|
+
:call_order_update_operation,
|
15
|
+
:fill_order_operation, # VIRTUAL
|
16
|
+
:account_create_operation,
|
17
|
+
:account_update_operation,
|
18
|
+
:account_whitelist_operation,
|
19
|
+
:account_upgrade_operation,
|
20
|
+
:account_transfer_operation,
|
21
|
+
:asset_create_operation,
|
22
|
+
:asset_update_operation,
|
23
|
+
:asset_update_bitasset_operation,
|
24
|
+
:asset_update_feed_producers_operation,
|
25
|
+
:asset_issue_operation,
|
26
|
+
:asset_reserve_operation,
|
27
|
+
:asset_fund_fee_pool_operation,
|
28
|
+
:asset_settle_operation,
|
29
|
+
:asset_global_settle_operation,
|
30
|
+
:asset_publish_feed_operation,
|
31
|
+
:witness_create_operation,
|
32
|
+
:witness_update_operation,
|
33
|
+
:proposal_create_operation,
|
34
|
+
:proposal_update_operation,
|
35
|
+
:proposal_delete_operation,
|
36
|
+
:withdraw_permission_create_operation,
|
37
|
+
:withdraw_permission_update_operation,
|
38
|
+
:withdraw_permission_claim_operation,
|
39
|
+
:withdraw_permission_delete_operation,
|
40
|
+
:committee_member_create_operation,
|
41
|
+
:committee_member_update_operation,
|
42
|
+
:committee_member_update_global_parameters_operation,
|
43
|
+
:vesting_balance_create_operation,
|
44
|
+
:vesting_balance_withdraw_operation,
|
45
|
+
:worker_create_operation,
|
46
|
+
:custom_operation,
|
47
|
+
:assert_operation,
|
48
|
+
:balance_claim_operation,
|
49
|
+
:override_transfer_operation,
|
50
|
+
:transfer_to_blind_operation,
|
51
|
+
:blind_transfer_operation,
|
52
|
+
:transfer_from_blind_operation,
|
53
|
+
:asset_settle_cancel_operation, # VIRTUAL
|
54
|
+
:asset_claim_fees_operation,
|
55
|
+
:fba_distribute_operation, # VIRTUAL
|
56
|
+
:tournament_create_operation,
|
57
|
+
:tournament_join_operation,
|
58
|
+
:game_move_operation,
|
59
|
+
:asset_update_dividend_operation,
|
60
|
+
:asset_dividend_distribution_operation, # VIRTUAL
|
61
|
+
:tournament_payout_operation, # VIRTUAL
|
62
|
+
:tournament_leave_operation,
|
63
|
+
:sport_create_operation,
|
64
|
+
:sport_update_operation,
|
65
|
+
:event_group_create_operation,
|
66
|
+
:event_group_update_operation,
|
67
|
+
:event_create_operation,
|
68
|
+
:event_update_operation,
|
69
|
+
:betting_market_rules_create_operation,
|
70
|
+
:betting_market_rules_update_operation,
|
71
|
+
:betting_market_group_create_operation,
|
72
|
+
:betting_market_create_operation,
|
73
|
+
:bet_place_operation,
|
74
|
+
:betting_market_group_resolve_operation,
|
75
|
+
:betting_market_group_resolved_operation, # VIRTUAL
|
76
|
+
:bet_adjusted_operation, # VIRTUAL
|
77
|
+
:betting_market_group_cancel_unmatched_bets_operation,
|
78
|
+
:bet_matched_operation, # VIRTUAL
|
79
|
+
:bet_cancel_operation,
|
80
|
+
:bet_canceled_operation, # VIRTUAL
|
81
|
+
:betting_market_group_update_operation,
|
82
|
+
:betting_market_update_operation,
|
83
|
+
:event_update_status_operation,
|
84
|
+
:sport_delete_operation,
|
85
|
+
:event_group_delete_operation,
|
86
|
+
:affiliate_payout_operation, # VIRTUAL
|
87
|
+
:affiliate_referral_payout_operation, # VIRTUAL
|
88
|
+
:lottery_asset_create_operation,
|
89
|
+
:ticket_purchase_operation,
|
90
|
+
:lottery_reward_operation,
|
91
|
+
:lottery_end_operation,
|
92
|
+
:sweeps_vesting_claim_operation
|
93
|
+
]
|
94
|
+
|
95
|
+
def self.op_id(op)
|
96
|
+
IDS.find_index op
|
97
|
+
end
|
98
|
+
|
99
|
+
def inspect
|
100
|
+
properties = self.class.attributes.map do |prop|
|
101
|
+
unless (v = instance_variable_get("@#{prop}")).nil?
|
102
|
+
v = if v.respond_to? :strftime
|
103
|
+
v.strftime('%Y-%m-%dT%H:%M:%S')
|
104
|
+
else
|
105
|
+
v
|
106
|
+
end
|
107
|
+
|
108
|
+
"@#{prop}=#{v}"
|
109
|
+
end
|
110
|
+
end.compact.join(', ')
|
111
|
+
|
112
|
+
"#<#{self.class.name} [#{properties}]>"
|
113
|
+
end
|
114
|
+
|
115
|
+
def [](key)
|
116
|
+
key = key.to_sym
|
117
|
+
send(key) if self.class.attributes.include?(key)
|
118
|
+
end
|
119
|
+
|
120
|
+
def []=(key, value)
|
121
|
+
key = key.to_sym
|
122
|
+
|
123
|
+
if self.class.attributes.include?(key)
|
124
|
+
if self.class.numeric? key
|
125
|
+
send("#{key}=", value.to_i)
|
126
|
+
else
|
127
|
+
send("#{key}=", value)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,304 @@
|
|
1
|
+
module Peerplays
|
2
|
+
# Peerplays::Stream allows a live view of the Peerplays blockchain.
|
3
|
+
#
|
4
|
+
# Example streaming blocks:
|
5
|
+
#
|
6
|
+
# stream = Peerplays::Stream.new
|
7
|
+
#
|
8
|
+
# stream.blocks do |block, block_num|
|
9
|
+
# puts "#{block_num} :: #{block.witness}"
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# Example streaming transactions:
|
13
|
+
#
|
14
|
+
# stream = Peerplays::Stream.new
|
15
|
+
#
|
16
|
+
# stream.transactions do |trx, block_num|
|
17
|
+
# puts "#{block_num} :: operations: #{trx.operations.size}"
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# Example streaming operations:
|
21
|
+
#
|
22
|
+
# stream = Peerplays::Stream.new
|
23
|
+
#
|
24
|
+
# stream.operations do |op, block_num|
|
25
|
+
# puts "#{block_num} :: #{op.type}: #{op.value.to_json}"
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# Allows streaming of block headers, full blocks, transactions, operations.
|
29
|
+
class Stream
|
30
|
+
attr_reader :mode
|
31
|
+
|
32
|
+
BLOCK_INTERVAL = 3
|
33
|
+
MAX_BACKOFF_BLOCK_INTERVAL = 30
|
34
|
+
MAX_RETRY_COUNT = 10
|
35
|
+
|
36
|
+
# @param options [Hash] additional options
|
37
|
+
# @option options [Symbol] :mode we have the choice between
|
38
|
+
# * :head the last block
|
39
|
+
# * :irreversible the block that is confirmed by 2/3 of all block producers and is thus irreversible!
|
40
|
+
def initialize(options = {mode: :irreversible})
|
41
|
+
@instance_options = options
|
42
|
+
@mode = options[:mode] || :irreversible
|
43
|
+
end
|
44
|
+
|
45
|
+
# Use this method to stream block numbers. This is significantly faster
|
46
|
+
# than requesting full blocks and even block headers. Basically, the only
|
47
|
+
# thing this method does is call {Peerplays::Database#get_dynamic_global_properties} at 3 second
|
48
|
+
# intervals.
|
49
|
+
#
|
50
|
+
# @param options [Hash] additional options
|
51
|
+
# @option options [Integer] :at_block_num Starts the stream at the given block number. Default: nil.
|
52
|
+
# @option options [Integer] :until_block_num Ends the stream at the given block number. Default: nil.
|
53
|
+
def block_numbers(options = {}, &block)
|
54
|
+
block_objects(options.merge(object: :block_numbers), block)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Use this method to stream block headers. This is quite a bit faster than
|
58
|
+
# requesting full blocks.
|
59
|
+
#
|
60
|
+
# @param options [Hash] additional options
|
61
|
+
# @option options [Integer] :at_block_num Starts the stream at the given block number. Default: nil.
|
62
|
+
# @option options [Integer] :until_block_num Ends the stream at the given block number. Default: nil.
|
63
|
+
def block_headers(options = {}, &block)
|
64
|
+
block_objects(options.merge(object: :block_header), block)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Use this method to stream full blocks.
|
68
|
+
#
|
69
|
+
# @param options [Hash] additional options
|
70
|
+
# @option options [Integer] :at_block_num Starts the stream at the given block number. Default: nil.
|
71
|
+
# @option options [Integer] :until_block_num Ends the stream at the given block number. Default: nil.
|
72
|
+
def blocks(options = {}, &block)
|
73
|
+
block_objects(options.merge(object: :block), block)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Use this method to stream each transaction.
|
77
|
+
#
|
78
|
+
# @param options [Hash] additional options
|
79
|
+
# @option options [Integer] :at_block_num Starts the stream at the given block number. Default: nil.
|
80
|
+
# @option options [Integer] :until_block_num Ends the stream at the given block number. Default: nil.
|
81
|
+
def transactions(options = {}, &block)
|
82
|
+
blocks(options) do |block, block_num|
|
83
|
+
block.transactions.each_with_index do |transaction, index|
|
84
|
+
yield transaction, block_num
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
# Returns the latest operations from the blockchain.
|
90
|
+
#
|
91
|
+
# stream = Peerplays::Stream.new
|
92
|
+
# stream.operations do |op|
|
93
|
+
# puts op.to_json
|
94
|
+
# end
|
95
|
+
#
|
96
|
+
# If symbol are passed to `types` option, then only that operation is
|
97
|
+
# returned. Expected symbols are:
|
98
|
+
#
|
99
|
+
# :transfer_operation
|
100
|
+
# :limit_order_create_operation
|
101
|
+
# :limit_order_cancel_operation
|
102
|
+
# :call_order_update_operation
|
103
|
+
# :fill_order_operation # VIRTUAL
|
104
|
+
# :account_create_operation
|
105
|
+
# :account_update_operation
|
106
|
+
# :account_whitelist_operation
|
107
|
+
# :account_upgrade_operation
|
108
|
+
# :account_transfer_operation
|
109
|
+
# :asset_create_operation
|
110
|
+
# :asset_update_operation
|
111
|
+
# :asset_update_bitasset_operation
|
112
|
+
# :asset_update_feed_producers_operation
|
113
|
+
# :asset_issue_operation
|
114
|
+
# :asset_reserve_operation
|
115
|
+
# :asset_fund_fee_pool_operation
|
116
|
+
# :asset_settle_operation
|
117
|
+
# :asset_global_settle_operation
|
118
|
+
# :asset_publish_feed_operation
|
119
|
+
# :witness_create_operation
|
120
|
+
# :witness_update_operation
|
121
|
+
# :proposal_create_operation
|
122
|
+
# :proposal_update_operation
|
123
|
+
# :proposal_delete_operation
|
124
|
+
# :withdraw_permission_create_operation
|
125
|
+
# :withdraw_permission_update_operation
|
126
|
+
# :withdraw_permission_claim_operation
|
127
|
+
# :withdraw_permission_delete_operation
|
128
|
+
# :committee_member_create_operation
|
129
|
+
# :committee_member_update_operation
|
130
|
+
# :committee_member_update_global_parameters_operation
|
131
|
+
# :vesting_balance_create_operation
|
132
|
+
# :vesting_balance_withdraw_operation
|
133
|
+
# :worker_create_operation
|
134
|
+
# :custom_operation
|
135
|
+
# :assert_operation
|
136
|
+
# :balance_claim_operation
|
137
|
+
# :override_transfer_operation
|
138
|
+
# :transfer_to_blind_operation
|
139
|
+
# :blind_transfer_operation
|
140
|
+
# :transfer_from_blind_operation
|
141
|
+
# :asset_settle_cancel_operation # VIRTUAL
|
142
|
+
# :asset_claim_fees_operation
|
143
|
+
# :fba_distribute_operation # VIRTUAL
|
144
|
+
# :tournament_create_operation
|
145
|
+
# :tournament_join_operation
|
146
|
+
# :game_move_operation
|
147
|
+
# :asset_update_dividend_operation
|
148
|
+
# :asset_dividend_distribution_operation # VIRTUAL
|
149
|
+
# :tournament_payout_operation # VIRTUAL
|
150
|
+
# :tournament_leave_operation
|
151
|
+
# :sport_create_operation
|
152
|
+
# :sport_update_operation
|
153
|
+
# :event_group_create_operation
|
154
|
+
# :event_group_update_operation
|
155
|
+
# :event_create_operation
|
156
|
+
# :event_update_operation
|
157
|
+
# :betting_market_rules_create_operation
|
158
|
+
# :betting_market_rules_update_operation
|
159
|
+
# :betting_market_group_create_operation
|
160
|
+
# :betting_market_create_operation
|
161
|
+
# :bet_place_operation
|
162
|
+
# :betting_market_group_resolve_operation
|
163
|
+
# :betting_market_group_resolved_operation # VIRTUAL
|
164
|
+
# :bet_adjusted_operation # VIRTUAL
|
165
|
+
# :betting_market_group_cancel_unmatched_bets_operation
|
166
|
+
# :bet_matched_operation # VIRTUAL
|
167
|
+
# :bet_cancel_operation
|
168
|
+
# :bet_canceled_operation # VIRTUAL
|
169
|
+
# :betting_market_group_update_operation
|
170
|
+
# :betting_market_update_operation
|
171
|
+
# :event_update_status_operation
|
172
|
+
# :sport_delete_operation
|
173
|
+
# :event_group_delete_operation
|
174
|
+
# :affiliate_payout_operation # VIRTUAL
|
175
|
+
# :affiliate_referral_payout_operation # VIRTUAL
|
176
|
+
# :lottery_asset_create_operation
|
177
|
+
# :ticket_purchase_operation
|
178
|
+
# :lottery_reward_operation
|
179
|
+
# :lottery_end_operation
|
180
|
+
# :sweeps_vesting_claim_operation
|
181
|
+
#
|
182
|
+
# For example, to stream only transfers:
|
183
|
+
#
|
184
|
+
# stream = Peerplays::Stream.new
|
185
|
+
# stream.operations(types: :transfer) do |_, transfer|
|
186
|
+
# puts transfer.to_json
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# ... Or ...
|
190
|
+
#
|
191
|
+
# stream = Peerplays::Stream.new
|
192
|
+
# stream.operations(:transfer) do |_, transfer|
|
193
|
+
# puts transfer.to_json
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
# @param args [Symbol || Array<Symbol> || Hash] the type(s) of operation or hash of expanded options, optional.
|
197
|
+
# @option args [Integer] :at_block_num Starts the stream at the given block number. Default: nil.
|
198
|
+
# @option args [Integer] :until_block_num Ends the stream at the given block number. Default: nil.
|
199
|
+
# @option args [Symbol || Array<Symbol>] :types the type(s) of operation, optional.
|
200
|
+
# @param block the block to execute for each result. Yields: |type_type, op_value, block_num|
|
201
|
+
def operations(*args, &block)
|
202
|
+
options = {}
|
203
|
+
types = []
|
204
|
+
last_block_num = nil
|
205
|
+
|
206
|
+
case args.first
|
207
|
+
when Hash
|
208
|
+
options = args.first
|
209
|
+
types = transform_types(options[:types])
|
210
|
+
when Symbol, Array then types = transform_types(args)
|
211
|
+
end
|
212
|
+
|
213
|
+
transactions(options) do |transaction, block_num|
|
214
|
+
transaction.operations.each do |type, value|
|
215
|
+
type = Operation::IDS[type]
|
216
|
+
|
217
|
+
yield type, value, block_num if types.none? || types.include?(type)
|
218
|
+
|
219
|
+
next unless last_block_num != block_num
|
220
|
+
|
221
|
+
last_block_num = block_num
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
private
|
226
|
+
# @private
|
227
|
+
def block_objects(options = {}, block)
|
228
|
+
object = options[:object]
|
229
|
+
object_method = "get_#{object}".to_sym
|
230
|
+
block_interval = BLOCK_INTERVAL
|
231
|
+
|
232
|
+
at_block_num, until_block_num = if !!block_range = options[:block_range]
|
233
|
+
[block_range.first, block_range.last]
|
234
|
+
else
|
235
|
+
[options[:at_block_num], options[:until_block_num]]
|
236
|
+
end
|
237
|
+
|
238
|
+
loop do
|
239
|
+
break if !!until_block_num && !!at_block_num && until_block_num < at_block_num
|
240
|
+
|
241
|
+
database_api.get_dynamic_global_properties do |properties|
|
242
|
+
current_block_num = find_block_number(properties)
|
243
|
+
current_block_num = [current_block_num, until_block_num].compact.min
|
244
|
+
at_block_num ||= current_block_num
|
245
|
+
|
246
|
+
if current_block_num >= at_block_num
|
247
|
+
range = at_block_num..current_block_num
|
248
|
+
|
249
|
+
if object == :block_numbers
|
250
|
+
range.each do |n|
|
251
|
+
block.call n
|
252
|
+
block_interval = BLOCK_INTERVAL
|
253
|
+
end
|
254
|
+
else
|
255
|
+
range.each do |block_num|
|
256
|
+
database_api.send(object_method, block_num) do |b|
|
257
|
+
block.call b, block_num
|
258
|
+
block_interval = BLOCK_INTERVAL
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
at_block_num = range.max + 1
|
264
|
+
else
|
265
|
+
# The stream has stalled, so let's back off and let the node sync
|
266
|
+
# up. We'll catch up with a bigger batch in the next cycle.
|
267
|
+
block_interval = [block_interval * 2, MAX_BACKOFF_BLOCK_INTERVAL].min
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
sleep block_interval
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
# @private
|
276
|
+
def find_block_number(properties)
|
277
|
+
block_num = case mode.to_sym
|
278
|
+
when :head then properties.head_block_number
|
279
|
+
when :irreversible then properties.last_irreversible_block_num
|
280
|
+
else; raise ArgumentError, "Unknown mode: #{mode}"
|
281
|
+
end
|
282
|
+
|
283
|
+
block_num
|
284
|
+
end
|
285
|
+
|
286
|
+
# @private
|
287
|
+
def transform_types(types)
|
288
|
+
[types].compact.flatten.map do |type|
|
289
|
+
type = type.to_s
|
290
|
+
|
291
|
+
unless type.end_with? '_operation'
|
292
|
+
type += '_operation'
|
293
|
+
end
|
294
|
+
|
295
|
+
type.to_sym
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# @private
|
300
|
+
def database_api
|
301
|
+
@database_api ||= DatabaseApi.new(@instance_options)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
data/lib/peerplays/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: peerplays-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.pre.
|
4
|
+
version: 1.0.0.pre.2
|
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-06-
|
11
|
+
date: 2020-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -379,7 +379,6 @@ extra_rdoc_files: []
|
|
379
379
|
files:
|
380
380
|
- ".gitignore"
|
381
381
|
- Gemfile
|
382
|
-
- Gemfile.lock
|
383
382
|
- LICENSE.txt
|
384
383
|
- README.md
|
385
384
|
- Rakefile
|
@@ -394,7 +393,9 @@ files:
|
|
394
393
|
- lib/peerplays/history_api.rb
|
395
394
|
- lib/peerplays/network_broadcast_api.rb
|
396
395
|
- lib/peerplays/network_node_api.rb
|
396
|
+
- lib/peerplays/operation.rb
|
397
397
|
- lib/peerplays/orders_api.rb
|
398
|
+
- lib/peerplays/stream.rb
|
398
399
|
- lib/peerplays/version.rb
|
399
400
|
- lib/peerplays/wallet_api.rb
|
400
401
|
- peerplays-ruby.gemspec
|
@@ -402,7 +403,7 @@ homepage: https://gitlab.com/PBSA/PeerplaysIO/tools-libs/ruby-peerplays
|
|
402
403
|
licenses:
|
403
404
|
- MIT
|
404
405
|
metadata: {}
|
405
|
-
post_install_message:
|
406
|
+
post_install_message:
|
406
407
|
rdoc_options: []
|
407
408
|
require_paths:
|
408
409
|
- lib
|
@@ -417,9 +418,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
417
418
|
- !ruby/object:Gem::Version
|
418
419
|
version: 1.3.1
|
419
420
|
requirements: []
|
420
|
-
|
421
|
-
|
422
|
-
signing_key:
|
421
|
+
rubygems_version: 3.0.8
|
422
|
+
signing_key:
|
423
423
|
specification_version: 4
|
424
424
|
summary: Peerplays Ruby Client
|
425
425
|
test_files: []
|
data/Gemfile.lock
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
peerplays-ruby (1.0.0.pre.1)
|
5
|
-
base58 (~> 0.2, >= 0.2.3)
|
6
|
-
bindata (~> 2.4, >= 2.4.4)
|
7
|
-
bitcoin-ruby (~> 0.0, >= 0.0.18)
|
8
|
-
faye-websocket (~> 0.10, >= 0.10.9)
|
9
|
-
ffi (~> 1.13, >= 1.9.23)
|
10
|
-
hashie (~> 4.1, >= 3.5.7)
|
11
|
-
json (~> 2.3, >= 2.1.0)
|
12
|
-
logging (~> 2.2, >= 2.2.0)
|
13
|
-
|
14
|
-
GEM
|
15
|
-
remote: https://rubygems.org/
|
16
|
-
specs:
|
17
|
-
awesome_print (1.8.0)
|
18
|
-
base58 (0.2.3)
|
19
|
-
bindata (2.4.7)
|
20
|
-
bitcoin-ruby (0.0.20)
|
21
|
-
eventmachine
|
22
|
-
ffi
|
23
|
-
scrypt
|
24
|
-
coderay (1.1.3)
|
25
|
-
docile (1.3.2)
|
26
|
-
eventmachine (1.2.7)
|
27
|
-
faye-websocket (0.10.9)
|
28
|
-
eventmachine (>= 0.12.0)
|
29
|
-
websocket-driver (>= 0.5.1)
|
30
|
-
ffi (1.13.1)
|
31
|
-
ffi-compiler (1.0.1)
|
32
|
-
ffi (>= 1.0.0)
|
33
|
-
rake
|
34
|
-
hashie (4.1.0)
|
35
|
-
io-console (0.5.6)
|
36
|
-
irb (1.2.4)
|
37
|
-
reline (>= 0.0.1)
|
38
|
-
json (2.3.0)
|
39
|
-
little-plugger (1.1.4)
|
40
|
-
logging (2.2.2)
|
41
|
-
little-plugger (~> 1.1)
|
42
|
-
multi_json (~> 1.10)
|
43
|
-
method_source (1.0.0)
|
44
|
-
minitest (5.14.1)
|
45
|
-
minitest-line (0.6.5)
|
46
|
-
minitest (~> 5.0)
|
47
|
-
minitest-proveit (1.0.0)
|
48
|
-
minitest (> 5, < 7)
|
49
|
-
multi_json (1.14.1)
|
50
|
-
pry (0.13.1)
|
51
|
-
coderay (~> 1.1)
|
52
|
-
method_source (~> 1.0)
|
53
|
-
rake (13.0.1)
|
54
|
-
reline (0.1.4)
|
55
|
-
io-console (~> 0.5)
|
56
|
-
scrypt (3.0.7)
|
57
|
-
ffi-compiler (>= 1.0, < 2.0)
|
58
|
-
simplecov (0.18.5)
|
59
|
-
docile (~> 1.1)
|
60
|
-
simplecov-html (~> 0.11)
|
61
|
-
simplecov-html (0.12.2)
|
62
|
-
websocket-driver (0.7.2)
|
63
|
-
websocket-extensions (>= 0.1.0)
|
64
|
-
websocket-extensions (0.1.5)
|
65
|
-
yard (0.9.25)
|
66
|
-
|
67
|
-
PLATFORMS
|
68
|
-
ruby
|
69
|
-
|
70
|
-
DEPENDENCIES
|
71
|
-
awesome_print (~> 1.8, >= 1.8.0)
|
72
|
-
bundler (~> 2.1, >= 1.16.1)
|
73
|
-
irb (~> 1.2, >= 1.2.3)
|
74
|
-
minitest (~> 5.14, >= 5.10.3)
|
75
|
-
minitest-line (~> 0.6, >= 0.6.4)
|
76
|
-
minitest-proveit (~> 1.0, >= 1.0.0)
|
77
|
-
peerplays-ruby!
|
78
|
-
pry (~> 0.13, >= 0.11.3)
|
79
|
-
rake (~> 13.0, >= 12.3.0)
|
80
|
-
simplecov (~> 0.18, >= 0.15.1)
|
81
|
-
yard (~> 0.9, >= 0.9.12)
|
82
|
-
|
83
|
-
BUNDLED WITH
|
84
|
-
2.1.4
|