radiator 0.3.15 → 0.4.0pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ module Radiator
2
+ module Mixins
3
+ module ActsAsVoter
4
+ # Create a vote operation.
5
+ #
6
+ # Examples:
7
+ #
8
+ # steem = Steem.new(account_name: 'your account name', wif: 'your wif')
9
+ # steem.vote(10000, 'author', 'permlink')
10
+ # steem.broadcast!
11
+ #
12
+ # ... or ...
13
+ #
14
+ # steem = Steem.new(account_name: 'your account name', wif: 'your wif')
15
+ # steem.vote(10000, '@author/permlink')
16
+ # steem.broadcast!
17
+ #
18
+ # @param weight [Integer] value between -10000 and 10000.
19
+ # @param args [author, permlink || slug] pass either `author` and `permlink` or string containing both like `@author/permlink`.
20
+ def vote(weight, *args)
21
+ author, permlink = normalize_author_permlink(args)
22
+
23
+ @operations << {
24
+ type: :vote,
25
+ voter: account_name,
26
+ author: author,
27
+ permlink: permlink,
28
+ weight: weight
29
+ }
30
+
31
+ self
32
+ end
33
+
34
+ # Create a vote operation and broadcasts it right away.
35
+ #
36
+ # Examples:
37
+ #
38
+ # steem = Steem.new(account_name: 'your account name', wif: 'your wif')
39
+ # steem.vote!(10000, 'author', 'permlink')
40
+ #
41
+ # ... or ...
42
+ #
43
+ # steem = Steem.new(account_name: 'your account name', wif: 'your wif')
44
+ # steem.vote!(10000, '@author/permlink')
45
+ #
46
+ # @see vote
47
+ def vote!(weight, *args); vote(weight, *args).broadcast!(true); end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,67 @@
1
+ module Radiator
2
+ module Mixins
3
+ module ActsAsWallet
4
+ # Create a claim_reward_balance operation.
5
+ #
6
+ # Examples:
7
+ #
8
+ # steem = Steem.new(account_name: 'your account name', wif: 'your wif')
9
+ # steem.claim_reward_balance(reward_sbd: '100.000 SBD')
10
+ # steem.broadcast!
11
+ #
12
+ # @param options [Hash] options
13
+ # @option options [String] :reward_steem The amount of STEEM to claim, like: `100.000 STEEM`
14
+ # @option options [String] :reward_sbd The amount of SBD to claim, like: `100.000 SBD`
15
+ # @option options [String] :reward_vests The amount of VESTS to claim, like: `100.000000 VESTS`
16
+ def claim_reward_balance(options)
17
+ reward_steem = options[:reward_steem] || '0.000 STEEM'
18
+ reward_sbd = options[:reward_sbd] || '0.000 SBD'
19
+ reward_vests = options[:reward_vests] || '0.000000 VESTS'
20
+
21
+ @operations << {
22
+ type: :claim_reward_balance,
23
+ account: account_name,
24
+ reward_steem: reward_steem,
25
+ reward_sbd: reward_sbd,
26
+ reward_vests: reward_vests
27
+ }
28
+
29
+ self
30
+ end
31
+
32
+ # Create a claim_reward_balance operation and broadcasts it right away.
33
+ #
34
+ # Examples:
35
+ #
36
+ # steem = Steem.new(account_name: 'your account name', wif: 'your wif')
37
+ # steem.claim_reward_balance!(reward_sbd: '100.000 SBD')
38
+ #
39
+ # @see claim_reward_balance
40
+ def claim_reward_balance!(permlink); claim_reward_balance(permlink).broadcast!(true); end
41
+
42
+ # Create a transfer operation.
43
+ #
44
+ # steem = Steem.new(account_name: 'your account name', wif: 'your active wif')
45
+ # steem.transfer(amount: '1.000 SBD', to: 'account name', memo: 'this is a memo')
46
+ # steem.broadcast!
47
+ #
48
+ # @param options [Hash] options
49
+ # @option options [String] :amount The amount to transfer, like: `100.000 STEEM`
50
+ # @option options [String] :to The account receiving the transfer.
51
+ # @option options [String] :memo ('') The memo for the transfer.
52
+ def transfer(options = {})
53
+ @operations << options.merge(type: :transfer, from: account_name)
54
+
55
+ self
56
+ end
57
+
58
+ # Create a transfer operation and broadcasts it right away.
59
+ #
60
+ # steem = Steem.new(account_name: 'your account name', wif: 'your wif')
61
+ # steem.transfer!(amount: '1.000 SBD', to: 'account name', memo: 'this is a memo')
62
+ #
63
+ # @see transfer
64
+ def transfer!(options = {}); transfer(options).broadcast!(true); end
65
+ end
66
+ end
67
+ end
@@ -8,13 +8,13 @@ module Radiator
8
8
  class Transaction
9
9
  include ChainConfig
10
10
  include Utils
11
-
11
+
12
12
  VALID_OPTIONS = %w(
13
13
  wif private_key ref_block_num ref_block_prefix expiration
14
14
  chain
15
15
  ).map(&:to_sym)
16
16
  VALID_OPTIONS.each { |option| attr_accessor option }
17
-
17
+
18
18
  def initialize(options = {})
19
19
  options = options.dup
20
20
  options.each do |k, v|
@@ -24,29 +24,31 @@ module Radiator
24
24
  send("#{k}=", v)
25
25
  end
26
26
  end
27
-
27
+
28
28
  @logger = options[:logger] || Radiator.logger
29
29
  @chain ||= :steem
30
30
  @chain = @chain.to_sym
31
31
  @chain_id = chain_id options[:chain_id]
32
32
  @url = options[:url] || url
33
33
  @operations = options[:operations] || []
34
-
34
+
35
35
  unless NETWORK_CHAIN_IDS.include? @chain_id
36
36
  warning "Unknown chain id: #{@chain_id}"
37
37
  end
38
-
38
+
39
39
  if !!wif && !!private_key
40
40
  raise TransactionError, "Do not pass both wif and private_key. That's confusing."
41
41
  end
42
-
42
+
43
43
  if !!wif
44
44
  @private_key = Bitcoin::Key.from_base58 wif
45
45
  end
46
-
46
+
47
+ @ref_block_num ||= nil
48
+ @ref_block_prefix ||= nil
47
49
  @expiration ||= nil
48
50
  @immutable_expiration = !!@expiration
49
-
51
+
50
52
  options = options.merge(
51
53
  url: @url,
52
54
  chain: @chain,
@@ -54,23 +56,23 @@ module Radiator
54
56
  persist: false,
55
57
  reuse_ssl_sessions: false
56
58
  )
57
-
59
+
58
60
  @api = Api.new(options)
59
61
  @network_broadcast_api = NetworkBroadcastApi.new(options)
60
-
62
+
61
63
  ObjectSpace.define_finalizer(self, self.class.finalize(@api, @network_broadcast_api, @logger))
62
64
  end
63
-
65
+
64
66
  def chain_id(chain_id = nil)
65
67
  return chain_id if !!chain_id
66
-
68
+
67
69
  case chain.to_s.downcase.to_sym
68
70
  when :steem then NETWORKS_STEEM_CHAIN_ID
69
71
  when :golos then NETWORKS_GOLOS_CHAIN_ID
70
72
  when :test then NETWORKS_TEST_CHAIN_ID
71
73
  end
72
74
  end
73
-
75
+
74
76
  def url
75
77
  case chain.to_s.downcase.to_sym
76
78
  when :steem then NETWORKS_STEEM_DEFAULT_NODE
@@ -78,24 +80,24 @@ module Radiator
78
80
  when :test then NETWORKS_TEST_DEFAULT_NODE
79
81
  end
80
82
  end
81
-
83
+
82
84
  def process(broadcast = false)
83
85
  prepare
84
-
86
+
85
87
  if broadcast
86
88
  loop do
87
89
  response = @network_broadcast_api.broadcast_transaction_synchronous(payload)
88
-
90
+
89
91
  if !!response.error
90
92
  parser = ErrorParser.new(response)
91
-
93
+
92
94
  if parser.can_reprepare?
93
95
  debug "Error code: #{parser}, repreparing transaction ..."
94
96
  prepare
95
- redo
97
+ redo
96
98
  end
97
99
  end
98
-
100
+
99
101
  return response
100
102
  end
101
103
  else
@@ -104,7 +106,7 @@ module Radiator
104
106
  ensure
105
107
  shutdown
106
108
  end
107
-
109
+
108
110
  def operations
109
111
  @operations = @operations.map do |op|
110
112
  case op
@@ -113,14 +115,20 @@ module Radiator
113
115
  end
114
116
  end
115
117
  end
116
-
118
+
117
119
  def operations=(operations)
118
120
  @operations = operations
119
121
  end
120
-
122
+
121
123
  def shutdown
122
124
  @api.shutdown if !!@api
123
125
  @network_broadcast_api.shutdown if !!@network_broadcast_api
126
+
127
+ if !!@logger && defined?(@logger.close)
128
+ if defined?(@logger.closed?)
129
+ @logger.close unless @logger.closed?
130
+ end
131
+ end
124
132
  end
125
133
  private
126
134
  def payload
@@ -133,35 +141,35 @@ module Radiator
133
141
  signatures: [hexlify(signature)]
134
142
  }
135
143
  end
136
-
144
+
137
145
  def prepare
138
146
  raise TransactionError, "No wif or private key." unless !!@wif || !!@private_key
139
-
147
+
140
148
  @payload = nil
141
-
149
+
142
150
  while @expiration.nil? && @ref_block_num.nil? && @ref_block_prefix.nil?
143
151
  @api.get_dynamic_global_properties do |properties, error|
144
152
  if !!error
145
153
  raise TransactionError, "Unable to prepare transaction.", error
146
154
  end
147
-
155
+
148
156
  @properties = properties
149
157
  end
150
-
158
+
151
159
  # You can actually go back as far as the TaPoS buffer will allow, which
152
160
  # is something like 50,000 blocks.
153
-
161
+
154
162
  block_number = @properties.last_irreversible_block_num
155
-
163
+
156
164
  @api.get_block(block_number) do |block, error|
157
165
  if !!error
158
166
  raise TransactionError, "Unable to prepare transaction.", error
159
167
  end
160
-
168
+
161
169
  if !!block && !!block.previous
162
170
  @ref_block_num = (block_number - 1) & 0xFFFF
163
171
  @ref_block_prefix = unhexlify(block.previous[8..-1]).unpack('V*')[0]
164
-
172
+
165
173
  # The expiration allows for transactions to expire if they are not
166
174
  # included into a block by that time. Always update it to the current
167
175
  # time + EXPIRE_IN_SECS.
@@ -169,50 +177,50 @@ module Radiator
169
177
  # Note, as of #1215, expiration exactly 'now' will be rejected:
170
178
  # https://github.com/steemit/steem/blob/57451b80d2cf480dcce9b399e48e56aa7af1d818/libraries/chain/database.cpp#L2870
171
179
  # https://github.com/steemit/steem/issues/1215
172
-
180
+
173
181
  block_time = Time.parse(@properties.time + 'Z')
174
182
  @expiration ||= block_time + EXPIRE_IN_SECS
175
183
  else
176
184
  # Suspect this happens when there are microforks, but it should be
177
185
  # rare, especially since we're asking for the last irreversible
178
186
  # block.
179
-
187
+
180
188
  if block.nil?
181
189
  warning "Block missing while trying to prepare transaction, retrying ..."
182
190
  else
183
191
  debug block if %w(DEBUG TRACE).include? ENV['LOG']
184
-
192
+
185
193
  warning "Block structure while trying to prepare transaction, retrying ..."
186
194
  end
187
-
195
+
188
196
  @expiration = nil unless @immutable_expiration
189
197
  end
190
198
  end
191
199
  end
192
-
200
+
193
201
  self
194
202
  end
195
-
203
+
196
204
  def to_bytes
197
205
  bytes = unhexlify(@chain_id)
198
206
  bytes << pakS(@ref_block_num)
199
207
  bytes << pakI(@ref_block_prefix)
200
208
  bytes << pakI(@expiration.to_i)
201
209
  bytes << pakC(operations.size)
202
-
210
+
203
211
  operations.each do |op|
204
212
  bytes << op.to_bytes
205
213
  end
206
-
214
+
207
215
  bytes << 0x00 # extensions
208
-
216
+
209
217
  bytes
210
218
  end
211
-
219
+
212
220
  def digest
213
221
  Digest::SHA256.digest(to_bytes)
214
222
  end
215
-
223
+
216
224
  # May not find all non-canonicals, see: https://github.com/lian/bitcoin-ruby/issues/196
217
225
  def signature
218
226
  public_key_hex = @private_key.pub
@@ -224,16 +232,17 @@ module Radiator
224
232
  count += 1
225
233
  debug "#{count} attempts to find canonical signature" if count % 40 == 0
226
234
  sig = ec.sign_compact(digest_hex, @private_key.priv, public_key_hex, false)
227
-
235
+
228
236
  next if public_key_hex != ec.recover_compact(digest_hex, sig)
229
-
237
+
230
238
  return sig if canonical? sig
231
239
  end
232
240
  end
233
241
 
242
+ # See: https://github.com/steemit/steem/issues/1944
234
243
  def canonical?(sig)
235
244
  sig = sig.unpack('C*')
236
-
245
+
237
246
  !(
238
247
  ((sig[0] & 0x80 ) != 0) || ( sig[0] == 0 ) ||
239
248
  ((sig[1] & 0x80 ) != 0) ||
@@ -241,7 +250,7 @@ module Radiator
241
250
  ((sig[33] & 0x80 ) != 0)
242
251
  )
243
252
  end
244
-
253
+
245
254
  def self.finalize(api, network_broadcast_api, logger)
246
255
  proc {
247
256
  if !!api && !api.stopped?
@@ -249,16 +258,20 @@ module Radiator
249
258
  api.shutdown
250
259
  api = nil
251
260
  end
252
-
261
+
253
262
  if !!network_broadcast_api && !network_broadcast_api.stopped?
254
263
  puts "DESTROY: #{network_broadcast_api.inspect}" if ENV['LOG'] == 'TRACE'
255
264
  network_broadcast_api.shutdown
256
265
  network_broadcast_api = nil
257
266
  end
258
-
259
- if !!logger && defined?(logger.close) && !logger.closed?
260
- logger.close
261
- end
267
+
268
+ begin
269
+ if !!logger && defined?(logger.close)
270
+ if defined?(logger.closed?)
271
+ logger.close unless logger.closed?
272
+ end
273
+ end
274
+ rescue IOError, NoMethodError => _; end
262
275
  }
263
276
  end
264
277
  end
@@ -5,13 +5,14 @@ module Radiator
5
5
  class Permission < Serializer
6
6
  def initialize(value)
7
7
  super(:permission, value)
8
- raise NotImplementedError, 'stub'
9
8
  end
10
9
 
11
10
  def to_bytes
11
+ pakHash(@value)
12
12
  end
13
13
 
14
14
  def to_s
15
+ @value.to_json
15
16
  end
16
17
  end
17
18
  end
@@ -37,18 +37,10 @@ module Radiator
37
37
  puts "#{level}: #{log_message}"
38
38
  end
39
39
  else
40
- if defined? @logger.ap
41
- if !!prefix
42
- @logger.ap log_level: level, prefix => obj
43
- else
44
- @logger.ap obj, level
45
- end
40
+ if !!prefix
41
+ @logger.ap log_level: level, prefix => obj
46
42
  else
47
- if !!prefix
48
- @logger.send level, ({prefix => obj}).inspect
49
- else
50
- @logger.send level, obj.inspect
51
- end
43
+ @logger.ap obj, level
52
44
  end
53
45
  end
54
46
 
@@ -1,4 +1,4 @@
1
1
  module Radiator
2
- VERSION = '0.3.15'
2
+ VERSION = '0.4.0pre1'
3
3
  AGENT_ID = "radiator/#{VERSION}"
4
4
  end
data/lib/radiator.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require 'radiator/version'
2
2
  require 'json'
3
- require 'awesome_print' if ENV['USE_AWESOME_PRINT'] == 'true'
4
3
 
5
4
  module Radiator
6
5
  require 'radiator/utils'
@@ -33,6 +32,9 @@ module Radiator
33
32
  require 'radiator/transaction'
34
33
  require 'radiator/base_error'
35
34
  require 'radiator/error_parser'
35
+ require 'radiator/mixins/acts_as_poster'
36
+ require 'radiator/mixins/acts_as_voter'
37
+ require 'radiator/mixins/acts_as_wallet'
36
38
  require 'radiator/chain'
37
39
  require 'steem'
38
40
  require 'golos'
data/lib/steem.rb CHANGED
@@ -5,4 +5,7 @@ class Steem < Radiator::Chain
5
5
  def initialize(options = {})
6
6
  super(options.merge(chain: :steem))
7
7
  end
8
+
9
+ alias steem_per_mvest base_per_mvest
10
+ alias steem_per_usd base_per_debt
8
11
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radiator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.15
4
+ version: 0.4.0pre1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthony Martin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-30 00:00:00.000000000 Z
11
+ date: 2018-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -342,6 +342,9 @@ files:
342
342
  - lib/radiator/logger.rb
343
343
  - lib/radiator/market_history_api.rb
344
344
  - lib/radiator/methods.json
345
+ - lib/radiator/mixins/acts_as_poster.rb
346
+ - lib/radiator/mixins/acts_as_voter.rb
347
+ - lib/radiator/mixins/acts_as_wallet.rb
345
348
  - lib/radiator/network_broadcast_api.rb
346
349
  - lib/radiator/operation.rb
347
350
  - lib/radiator/operation_ids.rb
@@ -378,12 +381,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
378
381
  version: '0'
379
382
  required_rubygems_version: !ruby/object:Gem::Requirement
380
383
  requirements:
381
- - - ">="
384
+ - - ">"
382
385
  - !ruby/object:Gem::Version
383
- version: '0'
386
+ version: 1.3.1
384
387
  requirements: []
385
388
  rubyforge_project:
386
- rubygems_version: 2.6.14
389
+ rubygems_version: 2.6.11
387
390
  signing_key:
388
391
  specification_version: 4
389
392
  summary: STEEM RPC Ruby Client