xrbp 0.2.2 → 0.2.3
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.
- checksums.yaml +4 -4
- data/examples/nodestore1.rb +3 -1
- data/lib/xrbp/common.rb +6 -0
- data/lib/xrbp/core_ext.rb +21 -0
- data/lib/xrbp/nodestore/format.rb +76 -26
- data/lib/xrbp/nodestore/ledger.rb +46 -14
- data/lib/xrbp/nodestore/parser.rb +47 -14
- data/lib/xrbp/nodestore/protocol/indexes.rb +11 -8
- data/lib/xrbp/nodestore/protocol/issue.rb +15 -0
- data/lib/xrbp/nodestore/protocol/rate.rb +13 -1
- data/lib/xrbp/nodestore/shamap/node_factory.rb +6 -1
- data/lib/xrbp/nodestore/shamap/node_id.rb +2 -2
- data/lib/xrbp/nodestore/sle/st_amount.rb +46 -181
- data/lib/xrbp/nodestore/sle/st_amount_arithmatic.rb +126 -0
- data/lib/xrbp/nodestore/sle/st_amount_comparison.rb +49 -0
- data/lib/xrbp/nodestore/sle/st_amount_conversion.rb +203 -0
- data/lib/xrbp/nodestore/sqldb.rb +69 -4
- data/lib/xrbp/overlay/handshake.rb +1 -1
- data/lib/xrbp/version.rb +1 -1
- data/spec/xrbp/crypto/account_spec.rb +7 -2
- data/spec/xrbp/nodestore/amendments_spec.rb +11 -0
- data/spec/xrbp/nodestore/db_parser.rb +64 -1
- data/spec/xrbp/nodestore/fees_spec.rb +3 -0
- data/spec/xrbp/nodestore/ledger_access.rb +87 -2
- data/spec/xrbp/nodestore/protocol/indexes_spec.rb +43 -0
- data/spec/xrbp/nodestore/protocol/rate_spec.rb +12 -0
- data/spec/xrbp/nodestore/shamap/inner_node_spec.rb +44 -0
- data/spec/xrbp/nodestore/shamap/node_factory_spec.rb +9 -0
- data/spec/xrbp/nodestore/shamap/node_id_spec.rb +6 -0
- data/spec/xrbp/nodestore/shamap/node_spec.rb +25 -0
- data/spec/xrbp/nodestore/shamap_spec.rb +144 -0
- data/spec/xrbp/nodestore/sle/st_amount_arithmatic_spec.rb +7 -0
- data/spec/xrbp/nodestore/sle/st_amount_comparison_spec.rb +11 -0
- data/spec/xrbp/nodestore/sle/st_amount_conversion_spec.rb +64 -0
- data/spec/xrbp/nodestore/sle/st_amount_spec.rb +47 -0
- data/spec/xrbp/nodestore/sle/st_ledger_entry_spec.rb +5 -0
- data/spec/xrbp/nodestore/sle/st_object_spec.rb +29 -0
- metadata +20 -2
@@ -8,9 +8,24 @@ module XRBP
|
|
8
8
|
@account = account
|
9
9
|
end
|
10
10
|
|
11
|
+
def to_h
|
12
|
+
{:currency => currency, :account => account}
|
13
|
+
end
|
14
|
+
|
11
15
|
def xrp?
|
12
16
|
self == NodeStore.xrp_issue
|
13
17
|
end
|
18
|
+
|
19
|
+
def inspect
|
20
|
+
c = currency == NodeStore.no_currency ? '' :
|
21
|
+
currency == NodeStore.xrp_currency ? 'XRP' :
|
22
|
+
"#{currency}"
|
23
|
+
|
24
|
+
a = account == Crypto.no_account ? '' :
|
25
|
+
account == Crypto.xrp_account ? '' :
|
26
|
+
"@#{account}"
|
27
|
+
"#{c}#{a}"
|
28
|
+
end
|
14
29
|
end # class Issue
|
15
30
|
|
16
31
|
def self.xrp_issue
|
@@ -1,5 +1,16 @@
|
|
1
1
|
module XRBP
|
2
2
|
module NodeStore
|
3
|
+
# Represents a transfer rate.
|
4
|
+
#
|
5
|
+
# The percent of an amount sent that is charged
|
6
|
+
# to the sender and paid to the issuer.
|
7
|
+
#
|
8
|
+
# https://xrpl.org/transfer-fees.html
|
9
|
+
#
|
10
|
+
# From rippled docs:
|
11
|
+
# Transfer rates are specified as fractions of 1 billion.
|
12
|
+
# For example, a transfer rate of 1% is represented as
|
13
|
+
# 1,010,000,000.
|
3
14
|
class Rate
|
4
15
|
attr_reader :rate
|
5
16
|
|
@@ -7,12 +18,13 @@ module XRBP
|
|
7
18
|
@rate = rate
|
8
19
|
end
|
9
20
|
|
21
|
+
# Rate signifying a 1:1 exchange
|
10
22
|
def self.parity
|
11
23
|
@parity ||= Rate.new(QUALITY_ONE)
|
12
24
|
end
|
13
25
|
|
14
26
|
def to_amount
|
15
|
-
STAmount.new :issue =>
|
27
|
+
STAmount.new :issue => NodeStore.no_issue,
|
16
28
|
:mantissa => rate,
|
17
29
|
:exponent => -9
|
18
30
|
end
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module XRBP
|
2
2
|
class SHAMap
|
3
3
|
module NodeFactory
|
4
|
+
# Create a new node whose type is specified in the binary prefix.
|
5
|
+
#
|
4
6
|
# See rippled::SHAMapAbstractNode::make
|
5
7
|
def make(node, seq, format, hash, hash_valid)
|
6
8
|
node_id = NodeID.new
|
@@ -22,6 +24,7 @@ module XRBP
|
|
22
24
|
|
23
25
|
s = node[4..-1]
|
24
26
|
|
27
|
+
# Transaction node (no metadata)
|
25
28
|
if prefix == NodeStore::Format::HASH_PREFIXES[:tx_id]
|
26
29
|
sha512 = OpenSSL::Digest::SHA512.new
|
27
30
|
sha512 << NodeStore::Format::HASH_PREFIXES[:tx_id]
|
@@ -38,6 +41,7 @@ module XRBP
|
|
38
41
|
|
39
42
|
return TreeNode.new(tree_node)
|
40
43
|
|
44
|
+
# Leaf node in state tree containing data (account info, order, etc)
|
41
45
|
elsif prefix == NodeStore::Format::HASH_PREFIXES[:leaf_node]
|
42
46
|
raise "short PLN node" if s.size < 32
|
43
47
|
|
@@ -55,6 +59,7 @@ module XRBP
|
|
55
59
|
|
56
60
|
return TreeNode.new(tree_node)
|
57
61
|
|
62
|
+
# Inner tree node referencing other nodes
|
58
63
|
elsif (prefix == NodeStore::Format::HASH_PREFIXES[:inner_node]) ||
|
59
64
|
(prefix == NodeStore::Format::HASH_PREFIXES[:inner_node_v2])
|
60
65
|
len = s.size
|
@@ -89,8 +94,8 @@ module XRBP
|
|
89
94
|
|
90
95
|
return ret
|
91
96
|
|
97
|
+
# Transaction node (with metadata)
|
92
98
|
elsif prefix == NodeStore::Format::HASH_PREFIXES[:tx_node]
|
93
|
-
# transaction with metadata
|
94
99
|
raise "short TXN node" if s.size < 32
|
95
100
|
|
96
101
|
tx_id = s[-32..-1]
|
@@ -20,7 +20,7 @@ module XRBP
|
|
20
20
|
# Used to calculate inner node hash for
|
21
21
|
# tree level:
|
22
22
|
# inner node = lookup key & mask
|
23
|
-
def masks
|
23
|
+
def self.masks
|
24
24
|
@masks ||= begin
|
25
25
|
masks = Array.new(MASK_SIZE)
|
26
26
|
|
@@ -41,7 +41,7 @@ module XRBP
|
|
41
41
|
|
42
42
|
# Return mask for current tree depth
|
43
43
|
def mask
|
44
|
-
@mask ||= masks[depth]
|
44
|
+
@mask ||= self.class.masks[depth]
|
45
45
|
end
|
46
46
|
|
47
47
|
# Return branch number of specified hash.
|
@@ -1,9 +1,37 @@
|
|
1
|
+
require_relative './st_amount_arithmatic'
|
2
|
+
require_relative './st_amount_comparison'
|
3
|
+
require_relative './st_amount_conversion'
|
4
|
+
|
1
5
|
module XRBP
|
2
6
|
module NodeStore
|
3
|
-
# Serialized Amount Representation
|
7
|
+
# Serialized Amount Representation.
|
8
|
+
#
|
9
|
+
# From rippled docs:
|
10
|
+
# Internal form:
|
11
|
+
# 1: If amount is zero, then value is zero and offset is -100
|
12
|
+
# 2: Otherwise:
|
13
|
+
# legal offset range is -96 to +80 inclusive
|
14
|
+
# value range is 10^15 to (10^16 - 1) inclusive
|
15
|
+
# amount = value * [10 ^ offset]
|
16
|
+
#
|
17
|
+
# Wire form:
|
18
|
+
# High 8 bits are (offset+142), legal range is, 80 to 22 inclusive
|
19
|
+
# Low 56 bits are value, legal range is 10^15 to (10^16 - 1) inclusive
|
4
20
|
class STAmount
|
5
|
-
|
6
|
-
|
21
|
+
include Arithmatic
|
22
|
+
include Comparison
|
23
|
+
include Conversion
|
24
|
+
|
25
|
+
# DEFINES FROM STAmount.h
|
26
|
+
|
27
|
+
MIN_OFFSET = -96
|
28
|
+
MAX_OFFSET = 80
|
29
|
+
|
30
|
+
MIN_VAL = 1000000000000000
|
31
|
+
MAX_VAL = 9999999999999999
|
32
|
+
NOT_NATIVE = 0x8000000000000000
|
33
|
+
POS_NATIVE = 0x4000000000000000
|
34
|
+
MAX_NATIVE = 100000000000000000
|
7
35
|
|
8
36
|
attr_reader :mantissa, :exponent, :neg
|
9
37
|
attr_accessor :issue
|
@@ -19,7 +47,8 @@ module XRBP
|
|
19
47
|
return STAmount.new(:issue => NodeStore.no_issue) if rate == 0
|
20
48
|
|
21
49
|
mantissa = rate & ~(255 << (64 - 8))
|
22
|
-
|
50
|
+
|
51
|
+
exponent = (rate >> (64 - 8)).to_int32 - 100
|
23
52
|
|
24
53
|
return STAmount.new(:issue => NodeStore.no_issue,
|
25
54
|
:mantissa => mantissa,
|
@@ -31,195 +60,31 @@ module XRBP
|
|
31
60
|
@mantissa = args[:mantissa] || 0
|
32
61
|
@exponent = args[:exponent] || 0
|
33
62
|
@neg = !!args[:neg]
|
34
|
-
end
|
35
63
|
|
36
|
-
|
37
|
-
@issue.xrp?
|
38
|
-
end
|
39
|
-
|
40
|
-
def zero?
|
41
|
-
@mantissa == 0
|
42
|
-
end
|
43
|
-
|
44
|
-
def clear
|
45
|
-
# see: https://github.com/ripple/rippled/blob/b53fda1e1a7f4d09b766724274329df1c29988ab/src/ripple/protocol/STAmount.h#L224
|
46
|
-
@exponent = native? ? 0 : -100
|
47
|
-
|
48
|
-
@neg = false
|
49
|
-
@mantissa = 0
|
50
|
-
end
|
51
|
-
|
52
|
-
def negate!
|
53
|
-
return if zero?
|
54
|
-
@neg = !@neg
|
55
|
-
end
|
56
|
-
|
57
|
-
def sn_value
|
58
|
-
neg ? (-mantissa) : mantissa
|
64
|
+
canonicalize
|
59
65
|
end
|
60
66
|
|
61
67
|
###
|
62
68
|
|
63
|
-
|
64
|
-
|
65
|
-
neg ? (-value) : value
|
66
|
-
end
|
67
|
-
|
68
|
-
alias :drops :xrp_amount
|
69
|
-
|
70
|
-
def iou_amount
|
71
|
-
(neg ? -1 : 1) * mantissa * 10 ** (exponent-97)
|
72
|
-
end
|
73
|
-
|
74
|
-
###
|
75
|
-
|
76
|
-
def +(v)
|
77
|
-
e1 = exponent
|
78
|
-
e2 = v.exponent
|
79
|
-
|
80
|
-
m1 = mantissa
|
81
|
-
m2 = v.mantissa
|
82
|
-
|
83
|
-
m1 *= -1 if neg
|
84
|
-
m2 *= -1 if v.neg
|
85
|
-
|
86
|
-
while e1 < e2
|
87
|
-
m1 /= 10
|
88
|
-
e1 += 1
|
89
|
-
end
|
90
|
-
|
91
|
-
while e2 < e1
|
92
|
-
m2 /= 10
|
93
|
-
e2 += 1
|
94
|
-
end
|
95
|
-
|
96
|
-
m = m1 + m2
|
97
|
-
return STAmount.new :issue => issue if m >= -10 && m <= 10
|
98
|
-
return STAmount.new :mantissa => m,
|
99
|
-
:exponent => e1,
|
100
|
-
:issue => issue if m >= 0
|
101
|
-
return STAmount.new :mantissa => -m,
|
102
|
-
:exponent => e1,
|
103
|
-
:issue => issue
|
104
|
-
end
|
105
|
-
|
106
|
-
def -(v)
|
107
|
-
self + (-v)
|
108
|
-
end
|
109
|
-
|
110
|
-
def /(v)
|
111
|
-
if v.is_a?(Rate)
|
112
|
-
return self if v == Rate.parity
|
113
|
-
return self / v.to_amount
|
114
|
-
end
|
115
|
-
|
116
|
-
raise "divide by zero" if v.zero?
|
117
|
-
return STAmount.new :issue => issue
|
118
|
-
|
119
|
-
nm = mantissa
|
120
|
-
dm = v.mantissa
|
121
|
-
|
122
|
-
ne = exponent
|
123
|
-
de = v.exponent
|
124
|
-
|
125
|
-
if native?
|
126
|
-
while nm < MIN_VAL
|
127
|
-
nm *= 10
|
128
|
-
ne -= 1
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
if v.native?
|
133
|
-
while dm < MIN_VAL
|
134
|
-
dm *= 10
|
135
|
-
de -= 1
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# see note: https://github.com/ripple/rippled/blob/b53fda1e1a7f4d09b766724274329df1c29988ab/src/ripple/protocol/impl/STAmount.cpp#L1075
|
140
|
-
STAmount.new :issue => issue,
|
141
|
-
:mantissa => (nm * 10**17)/dm,
|
142
|
-
:exponent => (ne - de - 17),
|
143
|
-
:neg => (neg != v.neg)
|
144
|
-
end
|
145
|
-
|
146
|
-
def *(o)
|
147
|
-
return STAmount.new :issue => issue if zero? || o.zero?
|
148
|
-
|
149
|
-
if native?
|
150
|
-
min = sn_value < o.sn_value ? sn_value : o.sn_value
|
151
|
-
max = sn_value < o.sn_value ? o.sn_value : sn_value
|
152
|
-
|
153
|
-
return STAmount.new :mantissa => min * max
|
154
|
-
end
|
155
|
-
|
156
|
-
m1 = mantissa
|
157
|
-
m2 = o.mantissa
|
158
|
-
e1 = exponent
|
159
|
-
e2 = o.exponent
|
160
|
-
|
161
|
-
if native?
|
162
|
-
while nm < MIN_VAL
|
163
|
-
m1 *= 10
|
164
|
-
e1 -= 1
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
if o.native?
|
169
|
-
while dm < MIN_VAL
|
170
|
-
m2 *= 10
|
171
|
-
e2 -= 1
|
172
|
-
end
|
173
|
-
end
|
174
|
-
|
175
|
-
# see note: https://github.com/ripple/rippled/blob/b53fda1e1a7f4d09b766724274329df1c29988ab/src/ripple/protocol/impl/STAmount.cpp#L1131
|
176
|
-
STAmount.new :issue => issue,
|
177
|
-
:mantissa => (m1 * m2)/(10**14),
|
178
|
-
:exponent => (e1 + e2 + 14),
|
179
|
-
:neg => (neg != o.neg)
|
180
|
-
end
|
181
|
-
|
182
|
-
def -@
|
183
|
-
STAmount.new(:mantissa => mantissa,
|
184
|
-
:exponent => exponent,
|
185
|
-
:issue => issue,
|
186
|
-
:neg => !neg)
|
187
|
-
end
|
188
|
-
|
189
|
-
def <(o)
|
190
|
-
return neg if neg && !o.neg
|
191
|
-
if mantissa == 0
|
192
|
-
return false if o.neg
|
193
|
-
return o.mantissa != 0
|
194
|
-
end
|
195
|
-
|
196
|
-
return false if o.mantissa == 0
|
197
|
-
return neg if exponent > o.exponent
|
198
|
-
return !neg if exponent < o.exponent
|
199
|
-
return neg if mantissa > o.mantissa
|
200
|
-
return !neg if mantissa < o.mantissa
|
201
|
-
|
202
|
-
return false
|
69
|
+
def native?
|
70
|
+
@issue && @issue.xrp?
|
203
71
|
end
|
204
72
|
|
205
|
-
def
|
206
|
-
|
73
|
+
def zero?
|
74
|
+
@mantissa == 0
|
207
75
|
end
|
208
76
|
|
209
|
-
def
|
210
|
-
|
211
|
-
end
|
77
|
+
def inspect
|
78
|
+
return "0" if zero?
|
212
79
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
80
|
+
i = issue.inspect
|
81
|
+
i = i == '' ? '' : "(#{i})"
|
82
|
+
(native? ? xrp_amount : iou_amount.to_f).to_s +
|
83
|
+
(native? ? "" : i)
|
217
84
|
end
|
218
85
|
|
219
|
-
def
|
220
|
-
|
221
|
-
return -1 if self < o
|
222
|
-
return 1 if self > o
|
86
|
+
def to_s
|
87
|
+
inspect
|
223
88
|
end
|
224
89
|
end # class STAmount
|
225
90
|
end # module NodeStore
|
@@ -0,0 +1,126 @@
|
|
1
|
+
module XRBP
|
2
|
+
module NodeStore
|
3
|
+
class STAmount
|
4
|
+
module Arithmatic
|
5
|
+
def +(v)
|
6
|
+
return self + STAmount.new(:mantissa => v) if v.kind_of?(Numeric)
|
7
|
+
|
8
|
+
e1 = exponent
|
9
|
+
e2 = v.exponent
|
10
|
+
|
11
|
+
m1 = mantissa
|
12
|
+
m2 = v.mantissa
|
13
|
+
|
14
|
+
m1 *= -1 if neg
|
15
|
+
m2 *= -1 if v.neg
|
16
|
+
|
17
|
+
while e1 < e2
|
18
|
+
m1 /= 10
|
19
|
+
e1 += 1
|
20
|
+
end
|
21
|
+
|
22
|
+
while e2 < e1
|
23
|
+
m2 /= 10
|
24
|
+
e2 += 1
|
25
|
+
end
|
26
|
+
|
27
|
+
m = m1 + m2
|
28
|
+
return STAmount.new :issue => issue if m >= -10 && m <= 10
|
29
|
+
return STAmount.new :mantissa => m,
|
30
|
+
:exponent => e1,
|
31
|
+
:issue => issue if m >= 0
|
32
|
+
return STAmount.new :mantissa => -m,
|
33
|
+
:exponent => e1,
|
34
|
+
:issue => issue
|
35
|
+
end
|
36
|
+
|
37
|
+
def -(v)
|
38
|
+
self + (-v)
|
39
|
+
end
|
40
|
+
|
41
|
+
def /(v)
|
42
|
+
return self / STAmount.new(:mantissa => v) if v.kind_of?(Numeric)
|
43
|
+
|
44
|
+
if v.is_a?(Rate)
|
45
|
+
return self if v == Rate.parity
|
46
|
+
return self / v.to_amount
|
47
|
+
end
|
48
|
+
|
49
|
+
raise "divide by zero" if v.zero?
|
50
|
+
return STAmount.new :issue => issue if zero?
|
51
|
+
|
52
|
+
nm = mantissa
|
53
|
+
dm = v.mantissa
|
54
|
+
|
55
|
+
ne = exponent
|
56
|
+
de = v.exponent
|
57
|
+
|
58
|
+
if native?
|
59
|
+
while nm < MIN_VAL
|
60
|
+
nm *= 10
|
61
|
+
ne -= 1
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
if v.native?
|
66
|
+
while dm < MIN_VAL
|
67
|
+
dm *= 10
|
68
|
+
de -= 1
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# see note: https://github.com/ripple/rippled/blob/b53fda1e1a7f4d09b766724274329df1c29988ab/src/ripple/protocol/impl/STAmount.cpp#L1075
|
73
|
+
STAmount.new :issue => issue,
|
74
|
+
:mantissa => (nm * 10**17)/dm + 5,
|
75
|
+
:exponent => (ne - de - 17),
|
76
|
+
:neg => (neg != v.neg)
|
77
|
+
end
|
78
|
+
|
79
|
+
def *(o)
|
80
|
+
return self * STAmount.new(:mantissa => o) if o.kind_of?(Numeric)
|
81
|
+
|
82
|
+
return STAmount.new :issue => issue if zero? || o.zero?
|
83
|
+
|
84
|
+
if native? && o.native?
|
85
|
+
min = sn_value < o.sn_value ? sn_value : o.sn_value
|
86
|
+
max = sn_value < o.sn_value ? o.sn_value : sn_value
|
87
|
+
|
88
|
+
return STAmount.new :mantissa => min * max
|
89
|
+
end
|
90
|
+
|
91
|
+
m1 = mantissa
|
92
|
+
m2 = o.mantissa
|
93
|
+
e1 = exponent
|
94
|
+
e2 = o.exponent
|
95
|
+
|
96
|
+
if native?
|
97
|
+
while nm < MIN_VAL
|
98
|
+
m1 *= 10
|
99
|
+
e1 -= 1
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
if o.native?
|
104
|
+
while dm < MIN_VAL
|
105
|
+
m2 *= 10
|
106
|
+
e2 -= 1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# see note: https://github.com/ripple/rippled/blob/b53fda1e1a7f4d09b766724274329df1c29988ab/src/ripple/protocol/impl/STAmount.cpp#L1131
|
111
|
+
STAmount.new :issue => issue,
|
112
|
+
:mantissa => (m1 * m2)/(10**14) + 7,
|
113
|
+
:exponent => (e1 + e2 + 14),
|
114
|
+
:neg => (neg != o.neg)
|
115
|
+
end
|
116
|
+
|
117
|
+
def -@
|
118
|
+
STAmount.new(:mantissa => mantissa,
|
119
|
+
:exponent => exponent,
|
120
|
+
:issue => issue,
|
121
|
+
:neg => !neg)
|
122
|
+
end
|
123
|
+
end # module Arithmatic
|
124
|
+
end # class STAmount
|
125
|
+
end # module NodeStore
|
126
|
+
end # module XRBP
|