peerplays-ruby 1.0.0.pre.1 → 1.0.0.pre.2
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/.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
|