hive-ruby 1.0.0.pre.1
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 +7 -0
- data/.gitignore +54 -0
- data/CONTRIBUTING.md +79 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +91 -0
- data/LICENSE +21 -0
- data/README.md +248 -0
- data/Rakefile +358 -0
- data/gource.sh +6 -0
- data/hive-ruby.gemspec +40 -0
- data/images/Anthony Martin.png +0 -0
- data/lib/hive.rb +89 -0
- data/lib/hive/api.rb +223 -0
- data/lib/hive/base_error.rb +218 -0
- data/lib/hive/block_api.rb +78 -0
- data/lib/hive/bridge.rb +12 -0
- data/lib/hive/broadcast.rb +1334 -0
- data/lib/hive/chain_config.rb +34 -0
- data/lib/hive/fallback.rb +287 -0
- data/lib/hive/formatter.rb +14 -0
- data/lib/hive/jsonrpc.rb +112 -0
- data/lib/hive/marshal.rb +231 -0
- data/lib/hive/mixins/jsonable.rb +37 -0
- data/lib/hive/mixins/retriable.rb +58 -0
- data/lib/hive/mixins/serializable.rb +45 -0
- data/lib/hive/operation.rb +141 -0
- data/lib/hive/operation/account_create.rb +10 -0
- data/lib/hive/operation/account_create_with_delegation.rb +12 -0
- data/lib/hive/operation/account_update.rb +8 -0
- data/lib/hive/operation/account_witness_proxy.rb +4 -0
- data/lib/hive/operation/account_witness_vote.rb +5 -0
- data/lib/hive/operation/cancel_transfer_from_savings.rb +4 -0
- data/lib/hive/operation/challenge_authority.rb +5 -0
- data/lib/hive/operation/change_recovery_account.rb +5 -0
- data/lib/hive/operation/claim_account.rb +5 -0
- data/lib/hive/operation/claim_reward_balance.rb +6 -0
- data/lib/hive/operation/comment.rb +9 -0
- data/lib/hive/operation/comment_options.rb +10 -0
- data/lib/hive/operation/convert.rb +5 -0
- data/lib/hive/operation/create_claimed_account.rb +10 -0
- data/lib/hive/operation/custom.rb +5 -0
- data/lib/hive/operation/custom_binary.rb +8 -0
- data/lib/hive/operation/custom_json.rb +6 -0
- data/lib/hive/operation/decline_voting_rights.rb +4 -0
- data/lib/hive/operation/delegate_vesting_shares.rb +5 -0
- data/lib/hive/operation/delete_comment.rb +4 -0
- data/lib/hive/operation/escrow_approve.rb +8 -0
- data/lib/hive/operation/escrow_dispute.rb +7 -0
- data/lib/hive/operation/escrow_release.rb +10 -0
- data/lib/hive/operation/escrow_transfer.rb +12 -0
- data/lib/hive/operation/feed_publish.rb +4 -0
- data/lib/hive/operation/limit_order_cancel.rb +4 -0
- data/lib/hive/operation/limit_order_create.rb +8 -0
- data/lib/hive/operation/limit_order_create2.rb +8 -0
- data/lib/hive/operation/prove_authority.rb +4 -0
- data/lib/hive/operation/recover_account.rb +6 -0
- data/lib/hive/operation/report_over_production.rb +5 -0
- data/lib/hive/operation/request_account_recovery.rb +6 -0
- data/lib/hive/operation/reset_account.rb +5 -0
- data/lib/hive/operation/set_reset_account.rb +5 -0
- data/lib/hive/operation/set_withdraw_vesting_route.rb +6 -0
- data/lib/hive/operation/transfer.rb +6 -0
- data/lib/hive/operation/transfer_from_savings.rb +7 -0
- data/lib/hive/operation/transfer_to_savings.rb +6 -0
- data/lib/hive/operation/transfer_to_vesting.rb +5 -0
- data/lib/hive/operation/vote.rb +6 -0
- data/lib/hive/operation/withdraw_vesting.rb +4 -0
- data/lib/hive/operation/witness_set_properties.rb +5 -0
- data/lib/hive/operation/witness_update.rb +7 -0
- data/lib/hive/rpc/base_client.rb +179 -0
- data/lib/hive/rpc/http_client.rb +143 -0
- data/lib/hive/rpc/thread_safe_http_client.rb +35 -0
- data/lib/hive/stream.rb +385 -0
- data/lib/hive/transaction.rb +115 -0
- data/lib/hive/transaction_builder.rb +406 -0
- data/lib/hive/type/amount.rb +126 -0
- data/lib/hive/type/base_type.rb +10 -0
- data/lib/hive/utils.rb +17 -0
- data/lib/hive/version.rb +4 -0
- metadata +502 -0
@@ -0,0 +1,10 @@
|
|
1
|
+
class Hive::Operation::AccountCreate < Hive::Operation
|
2
|
+
def_attr fee: :amount
|
3
|
+
def_attr creator: :string
|
4
|
+
def_attr new_account_name: :string
|
5
|
+
def_attr owner: :authority
|
6
|
+
def_attr active: :authority
|
7
|
+
def_attr posting: :authority
|
8
|
+
def_attr memo_key: :public_key
|
9
|
+
def_attr json_metadata: :string
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Hive::Operation::AccountCreateWithDelegation < Hive::Operation
|
2
|
+
def_attr fee: :amount
|
3
|
+
def_attr delegation: :amount
|
4
|
+
def_attr creator: :string
|
5
|
+
def_attr new_account_name: :string
|
6
|
+
def_attr owner: :authority
|
7
|
+
def_attr active: :authority
|
8
|
+
def_attr posting: :authority
|
9
|
+
def_attr memo_key: :public_key
|
10
|
+
def_attr json_metadata: :string
|
11
|
+
def_attr extensions: :empty_array
|
12
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class Hive::Operation::AccountUpdate < Hive::Operation
|
2
|
+
def_attr account: :string
|
3
|
+
def_attr owner: :optional_authority
|
4
|
+
def_attr active: :optional_authority
|
5
|
+
def_attr posting: :optional_authority
|
6
|
+
def_attr memo_key: :public_key
|
7
|
+
def_attr json_metadata: :string
|
8
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
class Hive::Operation::Comment < Hive::Operation
|
2
|
+
def_attr parent_author: :string
|
3
|
+
def_attr parent_permlink: :string
|
4
|
+
def_attr author: :string
|
5
|
+
def_attr permlink: :string
|
6
|
+
def_attr title: :string
|
7
|
+
def_attr body: :string
|
8
|
+
def_attr json_metadata: :string
|
9
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Hive::Operation::CommentOptions < Hive::Operation
|
2
|
+
def_attr author: :string
|
3
|
+
def_attr permlink: :string
|
4
|
+
def_attr max_accepted_payout: :amount
|
5
|
+
def_attr percent_steem_dollars: :uint32
|
6
|
+
# def_attr allow_replies: :boolean
|
7
|
+
def_attr allow_votes: :boolean
|
8
|
+
def_attr allow_curation_rewards: :boolean
|
9
|
+
def_attr extensions: :comment_options_extensions
|
10
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Hive::Operation::CreateClaimedAccount < Hive::Operation
|
2
|
+
def_attr creator: :string
|
3
|
+
def_attr new_account_name: :string
|
4
|
+
def_attr owner: :authority
|
5
|
+
def_attr active: :authority
|
6
|
+
def_attr posting: :authority
|
7
|
+
def_attr memo_key: :public_key
|
8
|
+
def_attr json_metadata: :string
|
9
|
+
def_attr extensions: :empty_array
|
10
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class Hive::Operation::CustomBinary < Hive::Operation
|
2
|
+
def_attr required_owner_auths: :required_auths
|
3
|
+
def_attr required_active_auths: :required_auths
|
4
|
+
def_attr required_posting_auths: :required_auths
|
5
|
+
def_attr required_auths: :required_auths
|
6
|
+
def_attr id: :string
|
7
|
+
def_attr data: :raw_bytes
|
8
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Hive::Operation::EscrowRelease < Hive::Operation
|
2
|
+
def_attr from: :string
|
3
|
+
def_attr to: :string
|
4
|
+
def_attr agent: :string
|
5
|
+
def_attr who: :string
|
6
|
+
def_attr receiver: :string
|
7
|
+
def_attr escrow_id: :uint32
|
8
|
+
def_attr sbd_amount: :amount
|
9
|
+
def_attr steem_amount: :amount
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
class Hive::Operation::EscrowTransfer < Hive::Operation
|
2
|
+
def_attr from: :string
|
3
|
+
def_attr to: :string
|
4
|
+
def_attr sbd_amount: :amount
|
5
|
+
def_attr steem_amount: :amount
|
6
|
+
def_attr escrow_id: :uint32
|
7
|
+
def_attr agent: :string
|
8
|
+
def_attr fee: :amount
|
9
|
+
def_attr json_metadata: :string
|
10
|
+
def_attr ratification_deadline: :point_in_time
|
11
|
+
def_attr escrow_expiration: :point_in_time
|
12
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module Hive
|
2
|
+
module RPC
|
3
|
+
class BaseClient
|
4
|
+
include ChainConfig
|
5
|
+
|
6
|
+
attr_accessor :url, :chain, :error_pipe
|
7
|
+
|
8
|
+
# @private
|
9
|
+
MAX_TIMEOUT_RETRY_COUNT = 100
|
10
|
+
|
11
|
+
# @private
|
12
|
+
MAX_TIMEOUT_BACKOFF = 30
|
13
|
+
|
14
|
+
# @private
|
15
|
+
TIMEOUT_ERRORS = [Net::ReadTimeout, Errno::EBADF, IOError]
|
16
|
+
|
17
|
+
def initialize(options = {})
|
18
|
+
@chain = options[:chain] || :hive
|
19
|
+
@error_pipe = options[:error_pipe] || STDERR
|
20
|
+
@api_name = options[:api_name]
|
21
|
+
@url = case @chain
|
22
|
+
when :hive then options[:url] || NETWORKS_HIVE_DEFAULT_NODE
|
23
|
+
when :test then options[:url] || NETWORKS_TEST_DEFAULT_NODE
|
24
|
+
else; raise UnsupportedChainError, "Unsupported chain: #{@chain}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def uri
|
29
|
+
@uri ||= URI.parse(url)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Adds a request object to the stack. Usually, this method is called
|
33
|
+
# internally by {BaseClient#rpc_execute}. If you want to create a batched
|
34
|
+
# request, use this method to add to the batch then execute {BaseClient#rpc_batch_execute}.
|
35
|
+
def put(api_name = @api_name, api_method = nil, options = {})
|
36
|
+
current_rpc_id = rpc_id
|
37
|
+
rpc_method_name = "#{api_name}.#{api_method}"
|
38
|
+
options ||= {}
|
39
|
+
request_object = defined?(options.delete) ? options.delete(:request_object) : []
|
40
|
+
request_object ||= []
|
41
|
+
|
42
|
+
request_object << {
|
43
|
+
jsonrpc: '2.0',
|
44
|
+
id: current_rpc_id,
|
45
|
+
method: rpc_method_name,
|
46
|
+
params: options
|
47
|
+
}
|
48
|
+
|
49
|
+
request_object
|
50
|
+
end
|
51
|
+
|
52
|
+
# @abstract Subclass is expected to implement #rpc_execute.
|
53
|
+
# @!method rpc_execute
|
54
|
+
|
55
|
+
# @abstract Subclass is expected to implement #rpc_batch_execute.
|
56
|
+
# @!method rpc_batch_execute
|
57
|
+
|
58
|
+
# To be called by {BaseClient#rpc_execute} and {BaseClient#rpc_batch_execute}
|
59
|
+
# when a response has been consructed.
|
60
|
+
def yield_response(response, &block)
|
61
|
+
if !!block
|
62
|
+
case response
|
63
|
+
when Hashie::Mash then yield response.result, response.error, response.id
|
64
|
+
when Hashie::Array
|
65
|
+
response.each do |r|
|
66
|
+
r = Hashie::Mash.new(r)
|
67
|
+
block.call r.result, r.error, r.id
|
68
|
+
end
|
69
|
+
else; block.call response
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
response
|
74
|
+
end
|
75
|
+
|
76
|
+
# Checks json-rpc request/response for corrilated id. If they do not
|
77
|
+
# match, {IncorrectResponseIdError} is thrown. This is usually caused by
|
78
|
+
# the client, involving thread safety. It can also be caused by the node
|
79
|
+
# responding without an id.
|
80
|
+
#
|
81
|
+
# To avoid {IncorrectResponseIdError}, make sure you implement your client
|
82
|
+
# correctly.
|
83
|
+
#
|
84
|
+
# Setting DEBUG=true in the envrionment will cause this method to output
|
85
|
+
# both the request and response json.
|
86
|
+
#
|
87
|
+
# @param options [Hash] options
|
88
|
+
# @option options [Boolean] :debug Enable or disable debug output.
|
89
|
+
# @option options [Hash] :request to compare id
|
90
|
+
# @option options [Hash] :response to compare id
|
91
|
+
# @option options [String] :api_method
|
92
|
+
# @see {ThreadSafeHttpClient}
|
93
|
+
def evaluate_id(options = {})
|
94
|
+
debug = options[:debug] || ENV['DEBUG'] == 'true'
|
95
|
+
request = options[:request]
|
96
|
+
response = options[:response]
|
97
|
+
api_method = options[:api_method]
|
98
|
+
req_id = request[:id].to_i
|
99
|
+
res_id = !!response['id'] ? response['id'].to_i : nil
|
100
|
+
method = [@api_name, api_method].join('.')
|
101
|
+
|
102
|
+
if debug
|
103
|
+
req = JSON.pretty_generate(request)
|
104
|
+
res = JSON.parse(response) rescue response
|
105
|
+
res = JSON.pretty_generate(response) rescue response
|
106
|
+
|
107
|
+
error_pipe.puts '=' * 80
|
108
|
+
error_pipe.puts "Request:"
|
109
|
+
error_pipe.puts req
|
110
|
+
error_pipe.puts '=' * 80
|
111
|
+
error_pipe.puts "Response:"
|
112
|
+
error_pipe.puts res
|
113
|
+
error_pipe.puts '=' * 80
|
114
|
+
error_pipe.puts Thread.current.backtrace.join("\n")
|
115
|
+
end
|
116
|
+
|
117
|
+
error = response['error'].to_json if !!response['error']
|
118
|
+
|
119
|
+
if req_id != res_id
|
120
|
+
raise IncorrectResponseIdError, "#{method}: The json-rpc id did not match. Request was: #{req_id}, got: #{res_id.inspect}", BaseError.send(:build_backtrace, error)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Current json-rpc id used for a request. This version auto-increments
|
125
|
+
# for each call. Subclasses can use their own strategy.
|
126
|
+
def rpc_id
|
127
|
+
@rpc_id ||= 0
|
128
|
+
@rpc_id += 1
|
129
|
+
end
|
130
|
+
private
|
131
|
+
# @private
|
132
|
+
def reset_timeout
|
133
|
+
@timeout_retry_count = 0
|
134
|
+
@back_off = 0.1
|
135
|
+
end
|
136
|
+
|
137
|
+
# @private
|
138
|
+
def retry_timeout(context, cause = nil)
|
139
|
+
@timeout_retry_count += 1
|
140
|
+
|
141
|
+
if @timeout_retry_count > MAX_TIMEOUT_RETRY_COUNT
|
142
|
+
raise TooManyTimeoutsError.new("Too many timeouts for: #{context}", cause)
|
143
|
+
elsif @timeout_retry_count % 10 == 0
|
144
|
+
msg = "#{@timeout_retry_count} retry attempts for: #{context}"
|
145
|
+
msg += "; cause: #{cause}" if !!cause
|
146
|
+
error_pipe.puts msg
|
147
|
+
end
|
148
|
+
|
149
|
+
backoff_timeout
|
150
|
+
|
151
|
+
context
|
152
|
+
end
|
153
|
+
|
154
|
+
# Expontential backoff.
|
155
|
+
#
|
156
|
+
# @private
|
157
|
+
def backoff_timeout
|
158
|
+
@backoff ||= 0.1
|
159
|
+
@backoff *= 2
|
160
|
+
@backoff = 0.1 if @backoff > MAX_TIMEOUT_BACKOFF
|
161
|
+
|
162
|
+
sleep @backoff
|
163
|
+
end
|
164
|
+
|
165
|
+
# @private
|
166
|
+
def raise_error_response(rpc_method_name, rpc_args, response)
|
167
|
+
raise UnknownError, "#{rpc_method_name}: #{response}" if response.error.nil?
|
168
|
+
|
169
|
+
error = response.error
|
170
|
+
|
171
|
+
if error.message == 'Invalid Request'
|
172
|
+
raise Hive::ArgumentError, "Unexpected arguments: #{rpc_args.inspect}. Expected: #{rpc_method_name} (#{args_keys_to_s(rpc_method_name)})"
|
173
|
+
end
|
174
|
+
|
175
|
+
BaseError.build_error(error, rpc_method_name)
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|