Class: StellarCoreCommander::Transactor
- Inherits:
-
Object
- Object
- StellarCoreCommander::Transactor
show all
- Includes:
- Contracts
- Defined in:
- lib/stellar_core_commander/transactor.rb
Overview
A transactor plays transactions against a stellar-core test node.
Defined Under Namespace
Classes: FailedTransaction, MissingTransaction
Instance Attribute Summary collapse
Class Method Summary
collapse
-
.recipe_step(name) ⇒ Object
recipe_step is a helper method to define a method that follows the common procedure of executing a recipe step:.
Instance Method Summary
collapse
Constructor Details
#initialize(commander) ⇒ Transactor
Returns a new instance of Transactor.
18
19
20
21
22
23
24
25
26
27
28
|
# File 'lib/stellar_core_commander/transactor.rb', line 18
def initialize(commander)
@commander = commander
@named = {}.with_indifferent_access
@operation_builder = OperationBuilder.new(self)
@manual_close = false
network_passphrase = @commander.process_options[:network_passphrase]
Stellar.on_network network_passphrase do
account :master, Stellar::KeyPair.master
end
end
|
Instance Attribute Details
#manual_close ⇒ Object
Returns the value of attribute manual_close.
15
16
17
|
# File 'lib/stellar_core_commander/transactor.rb', line 15
def manual_close
@manual_close
end
|
Class Method Details
.recipe_step(name) ⇒ Object
recipe_step is a helper method to define
a method that follows the common procedure of executing a recipe step:
- ensure all processes are running
- build the envelope by forwarding to the operation builder
- submit the envelope to the process
85
86
87
88
89
90
91
|
# File 'lib/stellar_core_commander/transactor.rb', line 85
def self.recipe_step(name)
define_method name do |*args|
require_process_running
envelope = @operation_builder.send(name, *args)
submit_transaction envelope
end
end
|
Instance Method Details
#account(name, keypair = Stellar::KeyPair.random) ⇒ Object
Registered an account for this scenario. Future calls may refer to
the name provided.
72
73
74
|
# File 'lib/stellar_core_commander/transactor.rb', line 72
def account(name, keypair=Stellar::KeyPair.random)
add_named name, keypair
end
|
#account_created(account) ⇒ Object
306
307
308
309
310
311
312
313
314
315
316
317
|
# File 'lib/stellar_core_commander/transactor.rb', line 306
def account_created(account)
require_process_running
if account.is_a?(Symbol)
account = get_account(account)
end
begin
@process.account_row(account)
return true
rescue
return false
end
end
|
#balance(account) ⇒ Object
320
321
322
323
324
325
326
327
|
# File 'lib/stellar_core_commander/transactor.rb', line 320
def balance(account)
require_process_running
if account.is_a?(Symbol)
account = get_account(account)
end
raise "no process!" unless @process
@process.balance_for(account)
end
|
#catchup(ledger, mode = :minimal) ⇒ Object
197
198
199
200
|
# File 'lib/stellar_core_commander/transactor.rb', line 197
def catchup(ledger, mode=:minimal)
require_process_running
@process.catchup ledger, mode
end
|
#check_database_against_ledger_buckets ⇒ Object
362
363
364
365
366
367
368
369
370
|
# File 'lib/stellar_core_commander/transactor.rb', line 362
def check_database_against_ledger_buckets
runs = @process.checkdb_runs
@process.start_checkdb
retry_until_true do
r = @process.checkdb_runs
$stderr.puts "checkdb runs: #{r}, checked: #{@process.objects_checked}"
r != runs
end
end
|
#check_equal_ledger_objects(processes) ⇒ Object
341
342
343
344
345
346
347
348
349
350
|
# File 'lib/stellar_core_commander/transactor.rb', line 341
def check_equal_ledger_objects(processes)
raise "no process!" unless @process
for p in processes
if p.is_a?(Symbol)
p = get_process(p)
end
@process.check_equal_ledger_objects(p)
end
true
end
|
#check_integrity_against(other) ⇒ Object
373
374
375
376
377
378
|
# File 'lib/stellar_core_commander/transactor.rb', line 373
def check_integrity_against(other)
check_no_error_metrics
check_database_against_ledger_buckets
check_equal_ledger_objects [other]
check_ledger_sequence_is_prefix_of other
end
|
#check_ledger_sequence_is_prefix_of(other) ⇒ Object
353
354
355
356
357
358
359
|
# File 'lib/stellar_core_commander/transactor.rb', line 353
def check_ledger_sequence_is_prefix_of(other)
raise "no process!" unless @process
if other.is_a?(Symbol)
other = get_process(other)
end
@process.check_ledger_sequence_is_prefix_of(other)
end
|
#check_no_error_metrics ⇒ Object
336
337
338
|
# File 'lib/stellar_core_commander/transactor.rb', line 336
def check_no_error_metrics
@commander.check_no_process_error_metrics
end
|
#close_ledger ⇒ Object
Triggers a ledger close. Any unvalidated transaction will
be validated, which will trigger an error if any fail to be validated
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
|
# File 'lib/stellar_core_commander/transactor.rb', line 168
def close_ledger
require_process_running
@process.close_ledger
@process.unverified.each do |eb|
begin
envelope, after_confirmation = *eb
result = validate_transaction envelope
after_confirmation.call(result) if after_confirmation
rescue MissingTransaction
$stderr.puts "Failed to validate tx: #{Convert.to_hex envelope.tx.hash}"
$stderr.puts "could not be found in txhistory table on process #{@process.name}"
rescue FailedTransaction
$stderr.puts "Failed to validate tx: #{Convert.to_hex envelope.tx.hash}"
$stderr.puts "failed result: #{result.to_xdr(:base64)}"
exit 1
end
end
@process.unverified.clear
end
|
#crash ⇒ Object
203
204
205
|
# File 'lib/stellar_core_commander/transactor.rb', line 203
def crash
@process.crash
end
|
#generate_load_and_await_completion(accounts, txs, txrate) ⇒ Object
238
239
240
241
242
243
244
245
246
247
248
249
|
# File 'lib/stellar_core_commander/transactor.rb', line 238
def generate_load_and_await_completion(accounts, txs, txrate)
runs = @process.load_generation_runs
start_load_generation accounts, txs, txrate
retry_until_true retries: accounts + txs do
txs = @process.transactions_applied
r = @process.load_generation_runs
tps = @process.transactions_per_second
ops = @process.operations_per_second
$stderr.puts "loadgen runs: #{r}, ledger: #{ledger_num}, txs: #{txs}, actual tx/s: #{tps} op/s: #{ops}"
r != runs
end
end
|
#get_account(name) ⇒ Object
208
209
210
211
212
213
214
215
|
# File 'lib/stellar_core_commander/transactor.rb', line 208
def get_account(name)
require_process_running
@named[name].tap do |found|
unless found.is_a?(Stellar::KeyPair)
raise ArgumentError, "#{name.inspect} is not account"
end
end
end
|
#get_process(name) ⇒ Object
218
219
220
221
222
223
224
|
# File 'lib/stellar_core_commander/transactor.rb', line 218
def get_process(name)
@named[name].tap do |found|
unless found.is_a?(Process)
raise ArgumentError, "#{name.inspect} is not process"
end
end
end
|
#ledger_num ⇒ Object
191
192
193
194
|
# File 'lib/stellar_core_commander/transactor.rb', line 191
def ledger_num
require_process_running
@process.ledger_num
end
|
#load_generation_complete ⇒ Object
233
234
235
|
# File 'lib/stellar_core_commander/transactor.rb', line 233
def load_generation_complete
@process.load_generation_complete
end
|
#metrics ⇒ Object
252
253
254
|
# File 'lib/stellar_core_commander/transactor.rb', line 252
def metrics
@process.metrics
end
|
#next_sequence(account) ⇒ Object
297
298
299
300
301
302
303
|
# File 'lib/stellar_core_commander/transactor.rb', line 297
def next_sequence(account)
require_process_running
base_sequence = @process.sequence_for(account)
inflight_count = @process.unverified.select{|e| e.first.tx.source_account == account.public_key}.length
base_sequence + inflight_count + 1
end
|
#on(process_name) ⇒ Object
270
271
272
273
274
275
276
277
278
279
|
# File 'lib/stellar_core_commander/transactor.rb', line 270
def on(process_name)
require_process_running
tmp = @process
p = get_process process_name
$stderr.puts "executing steps on #{p.idname}"
@process = p
yield
ensure
@process = tmp
end
|
#payment(*args) ⇒ Object
96
97
98
99
100
101
102
103
104
|
# File 'lib/stellar_core_commander/transactor.rb', line 96
def payment(*args)
require_process_running
envelope = @operation_builder.payment(*args)
submit_transaction envelope do |result|
payment_result = result.result.results!.first.tr!.value
raise FailedTransaction unless payment_result.code.value >= 0
end
end
|
#process(name, quorum = [name], options = {}) ⇒ Object
257
258
259
260
261
262
263
264
265
266
267
|
# File 'lib/stellar_core_commander/transactor.rb', line 257
def process(name, quorum=[name], options={})
if @manual_close and quorum.size != 1
raise "Cannot use `process` with multi-node quorum, this recipe has previously declared `use_manual_close`."
end
$stderr.puts "creating process #{name}"
p = @commander.make_process self, name, quorum, options
$stderr.puts "process #{name} is #{p.idname}"
add_named name, p
end
|
#require_process_running ⇒ Object
30
31
32
33
34
35
36
37
38
39
40
41
|
# File 'lib/stellar_core_commander/transactor.rb', line 30
def require_process_running
if @process.nil?
@process = @commander.get_root_process self
if not @named.has_key? @process.name
add_named @process.name, @process
end
end
@commander.start_all_processes
@commander.require_processes_in_sync
end
|
#retry_until_true(**opts, &block) ⇒ Object
281
282
283
284
285
286
287
288
289
290
291
292
293
294
|
# File 'lib/stellar_core_commander/transactor.rb', line 281
def retry_until_true(**opts, &block)
retries = opts[:retries] || 20
timeout = opts[:timeout] || 3
while retries > 0
b = begin yield block end
if b
return b
end
retries -= 1
$stderr.puts "sleeping #{timeout} secs, #{retries} retries left"
sleep timeout
end
raise "Ran out of retries while waiting for success"
end
|
#run_recipe(recipe_path) ⇒ Object
Runs the provided recipe against the process identified by @process
53
54
55
56
57
58
59
60
61
|
# File 'lib/stellar_core_commander/transactor.rb', line 53
def run_recipe(recipe_path)
recipe_content = IO.read(recipe_path)
network_passphrase = @commander.process_options[:network_passphrase]
Stellar.on_network network_passphrase do
instance_eval recipe_content, recipe_path, 1
end
rescue => e
crash_recipe e
end
|
#shutdown(*args) ⇒ Object
43
44
45
|
# File 'lib/stellar_core_commander/transactor.rb', line 43
def shutdown(*args)
@process.shutdown *args
end
|
#start_load_generation(accounts = 10000000, txs = 10000000, txrate = 500) ⇒ Object
227
228
229
230
|
# File 'lib/stellar_core_commander/transactor.rb', line 227
def start_load_generation(accounts=10000000, txs=10000000, txrate=500)
$stderr.puts "starting load generation: #{accounts} accounts, #{txs} txs, #{txrate} tx/s"
@process.start_load_generation accounts, txs, txrate
end
|
#use_manual_close ⇒ Object
330
331
332
333
|
# File 'lib/stellar_core_commander/transactor.rb', line 330
def use_manual_close()
$stderr.puts "using manual_close mode"
@manual_close = true
end
|