43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# File 'lib/solana/ruby/kit/resource_limit_estimation.rb', line 43
def estimate_resource_limits_factory(rpc:)
->(transaction_message, commitment: nil, min_context_slot: nil) do
replace_recent_blockhash = !TransactionMessages.durable_nonce_lifetime?(transaction_message)
is_v1 = transaction_message.version == 1
tx_for_sim = Functional.pipe(
transaction_message,
->(m) { TransactionMessages.set_transaction_message_compute_unit_limit(TransactionMessages::MAX_COMPUTE_UNIT_LIMIT, m) },
->(m) { is_v1 ? TransactionMessages.set_transaction_message_loaded_accounts_data_size_limit(TransactionMessages::MAX_LOADED_ACCOUNTS_DATA_SIZE_LIMIT, m) : m }
)
transaction = Transactions.compile_transaction_message(tx_for_sim)
wire_bytes = Transactions.wire_encode_transaction(transaction)
encoded = Base64.strict_encode64(wire_bytes)
sim_opts = { replace_recent_blockhash: replace_recent_blockhash }
sim_opts[:commitment] = commitment if commitment
sim_opts[:min_context_slot] = min_context_slot if min_context_slot
begin
sim_value = rpc.simulate_transaction(encoded, **sim_opts).value
transaction_error = sim_value['err']
units_consumed = sim_value['unitsConsumed']
loaded_accounts_data_size = sim_value['loadedAccountsDataSize']
if is_v1 && loaded_accounts_data_size.nil?
Kernel.raise SolanaError.new(SolanaError::TRANSACTION__FAILED_TO_ESTIMATE_LOADED_ACCOUNTS_DATA_SIZE_LIMIT)
end
if transaction_error
Kernel.raise SolanaError.new(
SolanaError::TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_RESOURCE_LIMITS
)
end
compute_unit_limit = [units_consumed.to_i, 4_294_967_295].min
estimate = { compute_unit_limit: compute_unit_limit }
estimate[:loaded_accounts_data_size_limit] = loaded_accounts_data_size.to_i unless loaded_accounts_data_size.nil?
estimate
rescue SolanaError => e
known = [
SolanaError::TRANSACTION__FAILED_WHEN_SIMULATING_TO_ESTIMATE_RESOURCE_LIMITS,
SolanaError::TRANSACTION__FAILED_TO_ESTIMATE_LOADED_ACCOUNTS_DATA_SIZE_LIMIT
]
Kernel.raise if known.include?(e.code)
Kernel.raise SolanaError.new(SolanaError::TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT)
rescue StandardError
Kernel.raise SolanaError.new(SolanaError::TRANSACTION__FAILED_TO_ESTIMATE_COMPUTE_LIMIT)
end
end
end
|