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.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/examples/nodestore1.rb +3 -1
  3. data/lib/xrbp/common.rb +6 -0
  4. data/lib/xrbp/core_ext.rb +21 -0
  5. data/lib/xrbp/nodestore/format.rb +76 -26
  6. data/lib/xrbp/nodestore/ledger.rb +46 -14
  7. data/lib/xrbp/nodestore/parser.rb +47 -14
  8. data/lib/xrbp/nodestore/protocol/indexes.rb +11 -8
  9. data/lib/xrbp/nodestore/protocol/issue.rb +15 -0
  10. data/lib/xrbp/nodestore/protocol/rate.rb +13 -1
  11. data/lib/xrbp/nodestore/shamap/node_factory.rb +6 -1
  12. data/lib/xrbp/nodestore/shamap/node_id.rb +2 -2
  13. data/lib/xrbp/nodestore/sle/st_amount.rb +46 -181
  14. data/lib/xrbp/nodestore/sle/st_amount_arithmatic.rb +126 -0
  15. data/lib/xrbp/nodestore/sle/st_amount_comparison.rb +49 -0
  16. data/lib/xrbp/nodestore/sle/st_amount_conversion.rb +203 -0
  17. data/lib/xrbp/nodestore/sqldb.rb +69 -4
  18. data/lib/xrbp/overlay/handshake.rb +1 -1
  19. data/lib/xrbp/version.rb +1 -1
  20. data/spec/xrbp/crypto/account_spec.rb +7 -2
  21. data/spec/xrbp/nodestore/amendments_spec.rb +11 -0
  22. data/spec/xrbp/nodestore/db_parser.rb +64 -1
  23. data/spec/xrbp/nodestore/fees_spec.rb +3 -0
  24. data/spec/xrbp/nodestore/ledger_access.rb +87 -2
  25. data/spec/xrbp/nodestore/protocol/indexes_spec.rb +43 -0
  26. data/spec/xrbp/nodestore/protocol/rate_spec.rb +12 -0
  27. data/spec/xrbp/nodestore/shamap/inner_node_spec.rb +44 -0
  28. data/spec/xrbp/nodestore/shamap/node_factory_spec.rb +9 -0
  29. data/spec/xrbp/nodestore/shamap/node_id_spec.rb +6 -0
  30. data/spec/xrbp/nodestore/shamap/node_spec.rb +25 -0
  31. data/spec/xrbp/nodestore/shamap_spec.rb +144 -0
  32. data/spec/xrbp/nodestore/sle/st_amount_arithmatic_spec.rb +7 -0
  33. data/spec/xrbp/nodestore/sle/st_amount_comparison_spec.rb +11 -0
  34. data/spec/xrbp/nodestore/sle/st_amount_conversion_spec.rb +64 -0
  35. data/spec/xrbp/nodestore/sle/st_amount_spec.rb +47 -0
  36. data/spec/xrbp/nodestore/sle/st_ledger_entry_spec.rb +5 -0
  37. data/spec/xrbp/nodestore/sle/st_object_spec.rb +29 -0
  38. 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 => Issue.no_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
- # see: https://github.com/ripple/rippled/blob/b53fda1e1a7f4d09b766724274329df1c29988ab/src/ripple/protocol/STAmount.h#L67
6
- MIN_VAL = 1000000000000000
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
- exponent = (rate >> (64 - 8)) - 100
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
- def native?
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
- # In drops!
64
- def xrp_amount
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 >=(o)
206
- !(self < o)
73
+ def zero?
74
+ @mantissa == 0
207
75
  end
208
76
 
209
- def >(o)
210
- self >= o && self != o
211
- end
77
+ def inspect
78
+ return "0" if zero?
212
79
 
213
- def ==(o)
214
- neg == o.neg &&
215
- mantissa == o.mantissa &&
216
- exponent == o.exponent
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 <=>(o)
220
- return 0 if self == o
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