Class: Hive::Marshal
Constant Summary
collapse
- PUBLIC_KEY_DISABLED =
'1111111111111111111111111111111114T1Anm'
Constants included
from ChainConfig
ChainConfig::EXPIRE_IN_SECS, ChainConfig::EXPIRE_IN_SECS_PROPOSAL, ChainConfig::NETWORKS_HIVE_ADDRESS_PREFIX, ChainConfig::NETWORKS_HIVE_CHAIN_ID, ChainConfig::NETWORKS_HIVE_CORE_ASSET, ChainConfig::NETWORKS_HIVE_DEBT_ASSET, ChainConfig::NETWORKS_HIVE_DEFAULT_NODE, ChainConfig::NETWORKS_HIVE_LEGACY_CHAIN_ID, ChainConfig::NETWORKS_HIVE_VEST_ASSET, ChainConfig::NETWORKS_TEST_ADDRESS_PREFIX, ChainConfig::NETWORKS_TEST_CHAIN_ID, ChainConfig::NETWORKS_TEST_CORE_ASSET, ChainConfig::NETWORKS_TEST_DEBT_ASSET, ChainConfig::NETWORKS_TEST_DEFAULT_NODE, ChainConfig::NETWORKS_TEST_VEST_ASSET, ChainConfig::NETWORK_CHAIN_IDS
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Utils
#hexlify, #unhexlify
Constructor Details
#initialize(options = {}) ⇒ Marshal
Returns a new instance of Marshal.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# File 'lib/hive/marshal.rb', line 13
def initialize(options = {})
@bytes = if !!(hex = options[:hex])
unhexlify hex
else
options[:bytes]
end
@chain = options[:chain] || :hive
@prefix ||= case @chain
when :hive then NETWORKS_HIVE_ADDRESS_PREFIX
when :test then NETWORKS_TEST_ADDRESS_PREFIX
else; raise UnsupportedChainError, "Unsupported chain: #{@chain}"
end
@cursor = 0
end
|
Instance Attribute Details
#bytes ⇒ Object
Returns the value of attribute bytes.
11
12
13
|
# File 'lib/hive/marshal.rb', line 11
def bytes
@bytes
end
|
#cursor ⇒ Object
Returns the value of attribute cursor.
11
12
13
|
# File 'lib/hive/marshal.rb', line 11
def cursor
@cursor
end
|
Instance Method Details
#amount ⇒ Object
101
102
103
104
105
106
107
108
109
|
# File 'lib/hive/marshal.rb', line 101
def amount
amount = uint64.to_f
precision = signed_char
asset = scan(7).strip
amount = "%.#{precision}f #{asset}" % (amount / 10 ** precision)
Hive::Type::Amount.new(amount)
end
|
#authority(options = {optional: false}) ⇒ Object
115
116
117
118
119
120
121
122
123
|
# File 'lib/hive/marshal.rb', line 115
def authority(options = {optional: false})
return if !!options[:optional] && unsigned_char == 0
{
weight_threshold: uint32,
account_auths: varint.times.map { [string, uint16] },
key_auths: varint.times.map { [public_key, uint16] }
}
end
|
#beneficiaries ⇒ Object
137
138
139
140
141
|
# File 'lib/hive/marshal.rb', line 137
def beneficiaries
if scan(1) == "\x00"
varint.times.map {{account: string, weight: uint16}}
end
end
|
#boolean ⇒ Object
59
|
# File 'lib/hive/marshal.rb', line 59
def boolean; scan(1) == "\x01"; end
|
#chain_properties ⇒ Object
143
144
145
146
147
148
149
|
# File 'lib/hive/marshal.rb', line 143
def chain_properties
{
account_creation_fee: amount,
maximum_block_size: uint32,
hbd_interest_rate: uint16
}
end
|
129
130
131
132
133
134
135
|
# File 'lib/hive/marshal.rb', line 129
def
if scan(1) == "\x01"
beneficiaries
else
[]
end
end
|
#empty_array ⇒ Object
178
179
180
|
# File 'lib/hive/marshal.rb', line 178
def empty_array
unsigned_char == 0 and [] or raise "Found non-empty array."
end
|
#hex ⇒ Object
29
30
31
|
# File 'lib/hive/marshal.rb', line 29
def hex
hexlify bytes
end
|
#int16 ⇒ Object
16-bit signed, little-endian
55
|
# File 'lib/hive/marshal.rb', line 55
def int16; BinData::Int16le.read(scan(2)); end
|
#int32 ⇒ Object
32-bit signed, little-endian
56
|
# File 'lib/hive/marshal.rb', line 56
def int32; BinData::Int32le.read(scan(4)); end
|
#int64 ⇒ Object
64-bit signed, little-endian
57
|
# File 'lib/hive/marshal.rb', line 57
def int64; BinData::Int64le.read(scan(8)); end
|
#operation_type ⇒ Object
45
46
47
|
# File 'lib/hive/marshal.rb', line 45
def operation_type
Operation::IDS[unsigned_char]
end
|
#operations ⇒ Object
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
|
# File 'lib/hive/marshal.rb', line 200
def operations
operations_len = signed_char
operations = []
while operations.size < operations_len do
begin
type = operation_type
break if type.nil?
op_class_name = type.to_s.sub!(/_operation$/, '')
op_class_name = "Hive::Operation::" + op_class_name.split('_').map(&:capitalize).join
op_class = Object::const_get(op_class_name)
op = op_class.new
op_class::serializable_types.each do |k, v|
begin
op.send("#{k}=", send(v))
rescue => e
raise DeserializationError.new("#{type}.#{k} (#{v}) failed", e)
end
end
operations << {type: type, value: op}
rescue => e
raise DeserializationError.new("#{type} failed", e)
end
end
operations
rescue => e
raise DeserializationError.new("Operations failed", e)
end
|
#optional_authority ⇒ Object
125
126
127
|
# File 'lib/hive/marshal.rb', line 125
def optional_authority
authority(optional: true)
end
|
#point_in_time ⇒ Object
85
86
87
88
89
90
91
|
# File 'lib/hive/marshal.rb', line 85
def point_in_time
if (time = uint32) == 2**32-1
Time.at -1
else
Time.at time
end.utc
end
|
#price ⇒ Object
111
112
113
|
# File 'lib/hive/marshal.rb', line 111
def price
{base: amount, quote: amount}
end
|
#public_key(prefix = @prefix) ⇒ Object
93
94
95
96
97
98
99
|
# File 'lib/hive/marshal.rb', line 93
def public_key(prefix = @prefix)
raw_public_key = raw_bytes(33)
checksum = OpenSSL::Digest::RIPEMD160.digest(raw_public_key)
key = Base58.binary_to_base58(raw_public_key + checksum.slice(0, 4), :bitcoin)
prefix + key unless key == PUBLIC_KEY_DISABLED
end
|
#raw_bytes(len = nil) ⇒ Object
83
|
# File 'lib/hive/marshal.rb', line 83
def raw_bytes(len = nil); scan(len || varint).force_encoding('BINARY'); end
|
#required_auths ⇒ Object
151
152
153
|
# File 'lib/hive/marshal.rb', line 151
def required_auths
varint.times.map { string }
end
|
#rewind! ⇒ Object
33
34
35
|
# File 'lib/hive/marshal.rb', line 33
def rewind!
@cursor = 0
end
|
#scan(len) ⇒ Object
41
42
43
|
# File 'lib/hive/marshal.rb', line 41
def scan(len)
bytes.slice(@cursor..(@cursor - 1) + len).tap { |_| @cursor += len }
end
|
#signed_char ⇒ Object
54
|
# File 'lib/hive/marshal.rb', line 54
def signed_char; BinData::Int8le.read(scan(1)); end
|
#step(n = 0) ⇒ Object
37
38
39
|
# File 'lib/hive/marshal.rb', line 37
def step(n = 0)
@cursor += n
end
|
#string(len = nil) ⇒ Object
81
|
# File 'lib/hive/marshal.rb', line 81
def string(len = nil); scan(len || varint); end
|
#transaction(options = {}) ⇒ Object
186
187
188
189
190
191
192
193
194
195
196
197
198
|
# File 'lib/hive/marshal.rb', line 186
def transaction(options = {})
trx = options[:trx] || Transaction.new
trx.ref_block_num = uint16
trx.ref_block_prefix = uint32
trx.expiration = point_in_time
trx.operations = operations
trx
rescue => e
raise DeserializationError.new("Transaction failed\nOriginal serialized bytes:\n[#{hex[0..(@cursor * 2) - 1]}]#{hex[((@cursor) * 2)..-1]}", e)
end
|
#uint16 ⇒ Object
16-bit unsigned, VAX (little-endian) byte order
50
|
# File 'lib/hive/marshal.rb', line 50
def uint16; BinData::Uint16le.read(scan(2)); end
|
#uint32 ⇒ Object
32-bit unsigned, VAX (little-endian) byte order
51
|
# File 'lib/hive/marshal.rb', line 51
def uint32; BinData::Uint32le.read(scan(4)); end
|
#uint64 ⇒ Object
64-bit unsigned, little-endian
52
|
# File 'lib/hive/marshal.rb', line 52
def uint64; BinData::Uint64le.read(scan(8)); end
|
#uint64_array ⇒ Object
182
183
184
|
# File 'lib/hive/marshal.rb', line 182
def uint64_array
varint.times{ uint64 }
end
|
#unsigned_char ⇒ Object
49
|
# File 'lib/hive/marshal.rb', line 49
def unsigned_char; BinData::Uint8le.read(scan(1)); end
|
#varint ⇒ Object
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
# File 'lib/hive/marshal.rb', line 61
def varint
shift = 0
result = 0
bytes = []
while (n = unsigned_char) >> 7 == 1
bytes << n
end
bytes << n
bytes.each do |b|
result += ((b & 0x7f) << shift)
break unless (b & 0x80)
shift += 7
end
result
end
|
#witness_properties ⇒ Object
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
|
# File 'lib/hive/marshal.rb', line 155
def witness_properties
properties = {}
varint.times do
key = string.to_sym
properties[key] = case key
when :account_creation_fee then Hive::Type::Amount.new(string)
when :hbd_exchange_rate
JSON[string].tap do |rate|
rate["base"] = Hive::Type::Amount.new(rate["base"])
rate["quote"] = Hive::Type::Amount.new(rate["quote"])
end
when :url, :key, :new_signing_key then string
else; warn "Unsupported witness property: #{key}"
end
end
properties
end
|