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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 35a78c6fb3c7f210ce43680547d1ab2174183762428a948164be64e9c6f69ddb
4
- data.tar.gz: 40afb1e1d97f39a3e6094c4c45534df8b91108d7e611138a1c78d396dd0ee634
3
+ metadata.gz: f854fa06f98effe1539d5c5dff3f4777275f771f395b17476207c9e98df07ecf
4
+ data.tar.gz: 9a2e1a64849d887d0b772a9719ff70483caea5bca7205c6d652382b52f96f13d
5
5
  SHA512:
6
- metadata.gz: 2554955eeb96fd7833b79e4c77f7d83eac3390f8f9faf37cdaf98ea24dfca402eb0b2d98e6fe551f4703bb3d1146bcd06ade5866f95eca3d921ee19266e414ee
7
- data.tar.gz: 44d6e613313a299099951c2144ac597d23d5fbc0da997adb95d6218db10cde6db7df6f998f50b3434688a3094e7f1a14b9769e16f666e160e6866fa87b6a6c6d
6
+ metadata.gz: a1b688fa1f02a212b520f91e856b80f4973410e3da568e07b3a07738c11618818ee01db7485732f352287d596374c09b8033883f6511594b952cee41da278688
7
+ data.tar.gz: ce0ccbe319ce3e3289b624ee0db760369486f52c8221df41e18df3ae44ea778682e750e50866fdfa67b074dfb4a075864eff9e478ddf7eeaad813125ceb590e4
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ Gemfile.lock
1
2
  *.gem
2
3
  /coverage/
3
4
  /pkg/
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
- ### Get Accounts
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
- ### Set API Node
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
- ### Reference
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
- ### Tests
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
@@ -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
@@ -1,4 +1,4 @@
1
1
  module Peerplays
2
- VERSION = '1.0.0-1'
2
+ VERSION = '1.0.0-2'
3
3
  AGENT_ID = "peerplays-ruby/#{VERSION}"
4
4
  end
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.1
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-10 00:00:00.000000000 Z
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
- rubyforge_project:
421
- rubygems_version: 2.7.10
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: []
@@ -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