librats 1.0.2 → 2.2.0

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 (319) hide show
  1. package/README.md +145 -331
  2. package/binding.gyp +16 -3
  3. package/lib/index.d.ts +288 -696
  4. package/lib/index.js +407 -44
  5. package/native-src/3rdparty/android/ifaddrs-android.c +1 -0
  6. package/native-src/3rdparty/android/ifaddrs-android.h +1 -0
  7. package/native-src/CMakeLists.txt +404 -179
  8. package/native-src/LICENSE +1 -1
  9. package/native-src/src/librats/bindings/rats.cpp +762 -0
  10. package/native-src/src/librats/bindings/rats.h +380 -0
  11. package/native-src/src/librats/bittorrent/bencode.cpp +437 -0
  12. package/native-src/src/librats/bittorrent/bencode.h +176 -0
  13. package/native-src/src/librats/bittorrent/bitfield.cpp +97 -0
  14. package/native-src/src/librats/bittorrent/bitfield.h +76 -0
  15. package/native-src/src/librats/bittorrent/byte_io.h +58 -0
  16. package/native-src/src/librats/bittorrent/choker.cpp +25 -0
  17. package/native-src/src/librats/bittorrent/choker.h +46 -0
  18. package/native-src/src/librats/bittorrent/client.cpp +413 -0
  19. package/native-src/src/librats/bittorrent/client.h +227 -0
  20. package/native-src/src/librats/bittorrent/disk_io.cpp +209 -0
  21. package/native-src/src/librats/bittorrent/disk_io.h +150 -0
  22. package/native-src/src/librats/bittorrent/extensions.cpp +191 -0
  23. package/native-src/src/librats/bittorrent/extensions.h +94 -0
  24. package/native-src/src/librats/bittorrent/file_storage.cpp +77 -0
  25. package/native-src/src/librats/bittorrent/file_storage.h +79 -0
  26. package/native-src/src/librats/bittorrent/log.h +42 -0
  27. package/native-src/src/librats/bittorrent/magnet_uri.cpp +98 -0
  28. package/native-src/src/librats/bittorrent/magnet_uri.h +35 -0
  29. package/native-src/src/librats/bittorrent/peer_connection.cpp +502 -0
  30. package/native-src/src/librats/bittorrent/peer_connection.h +194 -0
  31. package/native-src/src/librats/bittorrent/peer_list.cpp +68 -0
  32. package/native-src/src/librats/bittorrent/peer_list.h +75 -0
  33. package/native-src/src/librats/bittorrent/piece_picker.cpp +352 -0
  34. package/native-src/src/librats/bittorrent/piece_picker.h +201 -0
  35. package/native-src/src/librats/bittorrent/reactor.cpp +97 -0
  36. package/native-src/src/librats/bittorrent/reactor.h +89 -0
  37. package/native-src/src/librats/bittorrent/resume_data.cpp +72 -0
  38. package/native-src/src/librats/bittorrent/resume_data.h +41 -0
  39. package/native-src/src/librats/bittorrent/store_buffer.cpp +48 -0
  40. package/native-src/src/librats/bittorrent/store_buffer.h +47 -0
  41. package/native-src/src/librats/bittorrent/torrent.cpp +870 -0
  42. package/native-src/src/librats/bittorrent/torrent.h +260 -0
  43. package/native-src/src/librats/bittorrent/torrent_creator.cpp +129 -0
  44. package/native-src/src/librats/bittorrent/torrent_creator.h +58 -0
  45. package/native-src/src/librats/bittorrent/torrent_info.cpp +314 -0
  46. package/native-src/src/librats/bittorrent/torrent_info.h +118 -0
  47. package/native-src/src/librats/bittorrent/tracker.cpp +374 -0
  48. package/native-src/src/librats/bittorrent/tracker.h +108 -0
  49. package/native-src/src/librats/bittorrent/types.cpp +206 -0
  50. package/native-src/src/librats/bittorrent/types.h +86 -0
  51. package/native-src/src/librats/core/address.cpp +35 -0
  52. package/native-src/src/librats/core/address.h +78 -0
  53. package/native-src/src/librats/core/bytes.h +69 -0
  54. package/native-src/src/librats/core/chained_send_buffer.cpp +172 -0
  55. package/native-src/src/librats/core/chained_send_buffer.h +183 -0
  56. package/native-src/src/librats/core/endpoint_parse.cpp +41 -0
  57. package/native-src/src/librats/core/endpoint_parse.h +31 -0
  58. package/native-src/src/librats/core/event_bus.h +70 -0
  59. package/native-src/src/librats/core/host_endpoint.h +56 -0
  60. package/native-src/src/{io_poller.cpp → librats/core/io_poller.cpp} +520 -65
  61. package/native-src/src/{io_poller.h → librats/core/io_poller.h} +12 -6
  62. package/native-src/src/librats/core/ip_address.cpp +120 -0
  63. package/native-src/src/librats/core/ip_address.h +109 -0
  64. package/native-src/src/librats/core/mpsc_queue.h +47 -0
  65. package/native-src/src/librats/core/notifier.h +74 -0
  66. package/native-src/src/librats/core/receive_buffer.cpp +219 -0
  67. package/native-src/src/librats/core/receive_buffer.h +171 -0
  68. package/native-src/src/librats/core/service_registry.h +58 -0
  69. package/native-src/src/{socket.cpp → librats/core/socket.cpp} +625 -118
  70. package/native-src/src/librats/core/socket.h +496 -0
  71. package/native-src/src/librats/core/timer_queue.h +105 -0
  72. package/native-src/src/librats/core/types.cpp +43 -0
  73. package/native-src/src/librats/core/types.h +103 -0
  74. package/native-src/src/librats/core/wakeup_pipe.h +83 -0
  75. package/native-src/src/{crypto → librats/crypto}/blake2_endian.h +21 -23
  76. package/native-src/src/{crypto → librats/crypto}/blake2b.c +34 -33
  77. package/native-src/src/{crypto → librats/crypto}/blake2b.h +7 -6
  78. package/native-src/src/{crypto → librats/crypto}/blake2s.c +55 -54
  79. package/native-src/src/{crypto → librats/crypto}/blake2s.h +13 -12
  80. package/native-src/src/{crypto → librats/crypto}/chacha.c +22 -21
  81. package/native-src/src/{crypto → librats/crypto}/chacha.h +14 -13
  82. package/native-src/src/{crypto → librats/crypto}/chachapoly.c +56 -56
  83. package/native-src/src/{crypto → librats/crypto}/chachapoly.h +24 -17
  84. package/native-src/src/{crc32.cpp → librats/crypto/crc32.cpp} +1 -1
  85. package/native-src/src/{crc32.h → librats/crypto/crc32.h} +3 -1
  86. package/native-src/src/{crypto → librats/crypto}/curve25519.c +6 -4
  87. package/native-src/src/{crypto → librats/crypto}/curve25519.h +6 -3
  88. package/native-src/src/librats/crypto/hkdf.c +266 -0
  89. package/native-src/src/{crypto → librats/crypto}/hkdf.h +19 -19
  90. package/native-src/src/{noise.cpp → librats/crypto/noise.cpp} +84 -73
  91. package/native-src/src/{noise.h → librats/crypto/noise.h} +18 -8
  92. package/native-src/src/{crypto → librats/crypto}/poly1305.c +47 -46
  93. package/native-src/src/librats/crypto/poly1305.h +37 -0
  94. package/native-src/src/{sha1.cpp → librats/crypto/sha1.cpp} +33 -1
  95. package/native-src/src/{sha1.h → librats/crypto/sha1.h} +14 -6
  96. package/native-src/src/{crypto → librats/crypto}/sha256.c +15 -14
  97. package/native-src/src/{crypto → librats/crypto}/sha256.h +8 -7
  98. package/native-src/src/{crypto → librats/crypto}/sha512.c +15 -14
  99. package/native-src/src/{crypto → librats/crypto}/sha512.h +8 -7
  100. package/native-src/src/librats/dht/announce.cpp +37 -0
  101. package/native-src/src/librats/dht/announce.h +41 -0
  102. package/native-src/src/librats/dht/bep42.cpp +109 -0
  103. package/native-src/src/librats/dht/bep42.h +48 -0
  104. package/native-src/src/librats/dht/dht.cpp +501 -0
  105. package/native-src/src/librats/dht/dht.h +119 -0
  106. package/native-src/src/librats/dht/dht_runner.cpp +103 -0
  107. package/native-src/src/librats/dht/dht_runner.h +71 -0
  108. package/native-src/src/librats/dht/dos_blocker.cpp +42 -0
  109. package/native-src/src/librats/dht/dos_blocker.h +47 -0
  110. package/native-src/src/librats/dht/find_peers.cpp +52 -0
  111. package/native-src/src/librats/dht/find_peers.h +73 -0
  112. package/native-src/src/librats/dht/id.h +167 -0
  113. package/native-src/src/{krpc.cpp → librats/dht/krpc.cpp} +32 -81
  114. package/native-src/src/{krpc.h → librats/dht/krpc.h} +19 -23
  115. package/native-src/src/librats/dht/log.h +38 -0
  116. package/native-src/src/librats/dht/node.cpp +473 -0
  117. package/native-src/src/librats/dht/node.h +164 -0
  118. package/native-src/src/librats/dht/node_entry.h +81 -0
  119. package/native-src/src/librats/dht/observer.h +72 -0
  120. package/native-src/src/librats/dht/persistence.cpp +90 -0
  121. package/native-src/src/librats/dht/persistence.h +32 -0
  122. package/native-src/src/librats/dht/routing_table.cpp +559 -0
  123. package/native-src/src/librats/dht/routing_table.h +185 -0
  124. package/native-src/src/librats/dht/rpc_manager.cpp +127 -0
  125. package/native-src/src/librats/dht/rpc_manager.h +77 -0
  126. package/native-src/src/librats/dht/storage.cpp +92 -0
  127. package/native-src/src/librats/dht/storage.h +74 -0
  128. package/native-src/src/librats/dht/transport.h +27 -0
  129. package/native-src/src/librats/dht/traversal.cpp +326 -0
  130. package/native-src/src/librats/dht/traversal.h +120 -0
  131. package/native-src/src/librats/dht/udp_transport.cpp +49 -0
  132. package/native-src/src/librats/dht/udp_transport.h +51 -0
  133. package/native-src/src/librats/mdns/log.h +22 -0
  134. package/native-src/src/{mdns.cpp → librats/mdns/mdns.cpp} +75 -40
  135. package/native-src/src/{mdns.h → librats/mdns/mdns.h} +9 -8
  136. package/native-src/src/{natpmp.cpp → librats/nat/natpmp.cpp} +12 -9
  137. package/native-src/src/{natpmp.h → librats/nat/natpmp.h} +3 -3
  138. package/native-src/src/{port_mapping.h → librats/nat/port_mapping.h} +3 -2
  139. package/native-src/src/{stun.cpp → librats/nat/stun.cpp} +4 -4
  140. package/native-src/src/{stun.h → librats/nat/stun.h} +1 -1
  141. package/native-src/src/{upnp.cpp → librats/nat/upnp.cpp} +6 -6
  142. package/native-src/src/{upnp.h → librats/nat/upnp.h} +2 -2
  143. package/native-src/src/librats/node/circuit_service.h +84 -0
  144. package/native-src/src/librats/node/config.h +110 -0
  145. package/native-src/src/librats/node/dial_service.h +54 -0
  146. package/native-src/src/librats/node/dialer.cpp +264 -0
  147. package/native-src/src/librats/node/dialer.h +188 -0
  148. package/native-src/src/librats/node/host_events.h +26 -0
  149. package/native-src/src/librats/node/identify.cpp +130 -0
  150. package/native-src/src/librats/node/identify.h +71 -0
  151. package/native-src/src/librats/node/nat_status.cpp +103 -0
  152. package/native-src/src/librats/node/nat_status.h +118 -0
  153. package/native-src/src/librats/node/node.cpp +865 -0
  154. package/native-src/src/librats/node/node.h +344 -0
  155. package/native-src/src/librats/node/node_context.h +33 -0
  156. package/native-src/src/librats/node/peer_network.h +91 -0
  157. package/native-src/src/librats/peer/peer.h +49 -0
  158. package/native-src/src/librats/peer/peer_book.cpp +181 -0
  159. package/native-src/src/librats/peer/peer_book.h +88 -0
  160. package/native-src/src/librats/peer/peer_id.cpp +72 -0
  161. package/native-src/src/librats/peer/peer_id.h +62 -0
  162. package/native-src/src/librats/peer/peer_info.h +37 -0
  163. package/native-src/src/librats/peer/peer_table.cpp +170 -0
  164. package/native-src/src/librats/peer/peer_table.h +148 -0
  165. package/native-src/src/librats/security/handshaker.h +66 -0
  166. package/native-src/src/librats/security/identity.h +43 -0
  167. package/native-src/src/librats/security/noise_security.cpp +122 -0
  168. package/native-src/src/librats/security/noise_security.h +37 -0
  169. package/native-src/src/librats/security/plaintext_security.h +106 -0
  170. package/native-src/src/librats/security/session.h +37 -0
  171. package/native-src/src/{storage.cpp → librats/storage/storage.cpp} +369 -522
  172. package/native-src/src/{storage.h → librats/storage/storage.h} +135 -299
  173. package/native-src/src/librats/subsystems/bittorrent.cpp +211 -0
  174. package/native-src/src/librats/subsystems/bittorrent.h +136 -0
  175. package/native-src/src/librats/subsystems/dht_discovery.cpp +202 -0
  176. package/native-src/src/librats/subsystems/dht_discovery.h +123 -0
  177. package/native-src/src/librats/subsystems/dht_service.h +36 -0
  178. package/native-src/src/librats/subsystems/file_transfer.cpp +972 -0
  179. package/native-src/src/librats/subsystems/file_transfer.h +367 -0
  180. package/native-src/src/librats/subsystems/hole_punch.cpp +605 -0
  181. package/native-src/src/librats/subsystems/hole_punch.h +290 -0
  182. package/native-src/src/librats/subsystems/hole_punch_service.h +38 -0
  183. package/native-src/src/librats/subsystems/mdns_discovery.cpp +66 -0
  184. package/native-src/src/librats/subsystems/mdns_discovery.h +55 -0
  185. package/native-src/src/librats/subsystems/message_json.cpp +112 -0
  186. package/native-src/src/librats/subsystems/message_json.h +88 -0
  187. package/native-src/src/librats/subsystems/peer_exchange.cpp +241 -0
  188. package/native-src/src/librats/subsystems/peer_exchange.h +136 -0
  189. package/native-src/src/librats/subsystems/ping_service.cpp +98 -0
  190. package/native-src/src/librats/subsystems/ping_service.h +66 -0
  191. package/native-src/src/librats/subsystems/port_mapping_service.cpp +192 -0
  192. package/native-src/src/librats/subsystems/port_mapping_service.h +84 -0
  193. package/native-src/src/librats/subsystems/pubsub.cpp +567 -0
  194. package/native-src/src/librats/subsystems/pubsub.h +175 -0
  195. package/native-src/src/librats/subsystems/reconnection.cpp +239 -0
  196. package/native-src/src/librats/subsystems/reconnection.h +126 -0
  197. package/native-src/src/librats/subsystems/relay.cpp +1142 -0
  198. package/native-src/src/librats/subsystems/relay.h +211 -0
  199. package/native-src/src/librats/subsystems/relay_service.h +46 -0
  200. package/native-src/src/librats/transport/connection.cpp +343 -0
  201. package/native-src/src/librats/transport/connection.h +283 -0
  202. package/native-src/src/librats/transport/link.h +96 -0
  203. package/native-src/src/librats/transport/reactor.cpp +588 -0
  204. package/native-src/src/librats/transport/reactor.h +262 -0
  205. package/native-src/src/librats/transport/reactor_pool.h +81 -0
  206. package/native-src/src/librats/transport/relay_link.cpp +208 -0
  207. package/native-src/src/librats/transport/relay_link.h +303 -0
  208. package/native-src/src/librats/transport/tcp_link.cpp +49 -0
  209. package/native-src/src/librats/transport/tcp_link.h +43 -0
  210. package/native-src/src/librats/transport/udp_mux.cpp +617 -0
  211. package/native-src/src/librats/transport/udp_mux.h +363 -0
  212. package/native-src/src/librats/transport/udp_packet.cpp +121 -0
  213. package/native-src/src/librats/transport/udp_packet.h +190 -0
  214. package/native-src/src/librats/transport/udp_stream.cpp +1194 -0
  215. package/native-src/src/librats/transport/udp_stream.h +614 -0
  216. package/native-src/src/librats/util/features.h.in +51 -0
  217. package/native-src/src/{fs.cpp → librats/util/fs.cpp} +51 -3
  218. package/native-src/src/librats/util/fs.h +136 -0
  219. package/native-src/src/librats/util/json.cpp +1002 -0
  220. package/native-src/src/librats/util/json.h +444 -0
  221. package/native-src/src/{logger.cpp → librats/util/logger.cpp} +1 -1
  222. package/native-src/src/{logger.h → librats/util/logger.h} +43 -31
  223. package/native-src/src/{network_monitor.cpp → librats/util/network_monitor.cpp} +12 -4
  224. package/native-src/src/{network_monitor.h → librats/util/network_monitor.h} +2 -1
  225. package/native-src/src/{network_utils.cpp → librats/util/network_utils.cpp} +38 -23
  226. package/native-src/src/{network_utils.h → librats/util/network_utils.h} +15 -8
  227. package/native-src/src/{os.cpp → librats/util/os.cpp} +48 -18
  228. package/native-src/src/librats/util/rats_export.h +69 -0
  229. package/native-src/src/{version.cpp → librats/util/version.cpp} +2 -2
  230. package/native-src/src/{version.h.in → librats/util/version.h.in} +1 -1
  231. package/native-src/src/librats/wire/frame.cpp +76 -0
  232. package/native-src/src/librats/wire/frame.h +111 -0
  233. package/native-src/src/librats/wire/message_router.cpp +45 -0
  234. package/native-src/src/librats/wire/message_router.h +47 -0
  235. package/package.json +5 -4
  236. package/scripts/build-librats.js +1 -0
  237. package/scripts/postinstall.js +3 -3
  238. package/scripts/prepare-package.js +4 -4
  239. package/scripts/verify-installation.js +63 -105
  240. package/src/librats_node.cpp +1067 -1323
  241. package/native-src/src/bencode.cpp +0 -485
  242. package/native-src/src/bencode.h +0 -145
  243. package/native-src/src/bittorrent.cpp +0 -14
  244. package/native-src/src/bittorrent.h +0 -74
  245. package/native-src/src/bt_bitfield.cpp +0 -372
  246. package/native-src/src/bt_bitfield.h +0 -316
  247. package/native-src/src/bt_choker.cpp +0 -228
  248. package/native-src/src/bt_choker.h +0 -147
  249. package/native-src/src/bt_client.cpp +0 -1047
  250. package/native-src/src/bt_client.h +0 -445
  251. package/native-src/src/bt_create_torrent.cpp +0 -677
  252. package/native-src/src/bt_create_torrent.h +0 -473
  253. package/native-src/src/bt_extension.cpp +0 -469
  254. package/native-src/src/bt_extension.h +0 -309
  255. package/native-src/src/bt_file_storage.cpp +0 -261
  256. package/native-src/src/bt_file_storage.h +0 -298
  257. package/native-src/src/bt_handshake.cpp +0 -134
  258. package/native-src/src/bt_handshake.h +0 -157
  259. package/native-src/src/bt_messages.cpp +0 -364
  260. package/native-src/src/bt_messages.h +0 -324
  261. package/native-src/src/bt_network.cpp +0 -1007
  262. package/native-src/src/bt_network.h +0 -417
  263. package/native-src/src/bt_peer_connection.cpp +0 -742
  264. package/native-src/src/bt_peer_connection.h +0 -592
  265. package/native-src/src/bt_piece_picker.cpp +0 -786
  266. package/native-src/src/bt_piece_picker.h +0 -473
  267. package/native-src/src/bt_resume_data.cpp +0 -410
  268. package/native-src/src/bt_resume_data.h +0 -249
  269. package/native-src/src/bt_torrent.cpp +0 -2120
  270. package/native-src/src/bt_torrent.h +0 -641
  271. package/native-src/src/bt_torrent_info.cpp +0 -659
  272. package/native-src/src/bt_torrent_info.h +0 -418
  273. package/native-src/src/bt_types.h +0 -621
  274. package/native-src/src/chained_send_buffer.cpp +0 -75
  275. package/native-src/src/chained_send_buffer.h +0 -137
  276. package/native-src/src/crypto/hkdf.c +0 -266
  277. package/native-src/src/crypto/poly1305.h +0 -36
  278. package/native-src/src/dht.cpp +0 -3311
  279. package/native-src/src/dht.h +0 -717
  280. package/native-src/src/disk_io.cpp +0 -632
  281. package/native-src/src/disk_io.h +0 -315
  282. package/native-src/src/file_transfer.cpp +0 -1415
  283. package/native-src/src/file_transfer.h +0 -286
  284. package/native-src/src/fs.h +0 -108
  285. package/native-src/src/gossipsub.cpp +0 -1139
  286. package/native-src/src/gossipsub.h +0 -403
  287. package/native-src/src/ice.cpp +0 -893
  288. package/native-src/src/ice.h +0 -559
  289. package/native-src/src/json.hpp +0 -25526
  290. package/native-src/src/librats.cpp +0 -2378
  291. package/native-src/src/librats.h +0 -2324
  292. package/native-src/src/librats_bittorrent.cpp +0 -601
  293. package/native-src/src/librats_c.cpp +0 -1557
  294. package/native-src/src/librats_c.h +0 -323
  295. package/native-src/src/librats_discovery.cpp +0 -402
  296. package/native-src/src/librats_encryption.cpp +0 -275
  297. package/native-src/src/librats_file_transfer.cpp +0 -144
  298. package/native-src/src/librats_gossipsub.cpp +0 -289
  299. package/native-src/src/librats_ice.cpp +0 -213
  300. package/native-src/src/librats_log_macros.h +0 -36
  301. package/native-src/src/librats_logging.cpp +0 -173
  302. package/native-src/src/librats_mdns.cpp +0 -166
  303. package/native-src/src/librats_persistence.cpp +0 -796
  304. package/native-src/src/librats_portmap.cpp +0 -419
  305. package/native-src/src/librats_reconnection.cpp +0 -218
  306. package/native-src/src/librats_statistic.cpp +0 -105
  307. package/native-src/src/librats_storage.cpp +0 -189
  308. package/native-src/src/rats_export.h +0 -17
  309. package/native-src/src/receive_buffer.cpp +0 -82
  310. package/native-src/src/receive_buffer.h +0 -127
  311. package/native-src/src/socket.h +0 -228
  312. package/native-src/src/threadmanager.cpp +0 -105
  313. package/native-src/src/threadmanager.h +0 -53
  314. package/native-src/src/tracker.cpp +0 -1264
  315. package/native-src/src/tracker.h +0 -319
  316. package/native-src/src/turn.cpp +0 -762
  317. package/native-src/src/turn.h +0 -460
  318. package/native-src/src/wakeup_pipe.h +0 -60
  319. /package/native-src/src/{os.h → librats/util/os.h} +0 -0
@@ -1,7 +1,40 @@
1
1
  #pragma once
2
2
 
3
- #include "socket.h"
4
- #include "json.hpp"
3
+ /**
4
+ * @file storage.h
5
+ * @brief Distributed key-value store as a pluggable Node subsystem.
6
+ *
7
+ * A replicated key-value database with Last-Write-Wins (LWW) conflict
8
+ * resolution, typed values, binary on-disk persistence, and peer
9
+ * synchronization. It is a `Subsystem`: it reaches the mesh only through
10
+ * `PeerNetwork` (never the Node), exactly like PubSub/FileTransfer.
11
+ *
12
+ * Replication model — an epidemic LWW broadcast:
13
+ * - A local put/remove builds a StorageEntry (a delete is a tombstone entry
14
+ * with `deleted=true`) and broadcasts it to all connected peers.
15
+ * - On receiving an entry, a node applies it under LWW. It re-forwards the
16
+ * entry to its *other* peers ONLY if the entry actually won (carried new
17
+ * information). A duplicate loses LWW and is not forwarded, so flooding
18
+ * terminates naturally — no separate dedup table needed.
19
+ * - On peer connect, both sides exchange a full snapshot (anti-entropy) so a
20
+ * late joiner catches up. LWW makes the merge order-independent.
21
+ *
22
+ * Wire format (MessageType::Storage payload, opcode in byte 0):
23
+ * ENTRY: [1][StorageEntry.serialize()]
24
+ * SYNC_REQUEST: [2]
25
+ * SYNC_RESPONSE: [3][count:u32][StorageEntry.serialize()] * count
26
+ *
27
+ * The class is also usable standalone (no network attached) as a local,
28
+ * persistent key-value store; all network operations no-op until attach().
29
+ */
30
+
31
+ #include "librats/util/rats_export.h"
32
+ #include "librats/node/peer_network.h"
33
+ #include "librats/peer/peer.h"
34
+ #include "librats/peer/peer_id.h"
35
+ #include "librats/core/bytes.h"
36
+ #include "librats/util/json.h"
37
+
5
38
  #include <string>
6
39
  #include <vector>
7
40
  #include <functional>
@@ -16,9 +49,6 @@
16
49
 
17
50
  namespace librats {
18
51
 
19
- // Forward declaration
20
- class RatsClient;
21
-
22
52
  /**
23
53
  * Value types supported by the distributed storage
24
54
  */
@@ -31,7 +61,7 @@ enum class StorageValueType : uint8_t {
31
61
  };
32
62
 
33
63
  /**
34
- * Storage operation types for synchronization
64
+ * Storage operation types for change events
35
65
  */
36
66
  enum class StorageOperation : uint8_t {
37
67
  OP_PUT = 0x01, // Insert or update
@@ -51,42 +81,42 @@ enum class StorageSyncStatus {
51
81
  /**
52
82
  * Storage entry - represents a single key-value pair in the database
53
83
  */
54
- struct StorageEntry {
84
+ struct RATS_API StorageEntry {
55
85
  std::string key; // Key string
56
86
  StorageValueType type; // Value type
57
87
  std::vector<uint8_t> data; // Serialized value data
58
88
  uint64_t timestamp_ms; // Unix timestamp in milliseconds (for LWW)
59
- std::string origin_peer_id; // Peer that created/modified this entry
89
+ std::string origin_peer_id; // Peer that created/modified this entry (hex PeerId)
60
90
  uint32_t checksum; // CRC32 checksum for integrity
61
91
  bool deleted; // Tombstone marker for deleted entries
62
-
63
- StorageEntry()
64
- : type(StorageValueType::BINARY),
65
- timestamp_ms(0),
66
- checksum(0),
92
+
93
+ StorageEntry()
94
+ : type(StorageValueType::BINARY),
95
+ timestamp_ms(0),
96
+ checksum(0),
67
97
  deleted(false) {}
68
-
69
- StorageEntry(const std::string& k, StorageValueType t,
70
- const std::vector<uint8_t>& d, uint64_t ts,
98
+
99
+ StorageEntry(const std::string& k, StorageValueType t,
100
+ const std::vector<uint8_t>& d, uint64_t ts,
71
101
  const std::string& peer_id)
72
- : key(k), type(t), data(d), timestamp_ms(ts),
102
+ : key(k), type(t), data(d), timestamp_ms(ts),
73
103
  origin_peer_id(peer_id), checksum(0), deleted(false) {
74
104
  calculate_checksum();
75
105
  }
76
-
106
+
77
107
  // Calculate CRC32 checksum
78
108
  void calculate_checksum();
79
-
109
+
80
110
  // Verify checksum
81
111
  bool verify_checksum() const;
82
-
112
+
83
113
  // Serialize entry to binary format
84
114
  std::vector<uint8_t> serialize() const;
85
-
115
+
86
116
  // Deserialize entry from binary format
87
- static bool deserialize(const std::vector<uint8_t>& data, size_t offset,
117
+ static bool deserialize(const std::vector<uint8_t>& data, size_t offset,
88
118
  StorageEntry& entry, size_t& bytes_read);
89
-
119
+
90
120
  // Compare for LWW resolution (returns true if this entry wins)
91
121
  bool wins_over(const StorageEntry& other) const;
92
122
  };
@@ -111,19 +141,15 @@ struct StorageChangeEvent {
111
141
  struct StorageConfig {
112
142
  std::string data_directory; // Directory for storage files
113
143
  std::string database_name; // Database filename prefix
114
- bool enable_compression; // Enable LZ4 compression for values
115
144
  bool enable_sync; // Enable network synchronization
116
- uint32_t sync_batch_size; // Number of entries per sync batch
117
145
  uint32_t compaction_threshold; // Number of tombstones before compaction
118
146
  uint32_t max_value_size; // Maximum value size in bytes
119
147
  bool persist_to_disk; // Whether to persist data to disk
120
-
148
+
121
149
  StorageConfig()
122
150
  : data_directory("./storage"),
123
151
  database_name("rats_storage"),
124
- enable_compression(false),
125
152
  enable_sync(true),
126
- sync_batch_size(100),
127
153
  compaction_threshold(1000),
128
154
  max_value_size(16 * 1024 * 1024), // 16MB max value size
129
155
  persist_to_disk(true) {}
@@ -152,351 +178,161 @@ using StorageChangeCallback = std::function<void(const StorageChangeEvent&)>;
152
178
  using StorageSyncCompleteCallback = std::function<void(bool success, const std::string& error_message)>;
153
179
 
154
180
  /**
155
- * StorageManager - Distributed key-value storage with peer synchronization
156
- *
157
- * Features:
158
- * - Binary on-disk storage for efficiency
159
- * - In-memory index for O(1) key lookups
160
- * - Real-time synchronization via GossipSub
161
- * - Last-Write-Wins conflict resolution
162
- * - Full database sync for new peers
163
- * - Typed value support (string, int64, double, binary, JSON)
181
+ * StorageManager - Distributed key-value storage with peer synchronization.
182
+ *
183
+ * A Node subsystem: attach()/start()/stop() plug it into a Node, and it reaches
184
+ * the mesh only via PeerNetwork. It can also be used standalone as a local,
185
+ * persistent key-value store (network operations no-op until attached).
164
186
  */
165
- class StorageManager {
187
+ class RATS_API StorageManager final : public Subsystem {
166
188
  public:
167
189
  /**
168
- * Constructor
169
- * @param client Reference to RatsClient for network communication
170
- * @param config Storage configuration settings
190
+ * Constructor.
191
+ * @param config Storage configuration settings.
192
+ *
193
+ * Loads any existing data from disk and starts the background persistence
194
+ * thread immediately, so the store is usable for local reads/writes before
195
+ * (and without) being added to a Node.
171
196
  */
172
- StorageManager(RatsClient& client, const StorageConfig& config = StorageConfig());
173
-
197
+ explicit StorageManager(const StorageConfig& config = StorageConfig());
198
+
174
199
  /**
175
- * Destructor - saves data and cleans up resources
200
+ * Destructor - saves data and cleans up resources.
176
201
  */
177
- ~StorageManager();
178
-
202
+ ~StorageManager() override;
203
+
204
+ StorageManager(const StorageManager&) = delete;
205
+ StorageManager& operator=(const StorageManager&) = delete;
206
+
207
+ // =========================================================================
208
+ // Subsystem
209
+ // =========================================================================
210
+
211
+ void attach(NodeContext& ctx) override;
212
+ void start() override;
213
+ void stop() override;
214
+
179
215
  // =========================================================================
180
216
  // Configuration
181
217
  // =========================================================================
182
-
183
- /**
184
- * Update storage configuration
185
- * @param config New configuration settings
186
- */
218
+
187
219
  void set_config(const StorageConfig& config);
188
-
189
- /**
190
- * Get current configuration
191
- * @return Current configuration settings
192
- */
193
220
  const StorageConfig& get_config() const;
194
-
221
+
195
222
  // =========================================================================
196
223
  // Put Operations (Write)
197
224
  // =========================================================================
198
-
199
- /**
200
- * Store a string value
201
- * @param key Key to store under
202
- * @param value String value to store
203
- * @return true if stored successfully
204
- */
225
+
205
226
  bool put(const std::string& key, const std::string& value);
206
-
207
- /**
208
- * Store a 64-bit integer value
209
- * @param key Key to store under
210
- * @param value Integer value to store
211
- * @return true if stored successfully
212
- */
213
227
  bool put(const std::string& key, int64_t value);
214
-
215
- /**
216
- * Store a double-precision floating point value
217
- * @param key Key to store under
218
- * @param value Double value to store
219
- * @return true if stored successfully
220
- */
221
228
  bool put(const std::string& key, double value);
222
-
223
- /**
224
- * Store binary data
225
- * @param key Key to store under
226
- * @param value Binary data to store
227
- * @return true if stored successfully
228
- */
229
229
  bool put(const std::string& key, const std::vector<uint8_t>& value);
230
-
231
- /**
232
- * Store a JSON document
233
- * @param key Key to store under
234
- * @param value JSON value to store
235
- * @return true if stored successfully
236
- */
237
- bool put_json(const std::string& key, const nlohmann::json& value);
238
-
230
+ bool put_json(const std::string& key, const librats::Json& value);
231
+
239
232
  // =========================================================================
240
233
  // Get Operations (Read)
241
234
  // =========================================================================
242
-
243
- /**
244
- * Get a string value
245
- * @param key Key to retrieve
246
- * @return Optional containing value if found and type matches
247
- */
235
+
248
236
  std::optional<std::string> get_string(const std::string& key) const;
249
-
250
- /**
251
- * Get a 64-bit integer value
252
- * @param key Key to retrieve
253
- * @return Optional containing value if found and type matches
254
- */
255
237
  std::optional<int64_t> get_int(const std::string& key) const;
256
-
257
- /**
258
- * Get a double-precision floating point value
259
- * @param key Key to retrieve
260
- * @return Optional containing value if found and type matches
261
- */
262
238
  std::optional<double> get_double(const std::string& key) const;
263
-
264
- /**
265
- * Get binary data
266
- * @param key Key to retrieve
267
- * @return Optional containing value if found and type matches
268
- */
269
239
  std::optional<std::vector<uint8_t>> get_binary(const std::string& key) const;
270
-
271
- /**
272
- * Get a JSON document
273
- * @param key Key to retrieve
274
- * @return Optional containing value if found and type matches
275
- */
276
- std::optional<nlohmann::json> get_json(const std::string& key) const;
277
-
278
- /**
279
- * Get raw entry (for advanced usage)
280
- * @param key Key to retrieve
281
- * @return Pointer to entry or nullptr if not found
282
- */
283
- const StorageEntry* get_entry(const std::string& key) const;
284
-
285
- /**
286
- * Get the type of a stored value
287
- * @param key Key to check
288
- * @return Optional containing type if key exists
289
- */
240
+ std::optional<librats::Json> get_json(const std::string& key) const;
290
241
  std::optional<StorageValueType> get_type(const std::string& key) const;
291
-
242
+
292
243
  // =========================================================================
293
244
  // Delete and Query Operations
294
245
  // =========================================================================
295
-
296
- /**
297
- * Delete a key
298
- * @param key Key to delete
299
- * @return true if key existed and was deleted
300
- */
246
+
301
247
  bool remove(const std::string& key);
302
-
303
- /**
304
- * Check if a key exists
305
- * @param key Key to check
306
- * @return true if key exists and is not deleted
307
- */
308
248
  bool has(const std::string& key) const;
309
-
310
- /**
311
- * Get all keys
312
- * @return Vector of all keys in storage
313
- */
314
249
  std::vector<std::string> keys() const;
315
-
316
- /**
317
- * Get keys matching a prefix
318
- * @param prefix Prefix to match
319
- * @return Vector of matching keys
320
- */
321
250
  std::vector<std::string> keys_with_prefix(const std::string& prefix) const;
322
-
323
- /**
324
- * Get the number of stored entries (excluding tombstones)
325
- * @return Number of active entries
326
- */
327
251
  size_t size() const;
328
-
329
- /**
330
- * Check if storage is empty
331
- * @return true if no active entries exist
332
- */
333
252
  bool empty() const;
334
-
335
- /**
336
- * Clear all entries
337
- */
338
253
  void clear();
339
-
254
+
340
255
  // =========================================================================
341
256
  // Persistence Operations
342
257
  // =========================================================================
343
-
344
- /**
345
- * Save storage to disk
346
- * @return true if saved successfully
347
- */
258
+
348
259
  bool save();
349
-
350
- /**
351
- * Load storage from disk
352
- * @return true if loaded successfully
353
- */
354
260
  bool load();
355
-
356
- /**
357
- * Compact storage (remove tombstones)
358
- * @return Number of tombstones removed
359
- */
360
261
  size_t compact();
361
-
262
+
362
263
  // =========================================================================
363
264
  // Synchronization Operations
364
265
  // =========================================================================
365
-
366
- /**
367
- * Request full sync from connected peers
368
- * @return true if sync request was sent
369
- */
266
+
267
+ /// Request a full snapshot from one connected peer.
370
268
  bool request_sync();
371
-
372
- /**
373
- * Get current sync status
374
- * @return Current synchronization status
375
- */
376
269
  StorageSyncStatus get_sync_status() const;
377
-
378
- /**
379
- * Check if initial sync is complete
380
- * @return true if at least one full sync has completed
381
- */
382
270
  bool is_synced() const;
383
-
271
+
384
272
  // =========================================================================
385
273
  // Event Callbacks
386
274
  // =========================================================================
387
-
388
- /**
389
- * Set callback for storage changes
390
- * @param callback Function to call when storage changes
391
- */
275
+
392
276
  void set_change_callback(StorageChangeCallback callback);
393
-
394
- /**
395
- * Set callback for sync completion
396
- * @param callback Function to call when sync completes
397
- */
398
277
  void set_sync_complete_callback(StorageSyncCompleteCallback callback);
399
-
278
+
400
279
  // =========================================================================
401
- // Statistics and Debugging
280
+ // Statistics
402
281
  // =========================================================================
403
-
404
- /**
405
- * Get storage statistics
406
- * @return Statistics structure
407
- */
282
+
408
283
  StorageStatistics get_statistics() const;
409
-
410
- /**
411
- * Get statistics as JSON
412
- * @return JSON object with statistics
413
- */
414
- nlohmann::json get_statistics_json() const;
415
-
416
- // =========================================================================
417
- // Internal Network Message Handlers (called by RatsClient)
418
- // =========================================================================
419
-
420
- /**
421
- * Handle storage-related GossipSub message
422
- * @param peer_id Source peer ID
423
- * @param topic Topic name
424
- * @param message Message content
425
- */
426
- void handle_gossip_message(const std::string& peer_id, const std::string& topic,
427
- const std::string& message);
428
-
429
- /**
430
- * Handle storage sync request from peer
431
- * @param peer_id Requesting peer ID
432
- * @param data Request data
433
- */
434
- void handle_sync_request(const std::string& peer_id, const nlohmann::json& data);
435
-
436
- /**
437
- * Handle storage sync response from peer
438
- * @param peer_id Responding peer ID
439
- * @param data Response data containing entries
440
- */
441
- void handle_sync_response(const std::string& peer_id, const nlohmann::json& data);
442
-
443
- /**
444
- * Called when a new peer connects (to trigger sync if needed)
445
- * @param peer_id Connected peer ID
446
- */
447
- void on_peer_connected(const std::string& peer_id);
448
-
284
+ librats::Json get_statistics_json() const;
285
+
449
286
  private:
450
- RatsClient& client_;
287
+ // Network message handlers (run on a reactor thread).
288
+ void on_storage_message(const PeerId& from, ByteView payload);
289
+ void on_peer_connected(const PeerId& peer_id);
290
+
291
+ PeerNetwork* network_ = nullptr;
451
292
  StorageConfig config_;
452
-
293
+
453
294
  // In-memory storage
454
295
  mutable std::mutex storage_mutex_;
455
296
  std::unordered_map<std::string, StorageEntry> entries_;
456
-
297
+
457
298
  // Sync state
458
299
  mutable std::mutex sync_mutex_;
459
300
  StorageSyncStatus sync_status_;
460
301
  bool initial_sync_complete_;
461
- std::string sync_peer_id_; // Peer we're syncing from
462
302
  std::chrono::steady_clock::time_point last_sync_time_;
463
-
303
+
464
304
  // Statistics
465
305
  mutable std::mutex stats_mutex_;
466
306
  StorageStatistics stats_;
467
-
307
+
468
308
  // Callbacks
469
309
  StorageChangeCallback change_callback_;
470
310
  StorageSyncCompleteCallback sync_complete_callback_;
471
-
472
- // Background threads
311
+
312
+ // Background persistence thread
473
313
  std::atomic<bool> running_;
474
314
  std::thread persistence_thread_;
475
315
  std::condition_variable persistence_cv_;
476
316
  std::mutex persistence_mutex_;
477
317
  bool dirty_; // Flag indicating unsaved changes
478
-
479
- // GossipSub topic for real-time sync
480
- static constexpr const char* STORAGE_GOSSIP_TOPIC = "_rats_storage";
481
-
482
- // Message type identifiers
483
- static constexpr const char* MSG_TYPE_PUT = "storage_put";
484
- static constexpr const char* MSG_TYPE_DELETE = "storage_delete";
485
- static constexpr const char* MSG_TYPE_SYNC_REQUEST = "storage_sync_request";
486
- static constexpr const char* MSG_TYPE_SYNC_RESPONSE = "storage_sync_response";
487
-
318
+
319
+ // Wire opcodes (MessageType::Storage payload, byte 0)
320
+ static constexpr uint8_t OP_ENTRY = 1;
321
+ static constexpr uint8_t OP_SYNC_REQUEST = 2;
322
+ static constexpr uint8_t OP_SYNC_RESPONSE = 3;
323
+
488
324
  // Private methods
489
325
  void initialize();
490
326
  void shutdown();
491
327
  void persistence_thread_loop();
492
-
328
+
493
329
  // Internal put with full control
494
- bool put_internal(const std::string& key, StorageValueType type,
495
- const std::vector<uint8_t>& data,
330
+ bool put_internal(const std::string& key, StorageValueType type,
331
+ const std::vector<uint8_t>& data,
496
332
  uint64_t timestamp_ms = 0,
497
333
  const std::string& origin_peer_id = "",
498
334
  bool broadcast = true);
499
-
335
+
500
336
  // Serialization helpers
501
337
  std::vector<uint8_t> serialize_value(int64_t value) const;
502
338
  std::vector<uint8_t> serialize_value(double value) const;
@@ -504,24 +340,24 @@ private:
504
340
  int64_t deserialize_int64(const std::vector<uint8_t>& data) const;
505
341
  double deserialize_double(const std::vector<uint8_t>& data) const;
506
342
  std::string deserialize_string(const std::vector<uint8_t>& data) const;
507
-
343
+
508
344
  // Network operations
509
- void broadcast_put(const StorageEntry& entry);
510
- void broadcast_delete(const std::string& key, uint64_t timestamp_ms);
511
- void send_sync_request(const std::string& peer_id);
512
- void send_sync_response(const std::string& peer_id);
513
-
514
- // Apply remote changes with LWW resolution
515
- bool apply_remote_entry(const StorageEntry& entry);
516
-
345
+ void broadcast_entry(const StorageEntry& entry); ///< to all peers
346
+ void forward_entry(const StorageEntry& entry, const PeerId& except); ///< re-flood
347
+ void send_sync_request(const PeerId& peer_id);
348
+ void send_sync_response(const PeerId& peer_id);
349
+
350
+ // Apply a remote entry with LWW; fills `out_event` and returns true if applied.
351
+ bool apply_remote_entry(const StorageEntry& entry, StorageChangeEvent* out_event);
352
+
517
353
  // File path helpers
518
354
  std::string get_data_file_path() const;
519
355
  std::string get_index_file_path() const;
520
-
356
+
521
357
  // Disk I/O
522
358
  bool write_data_file();
523
359
  bool read_data_file();
524
-
360
+
525
361
  // Utility
526
362
  uint64_t get_current_timestamp_ms() const;
527
363
  std::string get_our_peer_id() const;