voilkruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +77 -0
  4. data/LICENSE +41 -0
  5. data/README.md +519 -0
  6. data/Rakefile +140 -0
  7. data/gource.sh +8 -0
  8. data/images/Anthony Martin.png +0 -0
  9. data/images/Marvin Hofmann.jpg +0 -0
  10. data/images/Marvin Hofmann.png +0 -0
  11. data/lib/voilk.rb +17 -0
  12. data/lib/voilkruby.rb +45 -0
  13. data/lib/voilkruby/account_by_key_api.rb +7 -0
  14. data/lib/voilkruby/account_history_api.rb +15 -0
  15. data/lib/voilkruby/api.rb +772 -0
  16. data/lib/voilkruby/base_error.rb +23 -0
  17. data/lib/voilkruby/block_api.rb +14 -0
  18. data/lib/voilkruby/broadcast_operations.json +497 -0
  19. data/lib/voilkruby/chain.rb +299 -0
  20. data/lib/voilkruby/chain_config.rb +22 -0
  21. data/lib/voilkruby/chain_stats_api.rb +15 -0
  22. data/lib/voilkruby/condenser_api.rb +99 -0
  23. data/lib/voilkruby/database_api.rb +5 -0
  24. data/lib/voilkruby/error_parser.rb +228 -0
  25. data/lib/voilkruby/follow_api.rb +7 -0
  26. data/lib/voilkruby/logger.rb +20 -0
  27. data/lib/voilkruby/market_history_api.rb +19 -0
  28. data/lib/voilkruby/methods.json +495 -0
  29. data/lib/voilkruby/mixins/acts_as_poster.rb +124 -0
  30. data/lib/voilkruby/mixins/acts_as_voter.rb +50 -0
  31. data/lib/voilkruby/mixins/acts_as_wallet.rb +67 -0
  32. data/lib/voilkruby/network_broadcast_api.rb +7 -0
  33. data/lib/voilkruby/operation.rb +101 -0
  34. data/lib/voilkruby/operation_ids.rb +98 -0
  35. data/lib/voilkruby/operation_types.rb +139 -0
  36. data/lib/voilkruby/stream.rb +527 -0
  37. data/lib/voilkruby/tag_api.rb +33 -0
  38. data/lib/voilkruby/transaction.rb +306 -0
  39. data/lib/voilkruby/type/amount.rb +57 -0
  40. data/lib/voilkruby/type/array.rb +17 -0
  41. data/lib/voilkruby/type/beneficiaries.rb +29 -0
  42. data/lib/voilkruby/type/future.rb +18 -0
  43. data/lib/voilkruby/type/hash.rb +17 -0
  44. data/lib/voilkruby/type/permission.rb +19 -0
  45. data/lib/voilkruby/type/point_in_time.rb +19 -0
  46. data/lib/voilkruby/type/price.rb +25 -0
  47. data/lib/voilkruby/type/public_key.rb +18 -0
  48. data/lib/voilkruby/type/serializer.rb +12 -0
  49. data/lib/voilkruby/type/u_int16.rb +19 -0
  50. data/lib/voilkruby/type/u_int32.rb +19 -0
  51. data/lib/voilkruby/utils.rb +170 -0
  52. data/lib/voilkruby/version.rb +4 -0
  53. data/voilkruby.gemspec +40 -0
  54. metadata +412 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 3ec2630b0bab4658e1097d2f15b408359140dee32c142c0859e4a5a3f36772ad
4
+ data.tar.gz: fbfca6cd909b3b5da392570bbc0dccd56d3ce95d339b5875034b759c2ca3a81f
5
+ SHA512:
6
+ metadata.gz: e94feb0dc13d4c9e405ddfabde9fc30cadd7fe0e7ad4f911b49db06ea6e63d7ade6bb3d6e3426c7d9b53f1d6e065142a1c5d85c8307883b05770f92efc74f9c1
7
+ data.tar.gz: 86afd13aadc3cbc397ab4fb6066fd72f6a6bc0d91444e81174bc91d7d242c562363143ee2fdab66c620fb4ae7950586dcb8e7ddcc72d9359f95487d521a34723
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,77 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ voilkruby (0.0.1)
5
+ awesome_print (~> 1.7, >= 1.7.0)
6
+ bitcoin-ruby (~> 0.0, >= 0.0.11)
7
+ ffi (~> 1.9, >= 1.9.18)
8
+ hashie (~> 3.5, >= 3.5.5)
9
+ json (~> 2.0, >= 2.0.2)
10
+ logging (~> 2.2, >= 2.2.0)
11
+ net-http-persistent (>= 2.5.2)
12
+
13
+ GEM
14
+ remote: https://rubygems.org/
15
+ specs:
16
+ addressable (2.5.2)
17
+ public_suffix (>= 2.0.2, < 4.0)
18
+ awesome_print (1.8.0)
19
+ bitcoin-ruby (0.0.18)
20
+ coderay (1.1.2)
21
+ connection_pool (2.2.2)
22
+ crack (0.4.3)
23
+ safe_yaml (~> 1.0.0)
24
+ docile (1.3.1)
25
+ ffi (1.9.25)
26
+ hashdiff (0.3.7)
27
+ hashie (3.6.0)
28
+ json (2.1.0)
29
+ little-plugger (1.1.4)
30
+ logging (2.2.2)
31
+ little-plugger (~> 1.1)
32
+ multi_json (~> 1.10)
33
+ method_source (0.9.2)
34
+ minitest (5.11.3)
35
+ minitest-line (0.6.5)
36
+ minitest (~> 5.0)
37
+ minitest-proveit (1.0.0)
38
+ minitest (> 5, < 7)
39
+ multi_json (1.13.1)
40
+ net-http-persistent (3.0.0)
41
+ connection_pool (~> 2.2)
42
+ pry (0.12.2)
43
+ coderay (~> 1.1.0)
44
+ method_source (~> 0.9.0)
45
+ public_suffix (3.0.3)
46
+ rake (12.3.1)
47
+ safe_yaml (1.0.4)
48
+ simplecov (0.16.1)
49
+ docile (~> 1.1)
50
+ json (>= 1.8, < 3)
51
+ simplecov-html (~> 0.10.0)
52
+ simplecov-html (0.10.2)
53
+ vcr (4.0.0)
54
+ webmock (3.4.2)
55
+ addressable (>= 2.3.6)
56
+ crack (>= 0.3.2)
57
+ hashdiff
58
+ yard (0.9.16)
59
+
60
+ PLATFORMS
61
+ ruby
62
+
63
+ DEPENDENCIES
64
+ bundler (~> 1.15, >= 1.15.4)
65
+ minitest (~> 5.10, >= 5.10.3)
66
+ minitest-line (~> 0.6.3)
67
+ minitest-proveit (~> 1.0, >= 1.0.0)
68
+ pry (~> 0.11, >= 0.11.3)
69
+ voilkruby!
70
+ rake (~> 12.1, >= 12.1.0)
71
+ simplecov (~> 0.16.1)
72
+ vcr (~> 4.0, >= 4.0.0)
73
+ webmock (~> 3.1, >= 3.1.0)
74
+ yard (~> 0.9.9)
75
+
76
+ BUNDLED WITH
77
+ 1.16.5
data/LICENSE ADDED
@@ -0,0 +1,41 @@
1
+ CC0 1.0 Universal (CC0 1.0)
2
+ Public Domain Dedication
3
+ https://creativecommons.org/publicdomain/zero/1.0/
4
+
5
+ This is a human-readable summary of the Legal Code:
6
+ https://creativecommons.org/publicdomain/zero/1.0/legalcode
7
+
8
+ Disclaimer
9
+
10
+ The Commons Deed is not a legal instrument. It is simply a handy reference for
11
+ understanding the CC0 Legal Code, a human-readable expression of some of its key
12
+ terms. Think of it as the user-friendly interface to the CC0 Legal Code beneath.
13
+ This Deed itself has no legal value, and its contents do not appear in CC0.
14
+ Creative Commons is not a law firm and does not provide legal services.
15
+ Distributing, displaying, or linking to this Commons Deed does not create an
16
+ attorney-client relationship.
17
+
18
+ Creative Commons has not verified the copyright status of any work to which CC0
19
+ has been applied. CC makes no warranties about any work or its copyright status
20
+ in any jurisdiction, and disclaims all liability for all uses of any work.
21
+
22
+ No Copyright
23
+
24
+ The person who associated a work with this deed has dedicated the work to the
25
+ public domain by waiving all of his or her rights to the work worldwide under
26
+ copyright law, including all related and neighboring rights, to the extent
27
+ allowed by law.
28
+
29
+ You can copy, modify, distribute and perform the work, even for commercial
30
+ purposes, all without asking permission. See Other Information below.
31
+
32
+ Other Information
33
+
34
+ * In no way are the patent or trademark rights of any person affected by CC0,
35
+ nor are the rights that other persons may have in the work or in how the work
36
+ is used, such as publicity or privacy rights.
37
+ * Unless expressly stated otherwise, the person who associated a work with this
38
+ deed makes no warranties about the work, and disclaims liability for all uses
39
+ of the work, to the fullest extent permitted by applicable law.
40
+ * When using or citing the work, you should not imply endorsement by the author
41
+ or the affirmer.
@@ -0,0 +1,519 @@
1
+ [![Build Status](https://travis-ci.org/voilk/voilkruby.svg?branch=master)](https://travis-ci.org/voilk/voilkruby)
2
+ [![Code Climate](https://codeclimate.com/github/voilk/voilkruby/badges/gpa.svg)](https://codeclimate.com/github/voilk/voilkruby)
3
+ [![Test Coverage](https://codeclimate.com/github/voilk/voilkruby/badges/coverage.svg)](https://codeclimate.com/github/voilk/voilkruby)
4
+ [![Inline docs](http://inch-ci.org/github/voilk/voilkruby.svg?branch=master&style=shields)](http://inch-ci.org/github/voilk/voilkruby)
5
+
6
+ [voilkruby](https://github.com/voilknetwork/voilkruby)
7
+ ========
8
+
9
+ #### VOILK Ruby API Client
10
+
11
+ VoilkRuby is an API Client for interaction with the VOILK network using Ruby.
12
+
13
+ #### Changes in v0.0.2
14
+
15
+ * Gem updates
16
+ * **AppBase Support**
17
+ * Defaulting to `condenser_api.*` in `VoilkRuby::Api` (see below)
18
+ * Handle/recover from new `AppBase` errors.
19
+ * `VoilkRuby::Stream` now detects if it's stalled and takes action if it has to wait too long for a new block.
20
+ 1. Exponential back-off for stalls so that the node doesn't get slammed.
21
+ 2. Short delays (3 times block production) only result in a warning.
22
+ 3. Long delays (6 times block production) may try to switch to an alternate node.
23
+ * Fixed internal logging bug that would open too many files.
24
+
25
+ **Appbase is now supported.**
26
+
27
+ If you were already using `VoilkRuby::Api` then there is nothing to change. But if you made use of other API classes, like `VoilkRuby::FollowApi`, then the method signatures have changed.
28
+
29
+ **Pre-AppBase:**
30
+
31
+ ```ruby
32
+ api = VoilkRuby::FollowApi.new
33
+
34
+ api.get_followers('bilalhaider', 0, 'blog', 10)
35
+ ```
36
+
37
+ **New Signature:**
38
+
39
+ ```ruby
40
+ api = VoilkRuby::FollowApi.new
41
+
42
+ api.get_followers(account: 'bilalhaider', start: 0, type: 'blog', limit: 10)
43
+ ```
44
+
45
+ *-- or --*
46
+
47
+ **Switch to Condenser API:**
48
+
49
+ The other strategy for using this version of VoilkRuby is to just switch away from classes like `VoilkRuby::FollowApi` over to `VoilkRuby::Api` (also known as `VoilkRuby::CondenserApi`) instead. Then you don't have to update individual method calls.
50
+
51
+ ```ruby
52
+ api = VoilkRuby::Api.new
53
+
54
+ api.get_followers('bilalhaider', 0, 'blog', 10)
55
+ ```
56
+
57
+
58
+ #### Changes in v0.0.2
59
+
60
+ * Gem updates
61
+ * Added failover subroutines (see Failover section, below).
62
+ * Added method closures support (aka passing a block to yield).
63
+ * You can now stream virtual operations (see Streaming section, below).
64
+ * Added more [documentation](http://www.rubydoc.info/gems/voilkruby).
65
+ * Added/expanded more api namespaces: `::BlockApi`, `::CondenserApi`, `::TagApi`
66
+ * Addressed an issue with logging on certain Windows configurations.
67
+ * Added low-level support for persistence and retrying API requests.
68
+ * Now using exponential back-off for retries.
69
+ * Detecting presence of `transaction_ids` (if enabled by the node).
70
+ * Default for `Hashie` warnings now go to `/dev/null`, where they belong.
71
+ * Added stray methods/operations.
72
+ * Improved support for datatypes and handlers.
73
+ * UTF-8 handled more smoothly.
74
+ * Simplified operation construction.
75
+ * Improved keep-alive defaults.
76
+ * Better streaming reliability.
77
+
78
+ ---
79
+
80
+ Also see: [Documentation](http://www.rubydoc.info/gems/voilkruby)
81
+
82
+ ---
83
+
84
+ ### Quick Start
85
+
86
+ Add the gem to your Gemfile:
87
+
88
+ ```ruby
89
+ gem 'voilkruby'
90
+ ```
91
+
92
+ Then:
93
+
94
+ ```bash
95
+ $ bundle install
96
+ ```
97
+
98
+ If you don't have `bundler`, see the next section.
99
+
100
+ ### Prerequisites
101
+
102
+ `minimum ruby version: 2.2`
103
+
104
+ #### Linux
105
+
106
+ ```bash
107
+ $ sudo apt-get install ruby-full git openssl libssl1.0.0 libssl-dev
108
+ $ gem install bundler
109
+ ```
110
+
111
+ #### macOS
112
+
113
+ ```
114
+ $ gem install bundler
115
+ ```
116
+
117
+ ### Usage
118
+
119
+ ```ruby
120
+ require 'voilkruby'
121
+
122
+ api = VoilkRuby::Api.new
123
+ api.get_dynamic_global_properties do |properties|
124
+ properties.virtual_supply
125
+ end
126
+ => "271342874.337 VOILK"
127
+ ```
128
+
129
+ ... or ...
130
+
131
+ ```ruby
132
+ require 'voilkruby'
133
+
134
+ api = VoilkRuby::Api.new
135
+ response = api.get_dynamic_global_properties
136
+ response.result.virtual_supply
137
+ => "271342874.337 VOILK"
138
+ ```
139
+
140
+ #### Follower API
141
+
142
+ ```ruby
143
+ api = VoilkRuby::FollowApi.new
144
+ api.get_followers(account: 'bilalhaider', start: 0, type: 'blog', limit: 100) do |followers|
145
+ followers.map(&:follower)
146
+ end
147
+ ```
148
+
149
+ #### Streaming
150
+
151
+ Here's an example of how to use a streaming instance to listen for votes:
152
+
153
+ ```ruby
154
+ require 'voilkruby'
155
+
156
+ stream = VoilkRuby::Stream.new
157
+
158
+ stream.operations(:vote) do |op|
159
+ print "#{op.voter} voted for #{op.author}"
160
+ puts " (weight: #{op.weight / 100.0}%)"
161
+ end
162
+ ```
163
+
164
+ The output would look like this and continue until interrupted.
165
+
166
+ ```
167
+ richman voted for krnel (weight: 100.0%)
168
+ rainchen voted for rainchen (weight: 100.0%)
169
+ richman voted for exploretraveler (weight: 100.0%)
170
+ jlufer voted for michaelstobiersk (weight: 100.0%)
171
+ jlufer voted for michaelstobiersk (weight: 100.0%)
172
+ patelincho voted for borishaifa (weight: 100.0%)
173
+ richman voted for vetvso (weight: 100.0%)
174
+ jlufer voted for michaelstobiersk (weight: 100.0%)
175
+ richman voted for orcish (weight: 100.0%)
176
+ demotruk voted for skeptic (weight: -100.0%)
177
+ photorealistic voted for oecp85 (weight: 100.0%)
178
+ meesterboom voted for rubenalexander (weight: 100.0%)
179
+ thecurator voted for robyneggs (weight: 40.0%)
180
+ richman voted for originate (weight: 100.0%)
181
+ helikopterben voted for etcmike (weight: 100.0%)
182
+ .
183
+ .
184
+ .
185
+ ```
186
+
187
+ You can also just stream all operations like this:
188
+
189
+ ```ruby
190
+ stream.operations do |op|
191
+ puts op.to_json
192
+ end
193
+ ```
194
+
195
+ Example of the output:
196
+
197
+ ```json
198
+ {
199
+ "vote":{
200
+ "voter":"abudar",
201
+ "author":"rangkangandroid",
202
+ "permlink":"the-kalinga-tattoo-maker",
203
+ "weight":10000
204
+ }
205
+ }
206
+ {
207
+ "vote":{
208
+ "voter":"shenburen",
209
+ "author":"masteryoda",
210
+ "permlink":"daily-payouts-leaderboards-september-16",
211
+ "weight":10000
212
+ }
213
+ }
214
+ {
215
+ "vote":{
216
+ "voter":"stiletto",
217
+ "author":"fyrstikken",
218
+ "permlink":"everybody-hating-me",
219
+ "weight":2500
220
+ }
221
+ }
222
+ {
223
+ "comment":{
224
+ "parent_author":"mariandavp",
225
+ "parent_permlink":"re-onceuponatime-re-mariandavp-the-bridge-original-artwork-by-mariandavp-20160906t182016608z",
226
+ "author":"onceuponatime",
227
+ "permlink":"re-mariandavp-re-onceuponatime-re-mariandavp-the-bridge-original-artwork-by-mariandavp-20160917t054726763z",
228
+ "title":"",
229
+ "body":"https://www.voilkimg.com/images/2016/09/17/oldcomputerpics551cb14c.jpg",
230
+ "json_metadata":"{\"tags\":[\"art\"],\"image\":[\"https://www.voilkimg.com/images/2016/09/17/oldcomputerpics551cb14c.jpg\"]}"
231
+ }
232
+ }
233
+ {
234
+ "vote":{
235
+ "voter":"abudar",
236
+ "author":"rangkangandroid",
237
+ "permlink":"the-journey-north-through-the-eyes-of-kalinga-tradition",
238
+ "weight":10000
239
+ }
240
+ }
241
+ {
242
+ "limit_order_cancel":{
243
+ "owner":"fnait",
244
+ "orderid":2755220300
245
+ }
246
+ }
247
+ .
248
+ .
249
+ .
250
+ ```
251
+
252
+ You can also stream virtual operations:
253
+
254
+ ```ruby
255
+ stream.operations(:producer_reward) do |op|
256
+ puts "#{op.producer} got a reward: #{op.coining_shares}"
257
+ end
258
+ ```
259
+
260
+ Example of the output:
261
+
262
+ ```
263
+ anyx got a reward: 390.974648 COINS
264
+ gtg got a reward: 390.974647 COINS
265
+ someguy123 got a reward: 390.974646 COINS
266
+ jesta got a reward: 390.974646 COINS
267
+ blocktrades got a reward: 390.974645 COINS
268
+ timcliff got a reward: 390.974644 COINS
269
+ bhuz got a reward: 1961.046504 COINS
270
+ .
271
+ .
272
+ .
273
+ ```
274
+
275
+ Transactions are supported:
276
+
277
+ ```ruby
278
+ stream.transactions do |tx, trx_id|
279
+ puts "[#{trx_id}] #{tx.to_json}"
280
+ end
281
+ ```
282
+
283
+ Example of the output:
284
+
285
+ ```json
286
+ {
287
+ "ref_block_num":59860,
288
+ "ref_block_prefix":2619183808,
289
+ "expiration":"2016-09-17T06:03:21",
290
+ "operations":[
291
+ [
292
+ "custom_json",
293
+ {
294
+ "required_auths":[
295
+
296
+ ],
297
+ "required_posting_auths":[
298
+ "acidpanda"
299
+ ],
300
+ "id":"follow",
301
+ "json":"[\"follow\",{\"follower\":\"acidpanda\",\"following\":\"gavvet\",\"what\":[\"blog\"]}]"
302
+ }
303
+ ]
304
+ ],
305
+ "extensions":[],
306
+ "signatures":[
307
+ "2048d7e32cc843adea0e11aa617dc9cdc773d0e9a0a0d0cd58d67a9fcd8fa2d2305d1bb611ac219fbd3b6a77ab60071df94fe193aae33591ee669cc7404d4e4ec4"
308
+ ]
309
+ }
310
+ .
311
+ .
312
+ .
313
+ ```
314
+
315
+ Even whole blocks:
316
+
317
+ ```ruby
318
+ stream.blocks do |bk, num|
319
+ puts "[#{num}] #{bk.to_json}"
320
+ end
321
+ ```
322
+
323
+ Example of the output:
324
+
325
+ ```json
326
+ {
327
+ "previous":"004cea0d46a4b91cffe7bb71763ad2ab854c6efd",
328
+ "timestamp":"2016-09-17T06:05:51",
329
+ "witness":"boatymcboatface",
330
+ "transaction_merkle_root":"0000000000000000000000000000000000000000",
331
+ "extensions":[],
332
+ "witness_signature":"2034b0d7398ed1c0d7511ac76c6dedaf227e609dc2676d13f926ddd1e9df7fa9cb254af122a4a82dc619a1091c87293cbd9e2db1b51404fdc8fb62f8e5f37b4625",
333
+ "transactions":[]
334
+ }
335
+ .
336
+ .
337
+ .
338
+ ```
339
+
340
+ #### Transaction Signing
341
+
342
+ VoilkRuby supports transaction signing, so you can use it to vote:
343
+
344
+ ```ruby
345
+ tx = VoilkRuby::Transaction.new(wif: 'Your Wif Here')
346
+ vote = {
347
+ type: :vote,
348
+ voter: 'bilalhaider',
349
+ author: 'bilalhaider',
350
+ permlink: 'introduction',
351
+ weight: 10000
352
+ }
353
+
354
+ tx.operations << vote
355
+ tx.process(true)
356
+ ```
357
+
358
+ You can also post/comment:
359
+
360
+ ```ruby
361
+ tx = VoilkRuby::Transaction.new(wif: 'Your Wif Here')
362
+ comment = {
363
+ type: :comment,
364
+ parent_permlink: 'test',
365
+ author: 'your-account',
366
+ permlink: 'something-unique',
367
+ title: 'VoilkRuby Can Post Comments!',
368
+ body: 'Yep, this post was created by VoilkRuby in `ruby`.',
369
+ json_metadata: '',
370
+ parent_author: ''
371
+ }
372
+
373
+ tx.operations << comment
374
+ tx.process(true)
375
+ ```
376
+
377
+ Transfers:
378
+
379
+ ```ruby
380
+ tx = VoilkRuby::Transaction.new(wif: 'Your Wif Here')
381
+ transfer = {
382
+ type: :transfer,
383
+ from: 'voilk',
384
+ to: 'bilalhaider',
385
+ amount: '100000.000 VSD',
386
+ memo: 'Wow, inertia! VoilkRuby is great!'
387
+ }
388
+
389
+ tx.operations << transfer
390
+ tx.process(true)
391
+ ```
392
+
393
+ There's a complete list of operations known to VoilkRuby in [`broadcast_operations.json`](https://github.com/voilknetwork/voilkruby/blob/master/lib/voilkruby/broadcast_operations.json).
394
+
395
+ ## Failover
396
+
397
+ VoilkRuby supports failover for situations where a node has, for example, become unresponsive. When creating a new instance of `::Api`, `::Stream`, and `::Transaction`, you may provide a list of alternative nodes, or leave them out to use the default list. For example:
398
+
399
+ ```ruby
400
+ options = {
401
+ url: 'https://api.voilk.com',
402
+ failover_urls: [
403
+ 'https://api2.voilk.com',
404
+ 'https://api3.voilk.com'
405
+ ]
406
+ }
407
+
408
+ api = VoilkRuby::Api.new(options)
409
+ ```
410
+
411
+ In a nutshell, the way this works is VoilkRuby will try a node and proceed until it encounters an error, then retry the request. If it encounters a second error within 5 minutes, it will abandon the node and try a random one from `failover_urls`.
412
+
413
+ It'll keep doing this until it runs out of failovers, then it will reset the configuration and go back to the original node.
414
+
415
+ VoilkRuby uses an exponential back-off subroutine to avoid slamming nodes when they act up.
416
+
417
+ There's an additional behavior in `::Stream`. When a node responds with a block out of sequence, it will use the failover logic above. Although this is not a network layer failure, it is a bad result that may indicate a problem on the node, so a new node is picked.
418
+
419
+ There is another rare scenario involving `::Transaction` broadcasts that's handled by the failover logic: When a node responds with a network error *after* a signed transaction is accepted, VoilkRuby will do a look-up to find the accepted signature in order to avoid triggering a `dupe_check` error from the blockchain. This subroutine might take up to five minutes to execute in the worst possible situation. To disable this behavior, use the `recover_transactions_on_error` and set it to `false`, e.g.:
420
+
421
+ ```ruby
422
+ tx = VoilkRuby::Transaction.new(wif: wif, recover_transactions_on_error: false)
423
+ ```
424
+
425
+ ## Debugging
426
+
427
+ To enable debugging, set environment `LOG=DEBUG` before launching your app. E.g.:
428
+
429
+ ```bash
430
+ $ LOG=DEBUG irb -rvoilkruby
431
+ ```
432
+
433
+ This will enable debugging for the `irb` session.
434
+
435
+ ## Troubleshooting
436
+
437
+ ## Problem: My log is full of `Unable to perform request ... retrying ...` messages.
438
+
439
+ ```
440
+ W, [2017-10-10T11:38:30.035318 #6743] WARN -- : database_api.get_dynamic_global_properties :: Unable to perform request: too many connection resets (due to Net::ReadTimeout - Net::ReadTimeout) after 0 requests on 26665356, last used 1507660710.035165 seconds ago :: cause: Net::ReadTimeout, retrying ...
441
+ ```
442
+
443
+ This is caused by network interruptions. If these messages happen once in a while, they can be ignored. VoilkRuby will retry the request and move on. If there are more frequent warnings, this will trigger the failover logic and pick a new node, if one has been configured (which is true by default). See the Failover section above.
444
+
445
+ ## Problem: My log is full of `Invalid block sequence` messages.
446
+
447
+ ```
448
+ W, [2017-10-10T13:53:24.327177 #6938] WARN -- : Invalid block sequence at height: 16217674
449
+ ```
450
+
451
+ This is a similar situation to `Unable to perform request ... retrying ...`. VoilkRuby::Stream will retry and failover if needed. It is happening because the node has responded with a block out of order and ::Stream is ignoring this block, then retrying.
452
+
453
+ ## Problem: What does the `Stream behind` error mean?
454
+
455
+ ```
456
+ W, [2017-10-09T17:15:59.164484 #6231] WARN -- : Stream behind by 6118 blocks (about 305.9 minutes).
457
+ ```
458
+
459
+ ## Solution:
460
+
461
+ This is an error produced by `::Stream` when it notices that the current block is falling too far behind the head block. One solution is to just restart the stream and see if it happens again. If you see a message like this occasionally, but otherwise the stream seems to keep up, it probably was able to recover on its own.
462
+
463
+ There can be several root causes. Resources like memory and CPU might be taxed. The network connection might be too slow for what you're doing. Remember, you're downloading each and every block, not just the operations you want.
464
+
465
+ If you have excluded system resources as the root cause, then you should take a look at your code. If you're doing anything that takes longer than 3 seconds per block, `::Stream` can fall behind. When this happens, `::Stream` will try to catch up without displaying a warning. But once you fall 400 blocks behind (~20 minutes), you'll start to get the warning messages.
466
+
467
+ Verify your code is not doing too much between blocks.
468
+
469
+ ## Problem: I'm getting an endless loop: `#<OpenSSL::SSL::SSLError: SSL_connect SYSCALL returned=5 errno=0 state=error: certificate verify failed>`
470
+
471
+ ## Solution:
472
+
473
+ You're probably creating too many threads or you don't have enough resources for what you're doing. One option for you is to avoid persistent HTTP by passing `persist: false`.
474
+
475
+ Doing this will impact performance because each API call will be a separate socket call. All of the constructors accept `persist: false`., e.g.:
476
+
477
+ ```ruby
478
+ api = VoilkRuby::Api.new(persist: false)
479
+ ```
480
+
481
+ ... or ...
482
+
483
+ ```ruby
484
+ stream = VoilkRuby::Stream.new(persist: false)
485
+ ```
486
+
487
+ ... or ...
488
+
489
+ ```ruby
490
+ tx = VoilkRuby::Transaction.new(options.merge(persist: false, wif: wif))
491
+ ```
492
+
493
+
494
+ ## Tests
495
+
496
+ * Clone the client repository into a directory of your choice:
497
+ * `git clone https://github.com/voilknetwork/voilkruby.git`
498
+ * Navigate into the new folder
499
+ * `cd voilkruby`
500
+ * Basic tests can be invoked as follows:
501
+ * `rake`
502
+ * To run tests with parallelization and local code coverage:
503
+ * `HELL_ENABLED=true rake`
504
+ * To run a stream test on the live VOILK blockchain with debug logging enabled:
505
+ * `LOG=DEBUG rake test_live_stream`
506
+
507
+ ---
508
+
509
+
510
+ See my previous Ruby How To posts in: [#voilkruby](https://voilk.com/created/voilkruby) [#ruby](https://voilk.com/created/ruby)
511
+
512
+ ## Special Thanks to
513
+
514
+ If you're using VoilkRuby, You should know that it was forked from "Radiator" which was created by Anthony Martin
515
+
516
+ ## License
517
+
518
+ We don't believe in licensing..
519
+ Use it however you want.