tigerbeetle 0.0.1.pre.dev → 0.0.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.
@@ -0,0 +1,213 @@
1
+ require 'ffi'
2
+ require 'tb_client'
3
+ require 'tigerbeetle/converters'
4
+ require 'tigerbeetle/account'
5
+ require 'tigerbeetle/account_balance'
6
+ require 'tigerbeetle/account_filter'
7
+ require 'tigerbeetle/query_filter'
8
+ require 'tigerbeetle/request'
9
+ require 'tigerbeetle/transfer'
10
+
11
+ module TigerBeetle
12
+ class Client
13
+ # TODO: Make this counter atomic
14
+ @counter = 0
15
+
16
+ def self.next_id
17
+ @counter += 1
18
+ end
19
+
20
+ def initialize(cluster_id = 0, address = '3000')
21
+ @inflight_requests = {}
22
+ # Keep a pointer to prevent proc from getting GCed
23
+ @callback = Proc.new { |*args| callback(*args) }
24
+ @client_id = self.class.next_id
25
+ @client = TBClient::Client.new
26
+
27
+ # FFI::MemoryPointer.new(:pointer, 1) # **void
28
+ cluster_id_ptr = serialize([cluster_id], Converters::UInt128)
29
+
30
+ status = TBClient.tb_client_init(
31
+ @client,
32
+ cluster_id_ptr,
33
+ address,
34
+ address.length,
35
+ @client_id,
36
+ &@callback
37
+ )
38
+ raise "Error while initializing client: #{status}" unless status == :SUCCESS
39
+
40
+ # Make sure to deinitialize all clients when the process terminates
41
+ at_exit { deinit }
42
+ end
43
+
44
+ def logger=(logger)
45
+ @logger = logger
46
+ @log_callback = @logger ? Proc.new { |*args| log_callback(*args) } : nil
47
+
48
+ status = TBClient.tb_client_register_log_callback(@log_callback, true)
49
+ raise "Error registering a logger: #{status}" unless status == :SUCCESS
50
+ end
51
+
52
+ def create_accounts(*accounts, &block)
53
+ submit_request(
54
+ :CREATE_ACCOUNTS,
55
+ accounts,
56
+ Converters::Account,
57
+ Converters::CreateAccountsResult,
58
+ &block
59
+ )
60
+ end
61
+
62
+ def create_transfers(*transfers, &block)
63
+ submit_request(
64
+ :CREATE_TRANSFERS,
65
+ transfers,
66
+ Converters::Transfer,
67
+ Converters::CreateTransfersResult,
68
+ &block
69
+ )
70
+ end
71
+
72
+ def lookup_accounts(*account_ids, &block)
73
+ submit_request(
74
+ :LOOKUP_ACCOUNTS,
75
+ account_ids,
76
+ Converters::UInt128,
77
+ Converters::Account,
78
+ &block
79
+ )
80
+ end
81
+
82
+ def lookup_transfers(*transfer_ids, &block)
83
+ submit_request(
84
+ :LOOKUP_TRANSFERS,
85
+ transfer_ids,
86
+ Converters::UInt128,
87
+ Converters::Transfer,
88
+ &block
89
+ )
90
+ end
91
+
92
+ def get_account_transfers(filter, &block)
93
+ submit_request(
94
+ :GET_ACCOUNT_TRANSFERS,
95
+ [filter],
96
+ Converters::AccountFilter,
97
+ Converters::Transfer,
98
+ &block
99
+ )
100
+ end
101
+
102
+ def get_account_balances(filter, &block)
103
+ submit_request(
104
+ :GET_ACCOUNT_BALANCES,
105
+ [filter],
106
+ Converters::AccountFilter,
107
+ Converters::AccountBalance,
108
+ &block
109
+ )
110
+ end
111
+
112
+ def query_accounts(filter, &block)
113
+ submit_request(
114
+ :QUERY_ACCOUNTS,
115
+ [filter],
116
+ Converters::QueryFilter,
117
+ Converters::Account,
118
+ &block
119
+ )
120
+ end
121
+
122
+ def query_transfers(filter, &block)
123
+ submit_request(
124
+ :QUERY_TRANSFERS,
125
+ [filter],
126
+ Converters::QueryFilter,
127
+ Converters::Transfer,
128
+ &block
129
+ )
130
+ end
131
+
132
+ def deinit
133
+ return unless client
134
+
135
+ TBClient.tb_client_deinit(client)
136
+ @client = nil
137
+ end
138
+
139
+ private
140
+
141
+ attr_reader :context, :client, :inflight_requests, :logger
142
+
143
+ def log_callback(level, ptr, length)
144
+ message = ptr.read_string(length).force_encoding('UTF-8')
145
+ case level
146
+ when :ERR then logger.error(message)
147
+ when :WARN then logger.warn(message)
148
+ when :INFO then logger.info(message)
149
+ when :DEBUG then logger.debug(message)
150
+ end
151
+ end
152
+
153
+ def callback(client_id, packet, timestamp, result_ptr, result_len)
154
+ request_id = packet[:user_data].read_uint64
155
+ request = inflight_requests[request_id]
156
+ result = deserialize(result_ptr, request.converter, result_len)
157
+ request.block.call(result)
158
+ end
159
+
160
+ def submit_request(operation, request, request_converter, response_converter, &block)
161
+ raise 'Client is not connected' unless client
162
+
163
+ request_id = self.class.next_id
164
+ user_data_ptr = FFI::MemoryPointer.new(:uint64, 1)
165
+ user_data_ptr.write_uint64(request_id)
166
+
167
+ data_ptr = serialize(request, request_converter)
168
+
169
+ packet = TBClient::Packet.new
170
+ packet[:user_data] = user_data_ptr
171
+ packet[:operation] = operation
172
+ packet[:status] = :OK
173
+ packet[:data_size] = data_ptr.size
174
+ packet[:data] = data_ptr
175
+
176
+ queue = Queue.new
177
+ inflight_requests[request_id] = Request.new(packet, response_converter) do |response|
178
+ if block
179
+ block.call(response)
180
+ else
181
+ queue << response
182
+ end
183
+ end
184
+
185
+ status = TBClient.tb_client_submit(client, packet)
186
+ raise "Unable to submit request: #{status}" unless status == :OK
187
+
188
+ # block until the client return a response
189
+ queue.pop unless block
190
+ end
191
+
192
+ def serialize(data, converter)
193
+ data_ptr = FFI::MemoryPointer.new(converter.native_type, data.length, true)
194
+ data.each_with_index do |value, i|
195
+ # initialize type at the memory address and write value over it
196
+ converter.to_native(data_ptr[i], value)
197
+ end
198
+
199
+ data_ptr
200
+ end
201
+
202
+ def deserialize(ptr, converter, length)
203
+ type = converter.native_type
204
+ # copy the memory own to retain the data after tb_client has freed its memory
205
+ own_ptr = FFI::MemoryPointer.new(:char, type.size * length)
206
+ own_ptr.put_bytes(0, ptr.read_bytes(type.size * length))
207
+
208
+ Array.new(length / type.size) do |i|
209
+ converter.from_native(own_ptr + i * type.size)
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,63 @@
1
+ require 'tb_client'
2
+ require 'tigerbeetle/account'
3
+ require 'tigerbeetle/converters/base'
4
+ require 'tigerbeetle/converters/time'
5
+ require 'tigerbeetle/converters/uint_128'
6
+
7
+ module TigerBeetle
8
+ module Converters
9
+ class Account < Base
10
+ def self.native_type
11
+ TBClient::Account
12
+ end
13
+
14
+ def from_native(ptr)
15
+ c_value = TBClient::Account.new(ptr)
16
+
17
+ TigerBeetle::Account.new(
18
+ id: Converters::UInt128.from_native(c_value[:id].to_ptr),
19
+ debits_pending: Converters::UInt128.from_native(c_value[:debits_pending].to_ptr),
20
+ debits_posted: Converters::UInt128.from_native(c_value[:debits_posted].to_ptr),
21
+ credits_pending: Converters::UInt128.from_native(c_value[:credits_pending].to_ptr),
22
+ credits_posted: Converters::UInt128.from_native(c_value[:credits_posted].to_ptr),
23
+ user_data_128: Converters::UInt128.from_native(c_value[:user_data_128].to_ptr),
24
+ user_data_64: c_value[:user_data_64],
25
+ user_data_32: c_value[:user_data_32],
26
+ ledger: c_value[:ledger],
27
+ code: c_value[:code],
28
+ flags: c_value[:flags],
29
+ timestamp: Converters::Time.from_native(ptr + c_value.offset_of(:timestamp))
30
+ )
31
+ end
32
+
33
+ def to_native(ptr, value)
34
+ validate_uint!(:id, 128, value.id)
35
+ validate_uint!(:debits_pending, 128, value.debits_pending)
36
+ validate_uint!(:debits_posted, 128, value.debits_posted)
37
+ validate_uint!(:credits_pending, 128, value.credits_pending)
38
+ validate_uint!(:credits_posted, 128, value.credits_posted)
39
+ validate_uint!(:user_data_128, 128, value.user_data_128)
40
+ validate_uint!(:user_data_64, 64, value.user_data_64)
41
+ validate_uint!(:user_data_32, 32, value.user_data_32)
42
+ validate_uint!(:ledger, 32, value.ledger)
43
+ validate_uint!(:code, 16, value.code)
44
+
45
+ TBClient::Account.new(ptr).tap do |result|
46
+ Converters::UInt128.to_native(result[:id].to_ptr, value.id)
47
+ Converters::UInt128.to_native(result[:debits_pending].to_ptr, value.debits_pending)
48
+ Converters::UInt128.to_native(result[:debits_posted].to_ptr, value.debits_posted)
49
+ Converters::UInt128.to_native(result[:credits_pending].to_ptr, value.credits_pending)
50
+ Converters::UInt128.to_native(result[:credits_posted].to_ptr, value.credits_posted)
51
+ Converters::UInt128.to_native(result[:user_data_128].to_ptr, value.user_data_128)
52
+ result[:user_data_64] = value.user_data_64
53
+ result[:user_data_32] = value.user_data_32
54
+ result[:reserved] = 0
55
+ result[:ledger] = value.ledger
56
+ result[:code] = value.code
57
+ result[:flags] = value.flags
58
+ Converters::Time.to_native(ptr + result.offset_of(:timestamp), value.timestamp || 0)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,31 @@
1
+ require 'tb_client'
2
+ require 'tigerbeetle/account_balance'
3
+ require 'tigerbeetle/converters/base'
4
+ require 'tigerbeetle/converters/time'
5
+ require 'tigerbeetle/converters/uint_128'
6
+
7
+ module TigerBeetle
8
+ module Converters
9
+ class AccountBalance < Base
10
+ def self.native_type
11
+ TBClient::AccountBalance
12
+ end
13
+
14
+ def from_native(ptr)
15
+ c_value = TBClient::AccountBalance.new(ptr)
16
+
17
+ TigerBeetle::AccountBalance.new(
18
+ debits_pending: Converters::UInt128.from_native(c_value[:debits_pending].to_ptr),
19
+ debits_posted: Converters::UInt128.from_native(c_value[:debits_posted].to_ptr),
20
+ credits_pending: Converters::UInt128.from_native(c_value[:credits_pending].to_ptr),
21
+ credits_posted: Converters::UInt128.from_native(c_value[:credits_posted].to_ptr),
22
+ timestamp: Converters::Time.from_native(ptr + c_value.offset_of(:timestamp))
23
+ )
24
+ end
25
+
26
+ def to_native(ptr, value)
27
+ raise 'Unexpected conversion of AccountBalance to native type'
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,32 @@
1
+ require 'tb_client'
2
+ require 'tigerbeetle/account_filter'
3
+ require 'tigerbeetle/converters/time'
4
+ require 'tigerbeetle/converters/uint_128'
5
+
6
+ module TigerBeetle
7
+ module Converters
8
+ class AccountFilter < Base
9
+ def self.native_type
10
+ TBClient::AccountFilter
11
+ end
12
+
13
+ def from_native(ptr)
14
+ raise 'Unexpected conversion of a native type to AccountFilter'
15
+ end
16
+
17
+ def to_native(ptr, value)
18
+ TBClient::AccountFilter.new(ptr).tap do |result|
19
+ Converters::UInt128.to_native(result[:account_id].to_ptr, value.account_id)
20
+ Converters::UInt128.to_native(result[:user_data_128].to_ptr, value.user_data_128)
21
+ result[:user_data_64] = value.user_data_64
22
+ result[:user_data_32] = value.user_data_32
23
+ result[:code] = value.code
24
+ Converters::Time.to_native(ptr + result.offset_of(:timestamp_min), value.timestamp_min || 0)
25
+ Converters::Time.to_native(ptr + result.offset_of(:timestamp_max), value.timestamp_max || 0)
26
+ result[:limit] = value.limit
27
+ result[:flags] = value.flags
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,35 @@
1
+ module TigerBeetle
2
+ module Converters
3
+ class Base
4
+ def self.from_native(ptr)
5
+ self.new.from_native(ptr)
6
+ end
7
+
8
+ def self.to_native(ptr, value)
9
+ self.new.to_native(ptr, value)
10
+ end
11
+
12
+ def self.native_type
13
+ raise NotImplementedError, 'Implement in sublcass'
14
+ end
15
+
16
+ def from_native(ptr)
17
+ raise NotImplementedError, 'Implement in sublcass'
18
+ end
19
+
20
+ def to_native(ptr, value)
21
+ raise NotImplementedError, 'Implement in sublcass'
22
+ end
23
+
24
+ private
25
+
26
+ def validate_uint!(name, bits, value)
27
+ if value > 2**bits - 1
28
+ raise ArgumentError, "#{name} == #{value} is too large to fit in #{bits} bits"
29
+ elsif value < 0
30
+ raise ArgumentError, "#{name} == #{value} cannot be negative"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,21 @@
1
+ require 'tb_client'
2
+ require 'tigerbeetle/converters/base'
3
+
4
+ module TigerBeetle
5
+ module Converters
6
+ class CreateAccountsResult < Base
7
+ def self.native_type
8
+ TBClient::CreateAccountsResult
9
+ end
10
+
11
+ def from_native(ptr)
12
+ c_value = TBClient::CreateAccountsResult.new(ptr)
13
+ [c_value[:index], c_value[:result]]
14
+ end
15
+
16
+ def to_native(ptr, value)
17
+ raise 'Unexpected conversion of CreateAccountsResult to a native type'
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,21 @@
1
+ require 'tb_client'
2
+ require 'tigerbeetle/converters/base'
3
+
4
+ module TigerBeetle
5
+ module Converters
6
+ class CreateTransfersResult < Base
7
+ def self.native_type
8
+ TBClient::CreateTransfersResult
9
+ end
10
+
11
+ def from_native(ptr)
12
+ c_value = TBClient::CreateTransfersResult.new(ptr)
13
+ [c_value[:index], c_value[:result]]
14
+ end
15
+
16
+ def to_native(ptr, value)
17
+ raise 'Unexpected conversion of CreateTransfersResult to a native type'
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,33 @@
1
+ require 'tb_client'
2
+ require 'tigerbeetle/query_filter'
3
+ require 'tigerbeetle/converters/base'
4
+ require 'tigerbeetle/converters/time'
5
+ require 'tigerbeetle/converters/uint_128'
6
+
7
+ module TigerBeetle
8
+ module Converters
9
+ class QueryFilter < Base
10
+ def self.native_type
11
+ TBClient::QueryFilter
12
+ end
13
+
14
+ def from_native(ptr)
15
+ raise 'Unexpected conversion of a native type to QueryFilter'
16
+ end
17
+
18
+ def to_native(ptr, value)
19
+ TBClient::QueryFilter.new(ptr).tap do |result|
20
+ Converters::UInt128.to_native(result[:user_data_128].to_ptr, value.user_data_128)
21
+ result[:user_data_64] = value.user_data_64
22
+ result[:user_data_32] = value.user_data_32
23
+ result[:code] = value.code
24
+ result[:ledger] = value.ledger
25
+ Converters::Time.to_native(ptr + result.offset_of(:timestamp_min), value.timestamp_min || 0)
26
+ Converters::Time.to_native(ptr + result.offset_of(:timestamp_max), value.timestamp_max || 0)
27
+ result[:limit] = value.limit
28
+ result[:flags] = value.flags
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,23 @@
1
+ require 'ffi'
2
+ require 'tigerbeetle/converters/base'
3
+
4
+ module TigerBeetle
5
+ module Converters
6
+ class Time < Base
7
+ def self.native_type
8
+ FFI::Type::UINT64
9
+ end
10
+
11
+ def from_native(ptr)
12
+ ::Time.at(ptr.read(FFI::Type::UINT64) / 1e9)
13
+ end
14
+
15
+ def to_native(ptr, value)
16
+ int = (value.to_f * 1e9).to_i
17
+ validate_uint!(:timestamp, 64, int)
18
+
19
+ ptr.write(FFI::Type::UINT64, int)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,64 @@
1
+ require 'tb_client'
2
+ require 'tigerbeetle/transfer'
3
+ require 'tigerbeetle/converters/base'
4
+ require 'tigerbeetle/converters/time'
5
+ require 'tigerbeetle/converters/uint_128'
6
+
7
+ module TigerBeetle
8
+ module Converters
9
+ class Transfer < Base
10
+ def self.native_type
11
+ TBClient::Transfer
12
+ end
13
+
14
+ def from_native(ptr)
15
+ c_value = TBClient::Transfer.new(ptr)
16
+
17
+ TigerBeetle::Transfer.new(
18
+ id: Converters::UInt128.from_native(c_value[:id].to_ptr),
19
+ debit_account_id: Converters::UInt128.from_native(c_value[:debit_account_id].to_ptr),
20
+ credit_account_id: Converters::UInt128.from_native(c_value[:credit_account_id].to_ptr),
21
+ amount: Converters::UInt128.from_native(c_value[:amount].to_ptr),
22
+ pending_id: Converters::UInt128.from_native(c_value[:pending_id].to_ptr),
23
+ user_data_128: Converters::UInt128.from_native(c_value[:user_data_128].to_ptr),
24
+ user_data_64: c_value[:user_data_64],
25
+ user_data_32: c_value[:user_data_32],
26
+ timeout: c_value[:timeout],
27
+ ledger: c_value[:ledger],
28
+ code: c_value[:code],
29
+ flags: c_value[:flags],
30
+ timestamp: Converters::Time.from_native(ptr + c_value.offset_of(:timestamp))
31
+ )
32
+ end
33
+
34
+ def to_native(ptr, value)
35
+ validate_uint!(:id, 128, value.id)
36
+ validate_uint!(:debit_account_id, 128, value.debit_account_id)
37
+ validate_uint!(:credit_account_id, 128, value.credit_account_id)
38
+ validate_uint!(:amount, 128, value.amount)
39
+ validate_uint!(:user_data_128, 128, value.user_data_128)
40
+ validate_uint!(:user_data_64, 64, value.user_data_64)
41
+ validate_uint!(:user_data_32, 32, value.user_data_32)
42
+ validate_uint!(:timeout, 32, value.timeout)
43
+ validate_uint!(:ledger, 32, value.ledger)
44
+ validate_uint!(:code, 16, value.code)
45
+
46
+ TBClient::Transfer.new(ptr).tap do |result|
47
+ Converters::UInt128.to_native(result[:id].to_ptr, value.id)
48
+ Converters::UInt128.to_native(result[:debit_account_id].to_ptr, value.debit_account_id)
49
+ Converters::UInt128.to_native(result[:credit_account_id].to_ptr, value.credit_account_id)
50
+ Converters::UInt128.to_native(result[:amount].to_ptr, value.amount)
51
+ Converters::UInt128.to_native(result[:pending_id].to_ptr, value.pending_id)
52
+ Converters::UInt128.to_native(result[:user_data_128].to_ptr, value.user_data_128)
53
+ result[:user_data_64] = value.user_data_64
54
+ result[:user_data_32] = value.user_data_32
55
+ result[:timeout] = value.timeout
56
+ result[:ledger] = value.ledger
57
+ result[:code] = value.code
58
+ result[:flags] = value.flags
59
+ Converters::Time.to_native(ptr + result.offset_of(:timestamp), value.timestamp || 0)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,24 @@
1
+ require 'tb_client'
2
+ require 'tigerbeetle/converters/base'
3
+
4
+ module TigerBeetle
5
+ module Converters
6
+ class UInt128 < Base
7
+ def self.native_type
8
+ TBClient::UInt128
9
+ end
10
+
11
+ def from_native(ptr)
12
+ c_value = TBClient::UInt128.new(ptr)
13
+ c_value[:low] + (c_value[:high] << 64)
14
+ end
15
+
16
+ def to_native(ptr, value)
17
+ TBClient::UInt128.new(ptr).tap do |result|
18
+ result[:low] = value % 2**64
19
+ result[:high] = value >> 64
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,12 @@
1
+ require 'tigerbeetle/converters/account'
2
+ require 'tigerbeetle/converters/account_balance'
3
+ require 'tigerbeetle/converters/account_filter'
4
+ require 'tigerbeetle/converters/create_accounts_result'
5
+ require 'tigerbeetle/converters/create_transfers_result'
6
+ require 'tigerbeetle/converters/query_filter'
7
+ require 'tigerbeetle/converters/time'
8
+ require 'tigerbeetle/converters/transfer'
9
+ require 'tigerbeetle/converters/uint_128'
10
+
11
+ module Converters
12
+ end
@@ -0,0 +1,30 @@
1
+ require 'securerandom'
2
+
3
+ module TigerBeetle
4
+ module ID
5
+ @last_time_ms = 0
6
+
7
+ # Generates a Universally Unique and Sortable Identifier as a 128-bit integer. Based on ULIDs
8
+ # Inspired by ext/tb_client/tigerbeetle/src/clients/python/src/tigerbeetle/client.py#id
9
+ def self.generate
10
+ rnd_bytes = SecureRandom.random_bytes(10)
11
+ time_ms = (Time.now.to_f * 1000).to_i
12
+
13
+ # Ensure time_ms monotonically increases
14
+ if time_ms <= @last_time_ms
15
+ time_ms = @last_time_ms
16
+ else
17
+ @last_time_ms = time_ms
18
+ end
19
+
20
+ # Convert time_ms integer to 6 bytes (string) in big-endian
21
+ time_bytes = [time_ms].pack("Q>")[2..7]
22
+
23
+ # Combine time and randomness and convert to two 64-bit integers in big-endian
24
+ integers = (time_bytes + rnd_bytes).unpack("Q>Q>")
25
+
26
+ # Re-combine into a single 128-bit integer in big-endian
27
+ integers[0] << 64 | integers[1]
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,31 @@
1
+ module TigerBeetle
2
+ QUERY_FILTER_PARAMS = %i[
3
+ user_data_128 user_data_64 user_data_32 ledger code timestamp_min timestamp_max limit flags
4
+ ]
5
+
6
+ QueryFilter = Struct.new(*QUERY_FILTER_PARAMS) do
7
+ def initialize(
8
+ user_data_128: 0,
9
+ user_data_64: 0,
10
+ user_data_32: 0,
11
+ ledger: 0,
12
+ code: 0,
13
+ timestamp_min: 0,
14
+ timestamp_max: 0,
15
+ limit: 0,
16
+ flags: []
17
+ )
18
+ super(
19
+ user_data_128,
20
+ user_data_64,
21
+ user_data_32,
22
+ ledger,
23
+ code,
24
+ timestamp_min,
25
+ timestamp_max,
26
+ limit,
27
+ flags
28
+ )
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ module TigerBeetle
2
+ Request = Struct.new(:packet, :converter, :block) do
3
+ def initialize(packet, converter, &block)
4
+ super(packet, converter, block)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,40 @@
1
+ module TigerBeetle
2
+ TRANSFER_PARAMS = %i[
3
+ id debit_account_id credit_account_id amount pending_id user_data_128
4
+ user_data_64 user_data_32 timeout ledger code flags timestamp
5
+ ]
6
+
7
+ Transfer = Struct.new(*TRANSFER_PARAMS) do
8
+ def initialize(
9
+ id: 0,
10
+ debit_account_id: 0,
11
+ credit_account_id: 0,
12
+ amount: 0,
13
+ pending_id: 0,
14
+ user_data_128: 0,
15
+ user_data_64: 0,
16
+ user_data_32: 0,
17
+ timeout: 0,
18
+ ledger: 0,
19
+ code: 0,
20
+ flags: [],
21
+ timestamp: nil
22
+ )
23
+ super(
24
+ id,
25
+ debit_account_id,
26
+ credit_account_id,
27
+ amount,
28
+ pending_id,
29
+ user_data_128,
30
+ user_data_64,
31
+ user_data_32,
32
+ timeout,
33
+ ledger,
34
+ code,
35
+ flags,
36
+ timestamp
37
+ )
38
+ end
39
+ end
40
+ end