xrbp 0.1.5 → 0.1.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9d22207d3716ce82876aa18980ca4a905cefb569b322d332f81a60879ecff900
4
- data.tar.gz: 66f05eab919c17ef84205a7b16afd0a577bdd7d8b19d3c0f2b8a8a90204d7cd8
3
+ metadata.gz: 4a8b3814b38bdb314bd9c69b5d9f3363b4f0a090f6d41a5849516cc1638d5abe
4
+ data.tar.gz: fc1ba94351b215389efaacb5013bfa9498a269cf12d7fde3e6958a5fb3f6273a
5
5
  SHA512:
6
- metadata.gz: 4a1b3a303dce21fff486b306fe95ad5ef930fdc7eaa9331ea2d1c45f28c606d09b6731e96ed326e022873bde6255d67eacc4bddea95df40ee6761cd1314cb096
7
- data.tar.gz: 9899f54fe7dad90e19f1eec884c55ea8d5d73b7c109dde1b395d3b0908f9b987b9c6fe6ae7604471e4f0ac98d5dbd0c561e528bb0b9e4fccc39f46bfed6d4199
6
+ metadata.gz: b8e9e87bc83b3bd361bef7d1deffd87c7637285e15fca3bb5b25f87b34091ebb792137178b06c71d8ac1566a75aadf5ed74fe85d1fc414c5070edecfddce78d4
7
+ data.tar.gz: 8e8cbea5804ff5f852584be3a699caee69169ad3563bb2a0696e8a3ea9492faa89ae937138bb64c7b65804adc72f49f24538659b85a018b2444b038c4b0b0558
@@ -1,14 +1,19 @@
1
1
  $: << File.expand_path('../../lib', __FILE__)
2
2
  require 'xrbp'
3
- require 'xrbp/nodestore/backends/rocksdb'
4
3
 
5
- db = XRBP::NodeStore::Backends::RocksDB.new "/var/lib/rippled/rocksdb/rippledb.0899"
4
+ # for rocksdb:
5
+ #require 'xrbp/nodestore/backends/rocksdb'
6
+ #db = XRBP::NodeStore::Backends::RocksDB.new "/home/mmorsi/rippledb/rocksdb/rippledb.beb0"
6
7
 
7
- #ledger = "B506ADD630CB707044B4BFFCD943C1395966692A13DD618E5BD0978A006B43BD"
8
- #ledger = [ledger].pack("H*")
9
- #puts db.ledger(ledger)
8
+ # for nudb:
9
+ require 'xrbp/nodestore/backends/nudb'
10
+ db = XRBP::NodeStore::Backends::NuDB.new "/var/lib/rippled/nudb/"
11
+
12
+ ledger = "1B927880277CCF943CB4F6BF57A9BCE48F9583A3DD8EEE9A068D63FB6CD99714"
13
+ ledger = [ledger].pack("H*")
14
+ puts db.ledger(ledger)
10
15
 
11
16
  #account = "0001bf7468341666f1f47a95e0f4d88e68b5fc7d20d77437cb22954fbbfe6127"
12
- account = "02c46b3a4130d0a329c47f0da61b829aa5d1ae53c5817e475bcd794e5107be44"
13
- account = [account].pack("H*")
14
- puts db.account(account)
17
+ #account = "02c46b3a4130d0a329c47f0da61b829aa5d1ae53c5817e475bcd794e5107be44"
18
+ #account = [account].pack("H*")
19
+ #puts db.account(account)
@@ -1,8 +1,13 @@
1
1
  $: << File.expand_path('../../lib', __FILE__)
2
2
  require 'xrbp'
3
- require 'xrbp/nodestore/backends/rocksdb'
4
3
 
5
- db = XRBP::NodeStore::Backends::RocksDB.new "/var/lib/rippled/rocksdb/rippledb.0899"
4
+ # for rocksdb:
5
+ #require 'xrbp/nodestore/backends/rocksdb'
6
+ #db = XRBP::NodeStore::Backends::RocksDB.new "/home/mmorsi/rippledb/rocksdb/rippledb.beb0"
7
+
8
+ # for nudb:
9
+ require 'xrbp/nodestore/backends/nudb'
10
+ db = XRBP::NodeStore::Backends::NuDB.new "/var/lib/rippled/nudb/"
6
11
 
7
12
  db.on :unknown do |hash, node|
8
13
  puts "Unknown #{hash}: #{node}"
@@ -0,0 +1,13 @@
1
+ $: << File.expand_path('../../lib', __FILE__)
2
+ require 'xrbp'
3
+ require 'xrbp/nodestore/backends/nudb'
4
+
5
+ db = XRBP::NodeStore::Backends::NuDB.new "/var/lib/rippled/nudb/"
6
+ store = db.instance_variable_get(:@store)
7
+
8
+ key = [173, 159, 139, 114, 152, 207, 218, 221, 216, 149, 123, 11, 7, 224, 137, 139, 4, 190, 176, 89, 215, 228, 145, 13, 7, 45, 165, 249, 162, 83, 43, 241].pack("C*")
9
+ val = store.fetch(key).first
10
+ puts val.unpack("C*").join " "
11
+ decompressed = db.send(:decompress, val)
12
+ puts decompressed.unpack("C*").join " "
13
+ type, obj = db.send(:infer_type, decompressed)
@@ -0,0 +1,197 @@
1
+ # requires lz4-ruby gem
2
+ require 'lz4-ruby'
3
+
4
+ module XRBP
5
+ module NodeStore
6
+ module Backends
7
+ # Ported from:
8
+ # https://github.com/ripple/rippled/blob/develop/src/ripple/nodestore/impl/codec.h
9
+ module Decompressor
10
+ protected
11
+ def decompress(data)
12
+ type, remaining = read_varint(data)
13
+ case(type)
14
+ when 0
15
+ remaining # uncompressed
16
+ when 1
17
+ decompress_lz4 remaining
18
+ when 2
19
+ decompress_compressed_v1_inner remaining
20
+ when 3
21
+ decompress_full_v1_inner remaining
22
+ when 5
23
+ decompress_compressed_v2_inner remaining
24
+ when 6
25
+ decompress_full_v2_inner remaining
26
+
27
+ else
28
+ raise "nodeobject codec: bad type=#{type}"
29
+ end
30
+ end
31
+
32
+ private
33
+ # https://github.com/ripple/rippled/blob/develop/src/ripple/nodestore/impl/varint.h
34
+ def read_varint(data)
35
+ bytes = data.bytes
36
+
37
+ t = 0
38
+ n = 0
39
+ while(bytes[n] & 0x80) != 0
40
+ n += 1
41
+ if n >= bytes.size
42
+ return t, data
43
+ end
44
+ end
45
+
46
+ if (n += 1) >= bytes.size
47
+ return t, data
48
+ end
49
+
50
+ if n == 1 && bytes[0] == 0
51
+ return t, data[1..-1]
52
+ end
53
+
54
+ used = n
55
+ while(n -= 1) >= 0
56
+ d = bytes[n]
57
+ t0 = t
58
+ t *= 127
59
+ t += d & 0x7F
60
+ if t <= t0 # overflow
61
+ return t, data
62
+ end
63
+ end
64
+
65
+ return t, data[used..-1]
66
+ end
67
+
68
+ ###
69
+
70
+ def decompress_lz4(data)
71
+ size, remaining = read_varint(data)
72
+ o = LZ4::Raw::decompress(remaining, size)[0]
73
+ o
74
+ end
75
+
76
+ ###
77
+
78
+ def decompress_compressed_v1_inner(data)
79
+ raise if data.size < 34
80
+
81
+ out = [0, 0, 0, 0,
82
+ 0, 0, 0, 0,
83
+ Format::NODE_OBJ_TYPES[:unknown]] +
84
+ [Format::HASH_PREFIXES.invert[:inner_node]].pack("H*")
85
+ .unpack("C*")
86
+
87
+ bytes = data.bytes
88
+ mask = bytes[0..1].pack("C*").unpack("S").first
89
+ bytes = bytes[2..-1]
90
+
91
+ raise "nodeobject codec v1: empty inner node" if mask == 0
92
+
93
+ bit = 0x8000
94
+ i = 16
95
+ while i > 0
96
+ i -= 1
97
+
98
+ if (mask & bit) != 0
99
+ raise "nodeobject codec v1: short inner node" if bytes.size < 32
100
+
101
+ out += bytes[0..31]
102
+ bytes = bytes[32..-1]
103
+
104
+ else
105
+ out += Array.new(32) { 0 }
106
+ end
107
+
108
+ bit = bit >> 1
109
+ end
110
+
111
+ out.pack("C*")
112
+ end
113
+
114
+ def decompress_compressed_v2_inner(data)
115
+ raise if data.size < 67
116
+
117
+ out = [0, 0, 0, 0,
118
+ 0, 0, 0, 0,
119
+ Format::NODE_OBJ_TYPES[:unknown]] +
120
+ [Format::HASH_PREFIXES.invert[:inner_node_v2]].pack("H*")
121
+ .unpack("C*")
122
+
123
+ bytes = data.bytes
124
+ mask = bytes[0..1].pack("C*").unpack("S").first
125
+ bytes = bytes[2..-1]
126
+
127
+ raise "nodeobject codec v2: empty inner node" if mask == 0
128
+
129
+ depth = bytes[0]
130
+ bytes = bytes[1..-1]
131
+
132
+ bit = 0x8000
133
+ i = 16
134
+ while i > 0
135
+ i -= 1
136
+
137
+ if (mask & bit) != 0
138
+ raise "nodeobject codec v1: short inner node" if bytes.size < 32
139
+
140
+ out += bytes[0..31]
141
+ bytes = bytes[32..-1]
142
+
143
+ else
144
+ out += Array.new(32) { 0 }
145
+ end
146
+
147
+ bit = bit >> 1
148
+ end
149
+
150
+ out << depth
151
+
152
+ copy = (depth + 1)/2
153
+ raise "nodeobject codec v2: short inner node" if bytes.size < copy
154
+ out += bytes[0...copy]
155
+ bytes = bytes[copy..-1]
156
+ raise "nodeobject codec v2: long inner node" if bytes.size > 0
157
+
158
+ out.pack("C*")
159
+ end
160
+
161
+ ###
162
+
163
+ def decompress_full_v1_inner(data)
164
+ raise if data.size != 512 # 16 32-bit hashes
165
+
166
+ out = [0, 0, 0, 0,
167
+ 0, 0, 0, 0,
168
+ Format::NODE_OBJ_TYPES[:unknown]] +
169
+ [Format::HASH_PREFIXES.invert[:inner_node]].pack("H*").unpack("C*")
170
+ (out + data[0...512].bytes).pack("C*")
171
+ end
172
+
173
+
174
+ def decompress_full_v2_inner(data)
175
+ bytes = data.bytes
176
+ depth = bytes[0]
177
+ bytes = bytes[1..-1]
178
+ copy = (depth + 1)/2
179
+
180
+ raise if bytes.size != 512 + copy # 16 32-bit hashes + copy
181
+
182
+ out = [0, 0, 0, 0,
183
+ 0, 0, 0, 0,
184
+ Format::NODE_OBJ_TYPES[:unknown]] +
185
+ [Format::HASH_PREFIXES.invert[:inner_node_v2]].pack("H*").unpack("C*")
186
+
187
+ out += bytes[0..511]
188
+ bytes = bytes[512..-1]
189
+ out << depth
190
+ out += bytes[0...copy]
191
+
192
+ out.pack("C*")
193
+ end
194
+ end # module Decompressor
195
+ end # module Backends
196
+ end # module NodeStore
197
+ end # module XRBP
@@ -1 +1,78 @@
1
- # TODO
1
+ require 'ostruct'
2
+
3
+ # requires rrudb gem
4
+ require "rudb"
5
+
6
+ require_relative './decompressor'
7
+
8
+ module XRBP
9
+ module NodeStore
10
+ module Backends
11
+ class NuDB < DB
12
+ include Decompressor
13
+
14
+ attr_reader :path
15
+
16
+ KEY_SIZE = 32
17
+
18
+ def initialize(path)
19
+ @path = path
20
+ create!
21
+ open
22
+ end
23
+
24
+ def [](key)
25
+ decompress(@store.fetch(key)[0])
26
+ end
27
+
28
+ def each
29
+ dat = File.join(path, "nudb.dat")
30
+
31
+ RuDB::each(dat) do |key, val|
32
+ val = decompress(val)
33
+ type, obj = infer_type(val)
34
+
35
+ if type
36
+ emit type, key, obj
37
+ else
38
+ emit :unknown, key, val
39
+ end
40
+
41
+ # 'mock' iterator
42
+ iterator = OpenStruct.new(:key => key,
43
+ :value => val)
44
+ yield iterator
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def create!
51
+ dat = File.join(path, "nudb.dat")
52
+ key = File.join(path, "nudb.key")
53
+ log = File.join(path, "nudb.log")
54
+
55
+ RuDB::create :dat_path => dat,
56
+ :key_path => key,
57
+ :log_path => log,
58
+ :app_num => 1,
59
+ :salt => RuDB::make_salt,
60
+ :key_size => KEY_SIZE,
61
+ :block_size => RuDB::block_size(key),
62
+ :load_factor => 0.5
63
+ end
64
+
65
+
66
+
67
+ def open
68
+ dat = File.join(path, "nudb.dat")
69
+ key = File.join(path, "nudb.key")
70
+ log = File.join(path, "nudb.log")
71
+
72
+ @store = RuDB::Store.new
73
+ @store.open(dat, key, log)
74
+ end
75
+ end # class NuDB
76
+ end # module Backends
77
+ end # module NodeStore
78
+ end # module XRBP
@@ -1,3 +1,4 @@
1
+ # requires rocksdb-ruby gem
1
2
  require "rocksdb"
2
3
 
3
4
  module XRBP
@@ -7,6 +7,8 @@ module XRBP
7
7
  include Enumerable
8
8
  include EventEmitter
9
9
 
10
+ # TODO return nil if db lookup not found
11
+
10
12
  def ledger(hash)
11
13
  parse_ledger(self[hash])
12
14
  end
@@ -258,6 +260,7 @@ module XRBP
258
260
  sha256 = OpenSSL::Digest::SHA256.new
259
261
  digest = sha256.digest(sha256.digest(acct))[0..3]
260
262
  acct += digest
263
+ acct.force_encoding(Encoding::BINARY) # required for Base58 gem
261
264
  return Base58.binary_to_base58(acct, :ripple), data[vl..-1]
262
265
  end
263
266
 
@@ -3,6 +3,13 @@ require "bistro"
3
3
  module XRBP
4
4
  module NodeStore
5
5
  module Format
6
+ NODE_OBJ_TYPES = {
7
+ :unknown => 0,
8
+ :ledger => 1,
9
+ :account_node => 2,
10
+ :transaction_node => 3
11
+ }
12
+
6
13
  NODE_TYPES = {
7
14
  1 => :ledger,
8
15
  2 => :tx,
@@ -15,6 +22,7 @@ module XRBP
15
22
  "534E4400" => :tx_node,
16
23
  "4D4C4E00" => :leaf_node,
17
24
  "4D494E00" => :inner_node,
25
+ "494E5200" => :inner_node_v2,
18
26
  "4C575200" => :ledger_master,
19
27
  "53545800" => :tx_sign,
20
28
  "56414C00" => :validation,
data/lib/xrbp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module XRBP
2
- VERSION = '0.1.5'
2
+ VERSION = '0.1.6'
3
3
  end # module XRBP
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xrbp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dev Null Productions
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-09 00:00:00.000000000 Z
11
+ date: 2019-05-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -196,6 +196,7 @@ files:
196
196
  - examples/paginate.rb
197
197
  - examples/prioritized.rb
198
198
  - examples/round_robin.rb
199
+ - examples/sandbox.rb
199
200
  - examples/username.rb
200
201
  - examples/validator.rb
201
202
  - examples/websocket.rb
@@ -228,6 +229,7 @@ files:
228
229
  - lib/xrbp/model/parsers/validator.rb
229
230
  - lib/xrbp/model/validator.rb
230
231
  - lib/xrbp/nodestore.rb
232
+ - lib/xrbp/nodestore/backends/decompressor.rb
231
233
  - lib/xrbp/nodestore/backends/nudb.rb
232
234
  - lib/xrbp/nodestore/backends/rocksdb.rb
233
235
  - lib/xrbp/nodestore/db.rb