xrbp 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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