@tradelayerprotocol/tradelayer 1.9.1

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 (249) hide show
  1. package/.claude/settings.local.json +13 -0
  2. package/.claude/skills/tl-algo/SKILL.md +255 -0
  3. package/.gitattributes +2 -0
  4. package/.github/workflows/publish.yaml +26 -0
  5. package/4mm.js +163 -0
  6. package/LICENSE +21 -0
  7. package/NPMSwapRefactor.zip +0 -0
  8. package/README.md +217 -0
  9. package/address.sh +26 -0
  10. package/algoAPI.js +581 -0
  11. package/analyzepsbt.js +92 -0
  12. package/apiEx.js +99 -0
  13. package/bb_hyperscalper.js +290 -0
  14. package/bbo_demo.js +111 -0
  15. package/buyer.js +622 -0
  16. package/client.js +50 -0
  17. package/createTxTest.js +26 -0
  18. package/createWallet.js +75 -0
  19. package/daytrader.js +531 -0
  20. package/decodeTest.js +69 -0
  21. package/fundingManager.js +144 -0
  22. package/index.js +4 -0
  23. package/listener.js +27 -0
  24. package/litecoreTxBuilder.js +1128 -0
  25. package/mmEx.js +356 -0
  26. package/networks.js +51 -0
  27. package/orderbook.js +200 -0
  28. package/package.json +34 -0
  29. package/perTradeQueue.js +36 -0
  30. package/projectsTLNPMTLNPM/package-lock.json +162 -0
  31. package/projectsTLNPMTLNPM/package.json +5 -0
  32. package/quick.js +32 -0
  33. package/quickFut.js +37 -0
  34. package/quickSell.js +37 -0
  35. package/relayerClient.js +117 -0
  36. package/run4mm.js +80 -0
  37. package/run_bbo_tracker.js +241 -0
  38. package/seller.js +443 -0
  39. package/session.js +45 -0
  40. package/setup-lin-ltc.sh +139 -0
  41. package/setup-lin.sh +203 -0
  42. package/setup-win-ltc.bat +108 -0
  43. package/setup-win.bat +167 -0
  44. package/spam_screamer_futures.js +222 -0
  45. package/tradelayer.js/.gitattributes +2 -0
  46. package/tradelayer.js/README.md +2 -0
  47. package/tradelayer.js/oldTests/activationTest.js +6 -0
  48. package/tradelayer.js/oldTests/base58.test.js +23 -0
  49. package/tradelayer.js/oldTests/base64Decode.test.js +16 -0
  50. package/tradelayer.js/oldTests/blocksRefactor.js +140 -0
  51. package/tradelayer.js/oldTests/checkVestBalance.js +25 -0
  52. package/tradelayer.js/oldTests/consensusHashProto.js +151 -0
  53. package/tradelayer.js/oldTests/contractOrderbook.js +243 -0
  54. package/tradelayer.js/oldTests/createPayload.js +0 -0
  55. package/tradelayer.js/oldTests/createTestnetAddr.js +43 -0
  56. package/tradelayer.js/oldTests/decode.js +205 -0
  57. package/tradelayer.js/oldTests/decodeTest.js +50 -0
  58. package/tradelayer.js/oldTests/displayTallyMap.js +19 -0
  59. package/tradelayer.js/oldTests/encodeDecode.js +340 -0
  60. package/tradelayer.js/oldTests/expressTest.js +29 -0
  61. package/tradelayer.js/oldTests/extractBlocksVanilla.js +214 -0
  62. package/tradelayer.js/oldTests/extractBlocksVanillaa.js +179 -0
  63. package/tradelayer.js/oldTests/extractPubkeyTest.js +60 -0
  64. package/tradelayer.js/oldTests/fillInputCacheProto.js +111 -0
  65. package/tradelayer.js/oldTests/getRawTxTest.js +22 -0
  66. package/tradelayer.js/oldTests/indexTest.js +26 -0
  67. package/tradelayer.js/oldTests/initTokensTest.js +32 -0
  68. package/tradelayer.js/oldTests/interfaceChild.js +129 -0
  69. package/tradelayer.js/oldTests/listenerChild.js +112 -0
  70. package/tradelayer.js/oldTests/opdecode.js +26 -0
  71. package/tradelayer.js/oldTests/options.js +79 -0
  72. package/tradelayer.js/oldTests/optxtest.js +116 -0
  73. package/tradelayer.js/oldTests/optxtest1.js +64 -0
  74. package/tradelayer.js/oldTests/oracle.test.js +32 -0
  75. package/tradelayer.js/oldTests/orderbook.test.js +36 -0
  76. package/tradelayer.js/oldTests/parsing.js +93 -0
  77. package/tradelayer.js/oldTests/payload.js +13 -0
  78. package/tradelayer.js/oldTests/persistenceUnitTest.js +23 -0
  79. package/tradelayer.js/oldTests/property.test.js +53 -0
  80. package/tradelayer.js/oldTests/propertyLevel.js +75 -0
  81. package/tradelayer.js/oldTests/propertyTest.js +32 -0
  82. package/tradelayer.js/oldTests/queryAddressTest.js +17 -0
  83. package/tradelayer.js/oldTests/salter.js +14 -0
  84. package/tradelayer.js/oldTests/tally.js +81 -0
  85. package/tradelayer.js/oldTests/tally.test.js +48 -0
  86. package/tradelayer.js/oldTests/tally2.js +124 -0
  87. package/tradelayer.js/oldTests/tally3.js +142 -0
  88. package/tradelayer.js/oldTests/tallyDiag.js +38 -0
  89. package/tradelayer.js/oldTests/testGetRaw.js +40 -0
  90. package/tradelayer.js/oldTests/testHexConvert.js +47 -0
  91. package/tradelayer.js/oldTests/testNewEncoding.js +96 -0
  92. package/tradelayer.js/oldTests/testNewEncoding2.js +113 -0
  93. package/tradelayer.js/oldTests/testNewEncoding3 +112 -0
  94. package/tradelayer.js/oldTests/testNewEncoding3.js +168 -0
  95. package/tradelayer.js/oldTests/testOPReturn.js +102 -0
  96. package/tradelayer.js/oldTests/testPayload.js +23 -0
  97. package/tradelayer.js/oldTests/testRaw.js +50 -0
  98. package/tradelayer.js/oldTests/testSendTooMuch.js +20 -0
  99. package/tradelayer.js/oldTests/testTxBuild +28 -0
  100. package/tradelayer.js/oldTests/testTxBuild.js +42 -0
  101. package/tradelayer.js/oldTests/tokenOrderbook.js +243 -0
  102. package/tradelayer.js/oldTests/txUtilsA.js +515 -0
  103. package/tradelayer.js/oldTests/validityUnitTest.js +53 -0
  104. package/tradelayer.js/oldTests/vaults.js +72 -0
  105. package/tradelayer.js/oldTests/volumeIndex.js +117 -0
  106. package/tradelayer.js/oldTests/volumeIndex2.js +88 -0
  107. package/tradelayer.js/output_base64.txt +1 -0
  108. package/tradelayer.js/package-lock.json +9967 -0
  109. package/tradelayer.js/package.json +61 -0
  110. package/tradelayer.js/server/index.js +88 -0
  111. package/tradelayer.js/server/litecoind.exe +0 -0
  112. package/tradelayer.js/src/activation.js +303 -0
  113. package/tradelayer.js/src/adjuster.js +77 -0
  114. package/tradelayer.js/src/amm.js +400 -0
  115. package/tradelayer.js/src/base256.js +55 -0
  116. package/tradelayer.js/src/base94.js +79 -0
  117. package/tradelayer.js/src/channels.js +1163 -0
  118. package/tradelayer.js/src/clearing.js +3109 -0
  119. package/tradelayer.js/src/clearlist.js +364 -0
  120. package/tradelayer.js/src/client.js +295 -0
  121. package/tradelayer.js/src/consensus.js +613 -0
  122. package/tradelayer.js/src/contractRegistry.js +964 -0
  123. package/tradelayer.js/src/db.js +89 -0
  124. package/tradelayer.js/src/init.js +24 -0
  125. package/tradelayer.js/src/insurance.js +347 -0
  126. package/tradelayer.js/src/interface.js +218 -0
  127. package/tradelayer.js/src/interfaceExpress.js +178 -0
  128. package/tradelayer.js/src/iou.js +509 -0
  129. package/tradelayer.js/src/listener.js +226 -0
  130. package/tradelayer.js/src/logic.js +1702 -0
  131. package/tradelayer.js/src/main.js +927 -0
  132. package/tradelayer.js/src/marginMap.js +2165 -0
  133. package/tradelayer.js/src/options.js +126 -0
  134. package/tradelayer.js/src/oracle.js +394 -0
  135. package/tradelayer.js/src/orderbook.js +4123 -0
  136. package/tradelayer.js/src/persistence.js +554 -0
  137. package/tradelayer.js/src/property.js +411 -0
  138. package/tradelayer.js/src/reOrg.js +41 -0
  139. package/tradelayer.js/src/scaling.js +145 -0
  140. package/tradelayer.js/src/tally.js +1275 -0
  141. package/tradelayer.js/src/tradeHistoryManager.js +552 -0
  142. package/tradelayer.js/src/txDecoder.js +584 -0
  143. package/tradelayer.js/src/txEncoder.js +610 -0
  144. package/tradelayer.js/src/txIndex.js +502 -0
  145. package/tradelayer.js/src/txUtils.js +1392 -0
  146. package/tradelayer.js/src/types.js +429 -0
  147. package/tradelayer.js/src/validity.js +3077 -0
  148. package/tradelayer.js/src/vaults.js +430 -0
  149. package/tradelayer.js/src/vesting.js +491 -0
  150. package/tradelayer.js/src/volumeIndex.js +618 -0
  151. package/tradelayer.js/src/walletInterface.js +220 -0
  152. package/tradelayer.js/src/walletListener.js +665 -0
  153. package/tradelayer.js/tests/256decode.js +82 -0
  154. package/tradelayer.js/tests/UTXOracle.js +205 -0
  155. package/tradelayer.js/tests/base94test.js +23 -0
  156. package/tradelayer.js/tests/cancelTxTest.js +62 -0
  157. package/tradelayer.js/tests/contractInterfaceTest.js +48 -0
  158. package/tradelayer.js/tests/decimalTest.js +65 -0
  159. package/tradelayer.js/tests/decoderTest.js +100 -0
  160. package/tradelayer.js/tests/deltaCount.js +47 -0
  161. package/tradelayer.js/tests/deltaCount2.js +60 -0
  162. package/tradelayer.js/tests/interfaceTest.js +37 -0
  163. package/tradelayer.js/tests/mainTest.js +53 -0
  164. package/tradelayer.js/tests/makeActivationTest.js +24 -0
  165. package/tradelayer.js/tests/maxHeightTest.js +49 -0
  166. package/tradelayer.js/tests/reverseHash.js +72 -0
  167. package/tradelayer.js/tests/sensitiveConsoleOutput.txt +267 -0
  168. package/tradelayer.js/tests/tallyTest.js +40 -0
  169. package/tradelayer.js/tests/testBuybacks.js +46 -0
  170. package/tradelayer.js/tests/testCodeHash.js +49 -0
  171. package/tradelayer.js/tests/testConsensusHash.js +91 -0
  172. package/tradelayer.js/tests/testDecode.js +30 -0
  173. package/tradelayer.js/tests/testEncodingLengths.js +129 -0
  174. package/tradelayer.js/tests/testGetTx +32 -0
  175. package/tradelayer.js/tests/testGetTx.js +32 -0
  176. package/tradelayer.js/tests/testHexHash.js +32 -0
  177. package/tradelayer.js/tests/testIndexHash.js +35 -0
  178. package/tradelayer.js/tests/testInitContracts.js +38 -0
  179. package/tradelayer.js/tests/testMaxConsensus.js +12 -0
  180. package/tradelayer.js/tests/testMaxSynth.js +44 -0
  181. package/tradelayer.js/tests/testMint.js +21 -0
  182. package/tradelayer.js/tests/testNetwork.js +33 -0
  183. package/tradelayer.js/tests/testOrderbookLoad.js +62 -0
  184. package/tradelayer.js/tests/testRebates.js +32 -0
  185. package/tradelayer.js/tests/testRedeem.js +22 -0
  186. package/tradelayer.js/tests/testTokenTrade.js +39 -0
  187. package/tradelayer.js/tests/testTxBuild.js +42 -0
  188. package/tradelayer.js/tests/testUTXOTrade.js +27 -0
  189. package/tradelayer.js/tests/tokenTradeHistory.js +27 -0
  190. package/tradelayer.js/tests/tradeFutures.js +40 -0
  191. package/tradelayer.js/tests/tradeHistoryExample.js +35 -0
  192. package/tradelayer.js/tests/tradeHistoryLoad.js +15 -0
  193. package/tradelayer.js/tests/txScanTest.js +134 -0
  194. package/tradelayer.js/tests/validateTest.js +136 -0
  195. package/tradelayer.js/tests/vestingTest.js +37 -0
  196. package/tradelayer.js/utils/activateMainnet.js +59 -0
  197. package/tradelayer.js/utils/activateMainnetDoge.js +63 -0
  198. package/tradelayer.js/utils/autocompactdb.js +23 -0
  199. package/tradelayer.js/utils/base64toHex.js +32 -0
  200. package/tradelayer.js/utils/broadcastDoge.js +38 -0
  201. package/tradelayer.js/utils/calcRedeem.js +19 -0
  202. package/tradelayer.js/utils/checkNetwork.js +27 -0
  203. package/tradelayer.js/utils/createAddress.js +48 -0
  204. package/tradelayer.js/utils/createAttestation.js +133 -0
  205. package/tradelayer.js/utils/createContract.js +118 -0
  206. package/tradelayer.js/utils/createOracle.js +94 -0
  207. package/tradelayer.js/utils/createwallet.js +20 -0
  208. package/tradelayer.js/utils/crossFuturesTrades.js +57 -0
  209. package/tradelayer.js/utils/crossTokenTrades.js +62 -0
  210. package/tradelayer.js/utils/dumpPriv.js +29 -0
  211. package/tradelayer.js/utils/generateChannel.js +34 -0
  212. package/tradelayer.js/utils/getInfo.js +21 -0
  213. package/tradelayer.js/utils/hardWipe.js +20 -0
  214. package/tradelayer.js/utils/hexTo64.js +16 -0
  215. package/tradelayer.js/utils/importAddress.js +28 -0
  216. package/tradelayer.js/utils/importpriv.js +20 -0
  217. package/tradelayer.js/utils/issueOracleContract.js +67 -0
  218. package/tradelayer.js/utils/issueTokens.js +41 -0
  219. package/tradelayer.js/utils/listunspent.js +66 -0
  220. package/tradelayer.js/utils/litecoinClient.js +30 -0
  221. package/tradelayer.js/utils/loadwallet.js +20 -0
  222. package/tradelayer.js/utils/publishOracle.js +113 -0
  223. package/tradelayer.js/utils/sendActivation.js +21 -0
  224. package/tradelayer.js/utils/sendChannelContractTrade.js +34 -0
  225. package/tradelayer.js/utils/sendChannelTokenTrade.js +34 -0
  226. package/tradelayer.js/utils/sendCommit.js +24 -0
  227. package/tradelayer.js/utils/sendDoge.js +62 -0
  228. package/tradelayer.js/utils/sendDogeMain.js +67 -0
  229. package/tradelayer.js/utils/sendDogeTx.js +46 -0
  230. package/tradelayer.js/utils/sendLTC.js +63 -0
  231. package/tradelayer.js/utils/sendMainnet.js +62 -0
  232. package/tradelayer.js/utils/sendTransfer.js +19 -0
  233. package/tradelayer.js/utils/sendVestTest.js +88 -0
  234. package/tradelayer.js/utils/sendWithdrawal.js +26 -0
  235. package/tradelayer.js/utils/simpleStart.js +8 -0
  236. package/tradelayer.js/utils/startStop.js +27 -0
  237. package/tradelayer.js/utils/structuredTrades.js +136 -0
  238. package/tradelayer.js/utils/verifySignature.js +90 -0
  239. package/tradelayer.js/utils/verifyWitnessAndScriptPubkey.js +41 -0
  240. package/tradelayer.js/utils/walletCache.js +172 -0
  241. package/tradelayer.js/utils/walletContractInterface.js +48 -0
  242. package/tradelayer.js/utils/walletFetchTxs.js +66 -0
  243. package/tradelayer.js/utils/walletUtils.js +97 -0
  244. package/tradelayer.js/utils/wipeDB.js +55 -0
  245. package/tradelayer.js/utils/wipeDBNotTx.js +50 -0
  246. package/txEncoder.js +529 -0
  247. package/utility.js +28 -0
  248. package/verifymessage.js +38 -0
  249. package/ws-transport.js +311 -0
@@ -0,0 +1,613 @@
1
+ const db = require('./db.js');
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const crypto = require('crypto');
5
+ const util = require('util');
6
+ const fsPromises = fs.promises;
7
+ const basePath = path.join(__dirname);
8
+
9
+ class ConsensusDatabase {
10
+ static consensusVector = [];
11
+ constructor() {
12
+ if (ConsensusDatabase.instance) {
13
+ return ConsensusDatabase.instance;
14
+ }
15
+
16
+ const flaggedIPs = []
17
+ ConsensusDatabase.instance = this;
18
+ this.loadFlaggedIPsFromDb(); // Load flagged IPs from the database on initialization
19
+ }
20
+
21
+ /**
22
+ * Store the consensus hash for a given block height.
23
+ * @param {Number} blockHeight - The height of the block.
24
+ * @param {String} consensusHash - The consensus hash for the block.
25
+ */
26
+ static async storeConsensusHash(blockHeight, consensusHash) {
27
+ const query = { _id: `block-${blockHeight}` }; // Use _id as a unique identifier
28
+ const update = { $set: { blockHeight, consensusHash } }; // Update or insert block and consensus hash
29
+
30
+ try {
31
+ const base = await db.getDatabase('consensus')
32
+ await base.updateAsync(query, update, { upsert: true }); // Upsert to insert if it doesn't exist
33
+ console.log(`Consensus hash for block ${blockHeight} stored.`);
34
+ } catch (err) {
35
+ console.error('Error storing consensus hash:', err);
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Retrieve the consensus hash for a given block height.
41
+ * @param {Number} blockHeight - The height of the block.
42
+ * @returns {String|null} - The consensus hash or null if not found.
43
+ */
44
+ static async getConsensusHash(blockHeight) {
45
+ const query = { _id: `block-${blockHeight}` }; // Use _id to find based on the block number
46
+
47
+ try {
48
+ const base = await db.getDatabase('consensus')
49
+ const result = await base.findOneAsync(query); // Find based on the block height (_id)
50
+ if (result) {
51
+ return result.consensusHash; // Return the consensus hash if found
52
+ } else {
53
+ console.warn(`No consensus hash found for block ${blockHeight}`);
54
+ return null;
55
+ }
56
+ } catch (err) {
57
+ console.error('Error retrieving consensus hash:', err);
58
+ return null;
59
+ }
60
+ }
61
+
62
+ static async checkIfTxProcessed(txId) {
63
+ //console.log('inside checkIfTxProcessed ' + txId);
64
+ const base = await db.getDatabase('consensus')
65
+ const result = await base.findOneAsync({ _id: txId });
66
+ //console.log(result);
67
+ return result && result.processed === true;
68
+ }
69
+
70
+ static async getTxParams(txId) {
71
+ const base = await db.getDatabase('consensus')
72
+ const result = await base.findOneAsync({ _id: txId });
73
+ return result.value.processed === true ? result.value.params : null;
74
+ }
75
+
76
+ static async markTxAsProcessed(txId, params) {
77
+ let value = { processed: true, params };
78
+ const base = await db.getDatabase('consensus')
79
+ await base.updateAsync(
80
+ { _id: txId },
81
+ { $set: value },
82
+ { upsert: true }
83
+ );
84
+ }
85
+
86
+ static async getTxParamsForAddress(address) {
87
+ const base = await db.getDatabase('consensus')
88
+ const results = await base.findAsync({ "value.processed": true, "value.params.address": address });
89
+ return results.map(result => result.value.params);
90
+ }
91
+
92
+ static async getTxParamsForBlock(blockHeight) {
93
+ const base = await db.getDatabase('consensus')
94
+ const results = await base.findAsync({ "value.processed": true, "value.params.block": blockHeight });
95
+ return results.map(result => result.value.params);
96
+ }
97
+
98
+ static async getMaxProcessedBlock() {
99
+ const base = await db.getDatabase('consensus')
100
+ const result = await base.findOneAsync({ _id: 'MaxProcessedHeight' });
101
+ return result ? result.value : null;
102
+ }
103
+
104
+ static async getHighestBlockHeight(callback) {
105
+ const base = await db.getDatabase('consensus')
106
+ const result = await base.aggregate([
107
+ { $group: { _id: null, maxBlockHeight: { $max: "$value.params.blockHeight" } } }
108
+ ], (err, result) => {
109
+ if (err) {
110
+ callback(err, null);
111
+ } else {
112
+ const maxBlockHeight = result.length > 0 ? result[0].maxBlockHeight : null;
113
+ callback(null, maxBlockHeight);
114
+ }
115
+ });
116
+ }
117
+
118
+
119
+ static async compareBlockHeights() {
120
+ const maxProcessedBlock = await this.getMaxProcessedBlock();
121
+ const highestBlockHeight = await this.getHighestBlockHeight();
122
+
123
+ const higherBlockHeight = Math.max(maxProcessedBlock, highestBlockHeight);
124
+
125
+ return {
126
+ maxProcessedBlock,
127
+ highestBlockHeight,
128
+ higherBlockHeight
129
+ };
130
+ }
131
+
132
+
133
+ // Function to generate SHA-256 hash
134
+ static generateHash(input) {
135
+ const hash = crypto.createHash('sha256');
136
+ hash.update(input);
137
+ return hash.digest('hex');
138
+ }
139
+
140
+ // 1. txIndexHash: Hash the filtered txIndex
141
+ static async txIndexHash() {
142
+ try {
143
+ const base = await db.getDatabase('txIndex')
144
+ const txIndex = await base.findAsync({});
145
+ const filteredTxIndex = txIndex.filter(tx => tx._id.startsWith('tx'));
146
+ const filteredTxIndexString = JSON.stringify(filteredTxIndex);
147
+ const hash = this.generateHash(filteredTxIndexString);
148
+ console.log('txIndexHash:', hash);
149
+ return hash;
150
+ } catch (err) {
151
+ console.error('Error generating txIndex hash:', err);
152
+ }
153
+ }
154
+
155
+ // Function to get the latest instance of a DB
156
+ static async getLatestInstance(dbName) {
157
+ const base = await db.getDatabase(dbName)
158
+ const data = await base.findAsync({});
159
+ return data.length > 0 ? data[data.length - 1] : null; // Get the latest entry
160
+ }
161
+
162
+ // Function to get all instances from a DB
163
+ static async getAllInstances(dbName) {
164
+ const base = await db.getDatabase(dbName)
165
+ const data = await base.findAsync({});
166
+ return data; // Return all entries
167
+ }
168
+
169
+ // Function to generate stateConsensusHash based on various DBs
170
+ // Function to generate stateConsensusHash based on various DBs
171
+ static async stateConsensusHash(snapshot) {
172
+ try {
173
+ // Retrieve latest instance from tally.db and activations.db
174
+ const latestTally = await this.getLatestInstance('tallyMap');
175
+ const latestActivation = await this.getLatestInstance('activations');
176
+
177
+ // Retrieve everything from other specified DBs
178
+ const channels = await this.getAllInstances('channels');
179
+ const clearlists = await this.getAllInstances('clearlists');
180
+ const contractList = await this.getAllInstances('contractList');
181
+ const feeCache = await this.getAllInstances('feeCache');
182
+ const insurance = await this.getAllInstances('insurance');
183
+ const marginMaps = await this.getAllInstances('marginMaps');
184
+ const oracleData = await this.getAllInstances('oracleData');
185
+ const oracleList = await this.getAllInstances('oracleList');
186
+ const orderBooks = await this.getAllInstances('orderBooks');
187
+ const propertyList = await this.getAllInstances('propertyList');
188
+ const syntheticTokens = await this.getAllInstances('syntheticTokens');
189
+ const vaults = await this.getAllInstances('vaults');
190
+ const volumeIndex = await this.getAllInstances('volumeIndex');
191
+ const withdrawQueue = await this.getAllInstances('withdrawQueue');
192
+
193
+ // Combine all the retrieved data into a single structure
194
+ const combinedState = {
195
+ latestTally,
196
+ latestActivation,
197
+ channels,
198
+ clearlists,
199
+ contractList,
200
+ feeCache,
201
+ insurance,
202
+ marginMaps,
203
+ oracleData,
204
+ oracleList,
205
+ orderBooks,
206
+ propertyList,
207
+ syntheticTokens,
208
+ vaults,
209
+ volumeIndex,
210
+ withdrawQueue
211
+ };
212
+
213
+ // Convert combined data to string
214
+ const combinedStateString = JSON.stringify(combinedState);
215
+
216
+ // Generate and return the SHA-256 hash of the combined state
217
+ const hash = this.generateHash(combinedStateString);
218
+ console.log('stateConsensusHash:', hash);
219
+ if(!snapshot){
220
+ return hash;
221
+ }else if(snapshot){
222
+ return {hash: hash, state: combinedStateString}
223
+ }
224
+
225
+ } catch (err) {
226
+ console.error('Error generating stateConsensus hash:', err);
227
+ }
228
+ }
229
+
230
+ // Function to hash files in the specified folder
231
+ static async hashFiles() {
232
+ try {
233
+ let combinedContent = ''; // Initialize empty string to hold combined file content
234
+
235
+ const jsFiles = [
236
+ 'activation', 'amm', 'channels', 'clearing', 'clearlist', 'consensus', 'contractRegistry',
237
+ 'insurance', 'logic', 'main', 'marginMap', 'options', 'oracle', 'orderbook',
238
+ 'persistence', 'property', 'reOrg', 'tally', 'txDecoder', 'txIndex', 'types',
239
+ 'validity', 'vaults', 'vesting', 'volumeIndex'
240
+ ];
241
+ // Loop through each file, read its content, and append to combinedContent
242
+ for (const file of jsFiles) {
243
+ console.log('file name '+file)
244
+ const name = file+'.js'
245
+ const filePath = path.join(basePath, name);
246
+
247
+ if (fs.existsSync(filePath)) {
248
+ const fileContent = await fsPromises.readFile(filePath, 'utf8');
249
+ combinedContent += fileContent; // Append file content
250
+ } else {
251
+ console.warn(`File not found: ${filePath}`); // Warn if the file is missing
252
+ }
253
+ }
254
+
255
+ // Stringify the combined content
256
+ const combinedContentString = JSON.stringify(combinedContent);
257
+ //console.log('combinedContent '+combinedContentString)
258
+
259
+ // Generate a SHA-256 hash of the combined content
260
+ const hash = crypto.createHash('sha256');
261
+ hash.update(combinedContentString);
262
+ const finalHash = hash.digest('hex');
263
+
264
+ console.log('Final SHA-256 Hash:', finalHash);
265
+ return finalHash;
266
+ } catch (err) {
267
+ console.error('Error reading or hashing files:', err);
268
+ }
269
+ }
270
+
271
+ // Function to fetch the latest activation from activations.db and push into the consensus vector
272
+ static async pushLatestActivationToConsensusVector() {
273
+ try {
274
+ const activationsDb = await db.getDatabase('activations');
275
+ const activations = await activationsDb.findAsync({ _id: 'activationsList' });
276
+
277
+ if (!activations || !activations[0] || !activations[0].value) {
278
+ console.log('No activations found in the database.');
279
+ return;
280
+ }
281
+
282
+ const activationsList = JSON.parse(activations[0].value);
283
+ let latestActivation = null;
284
+ let maxBlock = -1;
285
+
286
+ for (const key in activationsList) {
287
+ const activation = activationsList[key];
288
+ if (activation.activationBlock && activation.activationBlock > maxBlock) {
289
+ maxBlock = activation.activationBlock;
290
+ latestActivation = activation;
291
+ }
292
+ }
293
+
294
+ if (!latestActivation) {
295
+ console.log('No valid activation with an activationBlock found.');
296
+ return;
297
+ }
298
+
299
+ const projectPath = path.resolve(__dirname);
300
+ const codeHash = await ConsensusDatabase.hashFiles(projectPath) || '';
301
+ const wasmCodeHash = '';
302
+ const consensusHash = await ConsensusDatabase.stateConsensusHash();
303
+
304
+ const newConsensusEntry = {
305
+ activation: latestActivation,
306
+ codeHash,
307
+ wasmCodeHash,
308
+ consensusHash,
309
+ blockNumber: maxBlock,
310
+ };
311
+
312
+ this.consensusVector.push(newConsensusEntry);
313
+ console.log('Latest activation pushed to consensus vector:', newConsensusEntry);
314
+ return newConsensusEntry;
315
+
316
+ } catch (err) {
317
+ console.error('Error fetching latest activation or updating consensus vector:', err);
318
+ }
319
+ }
320
+
321
+
322
+
323
+ // Function to save the consensus vector to the consensus.db file
324
+ static async saveConsensusVector() {
325
+ try {
326
+ const consensusDb = await db.getDatabase('consensus');
327
+
328
+ // Check if a document with _id "consensusVector" exists
329
+ const existingConsensusVector = await consensusDb.findOneAsync({ _id: 'consensusVector' });
330
+
331
+ if (existingConsensusVector) {
332
+ // If it exists, update the document
333
+ await consensusDb.updateAsync(
334
+ { _id: 'consensusVector' },
335
+ { $set: { vector: consensusVector } },
336
+ { upsert: true }
337
+ );
338
+ console.log('Consensus vector updated in consensus.db');
339
+ } else {
340
+ // If it doesn't exist, insert a new document
341
+ await consensusDb.insertAsync({
342
+ _id: 'consensusVector',
343
+ vector: consensusVector
344
+ });
345
+ console.log('Consensus vector saved to consensus.db');
346
+ }
347
+ } catch (err) {
348
+ console.error('Error saving consensus vector to consensus.db:', err);
349
+ }
350
+ }
351
+
352
+ static async loadConsensusVector() {
353
+ try {
354
+ const consensusDb = await db.getDatabase('consensus');
355
+
356
+ // Check if a document with _id "consensusVector" exists
357
+ const existingConsensusVector = await consensusDb.findOneAsync({ _id: 'consensusVector' });
358
+
359
+ if (existingConsensusVector) {
360
+ return existingConsensusVector
361
+ } else {
362
+ return console.log('No Consensus vector found.');
363
+ }
364
+ } catch (err) {
365
+ console.error('Error saving consensus vector to consensus.db:', err);
366
+ }
367
+ }
368
+
369
+ static async generateHashes() {
370
+ // These are updated to match the actual method names
371
+ this.txIndexHash = await this.txIndexHash(); // For transaction index hash
372
+ this.consensusStateHash = await this.stateConsensusHash(); // For consensus state hash
373
+ this.codeHash = await this.hashFiles(path.resolve(__dirname)); // For code hash
374
+ }
375
+
376
+ // Consensus handshake function: compares local and incoming hashes
377
+ static async consensusHandshake(incomingHashes) {
378
+ await this.generateHashes(); // Generate both JS and WASM hashes
379
+ await this.populateConsensusVectorFromActivations();
380
+ const localHashes = {
381
+ txIndexHash: this.txIndexHash,
382
+ consensusStateHash: this.consensusStateHash,
383
+ codeHash: this.codeHash || '', // JavaScript hash
384
+ wasmCodeHash: this.wasmCodeHash || '' // WASM/Rust hash
385
+ };
386
+
387
+ console.log('Local Hashes:', localHashes);
388
+ console.log('Incoming Hashes:', incomingHashes);
389
+
390
+ const txIndexMatch = localHashes.txIndexHash === incomingHashes.txIndexHash;
391
+ const consensusStateMatch = localHashes.consensusStateHash === incomingHashes.consensusStateHash;
392
+ const codeHashMatch = localHashes.codeHash === incomingHashes.codeHash;
393
+ const wasmCodeHashMatch = localHashes.wasmCodeHash === incomingHashes.wasmCodeHash;
394
+
395
+ if (!txIndexMatch) {
396
+ console.warn('Transaction index hash does not match!');
397
+ }
398
+ if (!consensusStateMatch) {
399
+ console.warn('Consensus state hash does not match!');
400
+ }
401
+ if (!codeHashMatch) {
402
+ console.warn('Code hash does not match!');
403
+ }
404
+ if (!wasmCodeHashMatch) {
405
+ console.warn('WASM code hash does not match!');
406
+ }
407
+
408
+ const match = txIndexMatch && consensusStateMatch && codeHashMatch && wasmCodeHashMatch;
409
+
410
+ return match;
411
+ }
412
+
413
+
414
+ async investigateDiscrepancy(incomingHashes) {
415
+ try {
416
+ // Load the latest activations list
417
+ const activations = await this.loadActivationsList();
418
+
419
+ // Loop through the activations to compare with incoming codeHash
420
+ for (const [key, activation] of Object.entries(activations)) {
421
+ if (activation.codeHash === incomingHashes.codeHash) {
422
+ // If a match is found, check if the consensus hash also matches
423
+ if (activation.consensusHash === incomingHashes.consensusHash) {
424
+ return { status: 'match', message: 'Code and consensus hash match the existing version.' };
425
+ } else {
426
+ return { status: 'partial-match', message: 'Code hash matches but consensus hash differs.' };
427
+ }
428
+ }
429
+ }
430
+
431
+ // If no matches are found
432
+ return { status: 'unknown', message: 'No matching code hash found in the activations list.' };
433
+
434
+ } catch (error) {
435
+ console.error('Error investigating discrepancy:', error);
436
+ return { status: 'error', message: 'Error investigating discrepancy.' };
437
+ }
438
+ }
439
+
440
+ // Function to call the handshake and handle discrepancies
441
+ // Function to call the handshake and handle discrepancies
442
+ // Function to call the handshake and handle discrepancies
443
+ static async verifyConsensus(incomingHashes) {
444
+ const isHandshakeSuccessful = await this.consensusHandshake(incomingHashes);
445
+
446
+
447
+ if (isHandshakeSuccessful) {
448
+ console.log("Handshake successful, consensus verified.");
449
+ return true;
450
+ } else {
451
+ console.log("Handshake failed, investigating discrepancies...");
452
+ const status = await this.investigateDiscrepancy(incomingHashes);
453
+
454
+ if (status.status === 'unknown') {
455
+ // No match found for the codeHash - claim is suspicious
456
+ console.log("No matching codeHash found. This could be BS or a false claim.");
457
+ return false; // Call BS here and return false
458
+ } else if (status.status === 'partial-match') {
459
+ // CodeHash matches, but consensusHash differs
460
+ console.log("CodeHash matches but consensusHash differs. Attempting to reconstruct consensus...");
461
+
462
+ // Call a function to reconstruct consensus based on the incoming codeHash
463
+ const reconstructedConsensus = await this.reconstructConsensus(incomingHashes.codeHash);
464
+
465
+ // Compare the reconstructed consensus with the incoming consensusHash
466
+ if (reconstructedConsensus === incomingHashes.consensusHash) {
467
+ console.log("Consensus reconstructed successfully, matches the incoming hash.");
468
+ return true;
469
+ } else {
470
+ console.log("Reconstructed consensus does not match the incoming hash. Consensus mismatch.");
471
+ return false; // Return false if consensus reconstruction fails
472
+ }
473
+ } else if (status.status === 'match') {
474
+ // Everything matches, but somehow the handshake failed earlier, let's proceed anyway
475
+ console.log("Code and consensus hash match, but handshake failed earlier. Proceeding...");
476
+ return true;
477
+ }
478
+
479
+ return false; // Default to false if nothing else matches
480
+ }
481
+ }
482
+
483
+
484
+ // Function to reconstruct consensus based on codeHash
485
+ static async reconstructConsensus(codeHash) {
486
+ try {
487
+ // Load the activations list to ensure we have the latest consensus state
488
+ const activations = await this.loadActivationsList();
489
+
490
+ // Find the matching activation by codeHash
491
+ for (const [key, activation] of Object.entries(activations)) {
492
+ if (activation.codeHash === codeHash) {
493
+ console.log('Found matching activation for reconstruction:', activation);
494
+
495
+ // Regenerate the consensus state based on the activation we found
496
+ const reconstructedConsensus = await this.stateConsensusHash();
497
+
498
+ // Log and return the reconstructed consensus hash
499
+ console.log('Reconstructed consensus hash:', reconstructedConsensus);
500
+ return reconstructedConsensus;
501
+ }
502
+ }
503
+
504
+ // If no matching activation is found, return null
505
+ return null;
506
+
507
+ } catch (error) {
508
+ console.error('Error during consensus reconstruction:', error);
509
+ return null; // Return null in case of an error
510
+ }
511
+ }
512
+
513
+ static async crossReferenceFlagList(incomingFlagList) {
514
+ for (const flaggedNode of incomingFlagList) {
515
+ const localEntry = flaggedIPs.find(entry => entry.ip === flaggedNode.ip);
516
+
517
+ if (localEntry) {
518
+ localEntry.flagCount += flaggedNode.flagCount;
519
+ localEntry.reason += `; ${flaggedNode.reason}`;
520
+ localEntry.timestamp = new Date().toISOString();
521
+ } else {
522
+ flaggedIPs.push(flaggedNode);
523
+ }
524
+ }
525
+ }
526
+
527
+ static async flagIP(ipAddress, reason) {
528
+ const existingEntry = flaggedIPs.find(entry => entry.ip === ipAddress);
529
+ if (existingEntry) {
530
+ existingEntry.flagCount += 1;
531
+ existingEntry.timestamp = new Date().toISOString();
532
+ } else {
533
+ flaggedIPs.push({
534
+ ip: ipAddress,
535
+ flagCount: 1,
536
+ reason: reason,
537
+ timestamp: new Date().toISOString()
538
+ });
539
+ }
540
+ console.log(`IP ${ipAddress} flagged for reason: ${reason}`);
541
+ // Save the updated flagged IP list to the database
542
+ await this.saveFlaggedIPsToDb();
543
+ }
544
+
545
+ // Function to populate consensus vector using the activations blob
546
+ static async populateConsensusVectorFromActivations() {
547
+ try {
548
+ const activations = await this.loadActivationsList();
549
+
550
+ for (const [key, activation] of Object.entries(activations)) {
551
+ if (activation.active) {
552
+ const newEntry = {
553
+ codeHash: activation.codeHash || '', // The code hash for this activation
554
+ activationBlock: activation.activationBlock || -1, // The block it was activated
555
+ consensusHash: activation.consensusHash || null // Optional, if available
556
+ };
557
+
558
+ this.consensusVector.push(newEntry);
559
+ }
560
+ }
561
+
562
+ console.log('Consensus vector populated from activations:', this.consensusVector);
563
+ return this.consensusVector;
564
+
565
+ } catch (err) {
566
+ console.error('Error populating consensus vector from activations:', err);
567
+ return null;
568
+ }
569
+ }
570
+
571
+ // Save the flagged IPs list to the database
572
+ static async saveFlaggedIPsToDb() {
573
+ try {
574
+ const flaggedIPsDb = db.getDatabase('flaggedIPs');
575
+ await flaggedIPsDb.updateAsync(
576
+ { _id: 'flaggedIPsList' },
577
+ { $set: { value: JSON.stringify(this.flaggedIPs) } },
578
+ { upsert: true } // Insert if not found
579
+ );
580
+ console.log('Flagged IP list saved to the database.');
581
+ } catch (error) {
582
+ console.error('Error saving flagged IP list to the database:', error);
583
+ }
584
+ }
585
+
586
+ // Load the flagged IPs list from the database
587
+ static async loadFlaggedIPsFromDb() {
588
+ try {
589
+ const flaggedIPsDb = await db.getDatabase('flaggedIPs');
590
+ const entry = await flaggedIPsDb.findOneAsync({ _id: 'flaggedIPsList' });
591
+
592
+ if (entry && entry.value) {
593
+ this.flaggedIPs = JSON.parse(entry.value);
594
+ console.log('Flagged IP list loaded from the database.');
595
+ } else {
596
+ this.flaggedIPs = []; // Initialize to an empty list if not found in DB
597
+ console.log('No flagged IP list found in the database. Initialized with empty list.');
598
+ }
599
+ } catch (error) {
600
+ console.error('Error loading flagged IP list from the database:', error);
601
+ this.flaggedIPs = []; // Initialize to an empty list on error
602
+ }
603
+ }
604
+
605
+ // Method to get the current flagged IPs list
606
+ static getFlaggedIPs() {
607
+ return this.flaggedIPs;
608
+ }
609
+
610
+ }
611
+
612
+ module.exports = ConsensusDatabase;
613
+