Class: TezosClient::OperationMgr

Inherits:
Object
  • Object
show all
Includes:
Crypto
Defined in:
lib/tezos_client/operation_mgr.rb

Constant Summary

Constants included from Crypto

Crypto::PREFIXES, Crypto::WATERMARK

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Crypto

#checksum, #decode_account_wallet, #decode_base58, #decode_tz, #edsk2_to_edsk, #encode_base58, #encode_script_expr, #encode_tz, #generate_key, #generate_mnemonic, #get_prefix_and_payload, #hex_prefix, #operation_id, #public_key_to_address, #secret_key_to_public_key, #sign_bytes, #sign_operation, #signing_key

Constructor Details

#initialize(rpc_interface:, rpc_operation_args:, **args) ⇒ OperationMgr

Returns a new instance of OperationMgr.



13
14
15
16
17
18
19
20
21
22
# File 'lib/tezos_client/operation_mgr.rb', line 13

def initialize(rpc_interface:, rpc_operation_args:, **args)
  @rpc_interface = rpc_interface
  @secret_key = args.fetch(:secret_key)
  @multiple_operations = rpc_operation_args.is_a?(Array)
  @rpc_operation_args = @multiple_operations ? rpc_operation_args : [rpc_operation_args]
  @signed_operation_args_h = nil
  @branch = args[:branch]
  @protocol = args[:protocol]
  @ignore_counter_error = args[:ignore_counter_error]
end

Instance Attribute Details

#rpc_interfaceObject

Returns the value of attribute rpc_interface.



10
11
12
# File 'lib/tezos_client/operation_mgr.rb', line 10

def rpc_interface
  @rpc_interface
end

#rpc_operation_argsObject

Returns the value of attribute rpc_operation_args.



10
11
12
# File 'lib/tezos_client/operation_mgr.rb', line 10

def rpc_operation_args
  @rpc_operation_args
end

Instance Method Details

#base_58_signatureObject



85
86
87
88
# File 'lib/tezos_client/operation_mgr.rb', line 85

def base_58_signature
  sign unless signed?
  @base_58_signature
end

#branchObject



36
37
38
# File 'lib/tezos_client/operation_mgr.rb', line 36

def branch
  @branch ||= rpc_interface.head_hash
end

#broadcastObject



194
195
196
197
198
199
200
201
# File 'lib/tezos_client/operation_mgr.rb', line 194

def broadcast
  self.rpc_operation_args = ::TezosClient::ComputeOperationArgsCounters.new(
    pending_operations: rpc_interface.pending_operations,
    operation_args: rpc_operation_args
  ).call if ignore_counter_error?

  rpc_interface.broadcast_operation(signed_hex)
end

#chain_idObject



44
45
46
# File 'lib/tezos_client/operation_mgr.rb', line 44

def chain_id
  @chain_id ||= rpc_interface.chain_id
end

#compute_consumed_gas(metadata) ⇒ Object



167
168
169
170
171
172
173
174
175
176
# File 'lib/tezos_client/operation_mgr.rb', line 167

def compute_consumed_gas()
  consumed_gas = (.dig(:operation_result, :consumed_gas) || "0").to_i

  if .key?(:internal_operation_results)
    [:internal_operation_results].each do |internal_operation_result|
      consumed_gas += (internal_operation_result[:result][:consumed_gas] || "0").to_i
    end
  end
  consumed_gas
end

#compute_consumed_storage(metadata) ⇒ Object



178
179
180
# File 'lib/tezos_client/operation_mgr.rb', line 178

def compute_consumed_storage()
  (.dig(:operation_result, :paid_storage_size_diff) || "0").to_i.from_satoshi
end

#consumed_tez(rpc_responses) ⇒ Object



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/tezos_client/operation_mgr.rb', line 151

def consumed_tez(rpc_responses)
  total_consumed_storage = 0
  total_consumed_gas = 0

  rpc_responses.each do |rpc_response|
     = rpc_response[:metadata]
    total_consumed_storage += compute_consumed_storage()
    total_consumed_gas += compute_consumed_gas()
  end

  {
    consumed_storage: total_consumed_storage,
    consumed_gas: total_consumed_gas
  }
end

#convert_rpc_response(rpc_responses) ⇒ Object



127
128
129
130
131
132
133
134
135
# File 'lib/tezos_client/operation_mgr.rb', line 127

def convert_rpc_response(rpc_responses)
  converted_rpc_responce = {
    status: :applied,
    operation_results: operation_results(rpc_responses),
    internal_operation_results: internal_operation_result(rpc_responses)
  }

  converted_rpc_responce.merge(consumed_tez(rpc_responses))
end

#ignore_counter_error?Boolean

Returns:

  • (Boolean)


28
29
30
# File 'lib/tezos_client/operation_mgr.rb', line 28

def ignore_counter_error?
  !!@ignore_counter_error
end

#internal_operation_result(rpc_responses) ⇒ Object



145
146
147
148
149
# File 'lib/tezos_client/operation_mgr.rb', line 145

def internal_operation_result(rpc_responses)
  rpc_responses.map do |rpc_response|
    rpc_response[:metadata][:internal_operation_results]
  end.compact.flatten
end

#multiple_operations?Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/tezos_client/operation_mgr.rb', line 24

def multiple_operations?
  @multiple_operations
end

#operation_results(rpc_responses) ⇒ Object



137
138
139
140
141
142
143
# File 'lib/tezos_client/operation_mgr.rb', line 137

def operation_results(rpc_responses)
  rpc_responses.map do |rpc_response|
     = rpc_response[:metadata]
    [:operation_result][:consumed_gas] = compute_consumed_gas() if .key? :operation_result
    [:operation_result]
  end
end

#preapplyObject



182
183
184
185
186
187
188
189
190
191
192
# File 'lib/tezos_client/operation_mgr.rb', line 182

def preapply
  rpc_responses = rpc_interface.preapply_operations(
    operations: rpc_operation_args,
    signature: base_58_signature,
    protocol: protocol,
    branch: branch)

  ensure_applied!(rpc_responses)

  convert_rpc_response(rpc_responses)
end

#protocolObject



40
41
42
# File 'lib/tezos_client/operation_mgr.rb', line 40

def protocol
  @protocol ||= rpc_interface.protocol
end

#runObject



114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/tezos_client/operation_mgr.rb', line 114

def run
  rpc_responses = rpc_interface.run_operations(
    operations: rpc_operation_args,
    signature: RANDOM_SIGNATURE,
    branch: branch,
    chain_id: chain_id
  )

  ensure_applied!(rpc_responses)

  convert_rpc_response(rpc_responses)
end

#signObject

Raises:

  • (ArgumentError)


68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/tezos_client/operation_mgr.rb', line 68

def sign
  raise ArgumentError, "Invalid secret key" unless valid_secret_key?

  sign_operation(
    secret_key: @secret_key,
    operation_hex: to_hex
  ) do |base_58_signature, signed_hex, _op_id|
    @signed_operation_args_h = rpc_operation_args.hash
    @base_58_signature = base_58_signature
    @signed_hex = signed_hex
  end
end

#signed?Boolean

Returns:

  • (Boolean)


81
82
83
# File 'lib/tezos_client/operation_mgr.rb', line 81

def signed?
  @signed_operation_args_h == rpc_operation_args.hash
end

#signed_hexObject



90
91
92
93
# File 'lib/tezos_client/operation_mgr.rb', line 90

def signed_hex
  sign unless signed?
  @signed_hex
end

#simulateObject



95
96
97
98
99
100
101
102
103
# File 'lib/tezos_client/operation_mgr.rb', line 95

def simulate
  # simulate operations and adjust gas limits
  run_result = simulate_and_update_limits
  if valid_secret_key?
    preapply
  else
    run_result
  end
end

#simulate_and_update_limitsObject



48
49
50
51
52
53
54
55
56
57
58
# File 'lib/tezos_client/operation_mgr.rb', line 48

def simulate_and_update_limits
  run_result = run

  run_result[:operation_results].zip(rpc_operation_args) do |operation_result, rpc_operation_args|
    if rpc_operation_args.key?(:gas_limit)
      rpc_operation_args[:gas_limit] = (operation_result[:consumed_gas].to_i.from_satoshi + 0.001).to_satoshi.to_s
    end
  end

  run_result
end

#single_operation?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'lib/tezos_client/operation_mgr.rb', line 32

def single_operation?
  !multiple_operations?
end

#test_and_broadcastObject



105
106
107
108
109
110
111
112
# File 'lib/tezos_client/operation_mgr.rb', line 105

def test_and_broadcast
  simulate_res = simulate
  op_id = broadcast

  simulate_res.merge(
    operation_id: op_id,
  )
end

#to_hexObject



60
61
62
# File 'lib/tezos_client/operation_mgr.rb', line 60

def to_hex
  rpc_interface.forge_operations(operations: rpc_operation_args, branch: branch)
end

#valid_secret_key?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/tezos_client/operation_mgr.rb', line 64

def valid_secret_key?
  @secret_key&.match?(/^edsk/)
end