web-dc-api 0.1.4 → 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.
Files changed (148) hide show
  1. package/dist/cjs/index.js +1 -1
  2. package/dist/dc.min.js +1 -1
  3. package/dist/esm/index.js +1 -1
  4. package/dist/index.d.ts +934 -878
  5. package/package.json +4 -8
  6. package/dist/cjs/helia-core-B1Xqha7a.js +0 -1
  7. package/dist/cjs/helia-core-D8Uv1KjQ.js +0 -1
  8. package/dist/cjs/polkadot-api-7PhQf3ws.js +0 -1
  9. package/dist/cjs/polkadot-api-CtrJVWuZ.js +0 -1
  10. package/dist/esm/chunks/helia-core-BxMqyK2Y.js +0 -1
  11. package/dist/esm/chunks/helia-core-DMXRpcO-.js +0 -1
  12. package/dist/esm/chunks/polkadot-api-5Y9Bw8VT.js +0 -1
  13. package/dist/esm/chunks/polkadot-api-D69Ioun_.js +0 -1
  14. package/lib/common/blowfish/block.ts +0 -259
  15. package/lib/common/blowfish/cipher.ts +0 -144
  16. package/lib/common/blowfish/const.ts +0 -195
  17. package/lib/common/chain.ts +0 -469
  18. package/lib/common/commonclient.ts +0 -202
  19. package/lib/common/constants.ts +0 -55
  20. package/lib/common/dc-key/ed25519.ts +0 -343
  21. package/lib/common/dc-key/keyManager.ts +0 -424
  22. package/lib/common/dcapi.ts +0 -98
  23. package/lib/common/dcutil.ts +0 -627
  24. package/lib/common/define.ts +0 -70
  25. package/lib/common/error.ts +0 -67
  26. package/lib/common/grpc-dc.ts +0 -104
  27. package/lib/common/module-system.ts +0 -184
  28. package/lib/common/service-worker.ts +0 -234
  29. package/lib/common/types/types.ts +0 -344
  30. package/lib/dc.ts +0 -701
  31. package/lib/implements/account/client.ts +0 -185
  32. package/lib/implements/account/manager.ts +0 -683
  33. package/lib/implements/aiproxy/client.ts +0 -357
  34. package/lib/implements/aiproxy/manager.ts +0 -670
  35. package/lib/implements/cache/client.ts +0 -105
  36. package/lib/implements/cache/manager.ts +0 -127
  37. package/lib/implements/comment/client.ts +0 -982
  38. package/lib/implements/comment/manager.ts +0 -1151
  39. package/lib/implements/dc/client.ts +0 -51
  40. package/lib/implements/dc/manager.ts +0 -33
  41. package/lib/implements/file/client.ts +0 -253
  42. package/lib/implements/file/file-cache-manager.ts +0 -142
  43. package/lib/implements/file/manager.ts +0 -1240
  44. package/lib/implements/file/seekableFileStream.ts +0 -344
  45. package/lib/implements/file/streamwriter.ts +0 -322
  46. package/lib/implements/keyvalue/client.ts +0 -376
  47. package/lib/implements/keyvalue/manager.ts +0 -759
  48. package/lib/implements/message/client.ts +0 -250
  49. package/lib/implements/message/manager.ts +0 -215
  50. package/lib/implements/threaddb/cbor/coding.ts +0 -62
  51. package/lib/implements/threaddb/cbor/event.ts +0 -336
  52. package/lib/implements/threaddb/cbor/node.ts +0 -542
  53. package/lib/implements/threaddb/cbor/record.ts +0 -398
  54. package/lib/implements/threaddb/common/AsyncMutex.ts +0 -24
  55. package/lib/implements/threaddb/common/addrinfo.ts +0 -135
  56. package/lib/implements/threaddb/common/dispatcher.ts +0 -81
  57. package/lib/implements/threaddb/common/idbstore-adapter.ts +0 -260
  58. package/lib/implements/threaddb/common/json-patcher.ts +0 -204
  59. package/lib/implements/threaddb/common/key.ts +0 -290
  60. package/lib/implements/threaddb/common/level-adapter.ts +0 -235
  61. package/lib/implements/threaddb/common/lineReader.ts +0 -79
  62. package/lib/implements/threaddb/common/logstore.ts +0 -215
  63. package/lib/implements/threaddb/common/transformed-datastore.ts +0 -308
  64. package/lib/implements/threaddb/core/app.ts +0 -206
  65. package/lib/implements/threaddb/core/core.ts +0 -230
  66. package/lib/implements/threaddb/core/db.ts +0 -249
  67. package/lib/implements/threaddb/core/event.ts +0 -54
  68. package/lib/implements/threaddb/core/head.ts +0 -89
  69. package/lib/implements/threaddb/core/identity.ts +0 -171
  70. package/lib/implements/threaddb/core/logstore.ts +0 -137
  71. package/lib/implements/threaddb/core/options.ts +0 -14
  72. package/lib/implements/threaddb/core/record.ts +0 -54
  73. package/lib/implements/threaddb/db/collection.ts +0 -1910
  74. package/lib/implements/threaddb/db/db.ts +0 -698
  75. package/lib/implements/threaddb/db/json2Query.ts +0 -192
  76. package/lib/implements/threaddb/db/query.ts +0 -524
  77. package/lib/implements/threaddb/dbclient.ts +0 -543
  78. package/lib/implements/threaddb/dbmanager.ts +0 -1906
  79. package/lib/implements/threaddb/lsstoreds/addr_book.ts +0 -549
  80. package/lib/implements/threaddb/lsstoreds/cache.ts +0 -36
  81. package/lib/implements/threaddb/lsstoreds/cyclic_batch.ts +0 -87
  82. package/lib/implements/threaddb/lsstoreds/global.ts +0 -151
  83. package/lib/implements/threaddb/lsstoreds/headbook.ts +0 -373
  84. package/lib/implements/threaddb/lsstoreds/keybook.ts +0 -297
  85. package/lib/implements/threaddb/lsstoreds/logstore.ts +0 -29
  86. package/lib/implements/threaddb/lsstoreds/metadata.ts +0 -223
  87. package/lib/implements/threaddb/net/define.ts +0 -149
  88. package/lib/implements/threaddb/net/grpcClient.ts +0 -589
  89. package/lib/implements/threaddb/net/grpcserver.ts +0 -146
  90. package/lib/implements/threaddb/net/net.ts +0 -2047
  91. package/lib/implements/threaddb/pb/lstore.proto +0 -38
  92. package/lib/implements/threaddb/pb/lstore.ts +0 -393
  93. package/lib/implements/threaddb/pb/lstore_pb.d.ts +0 -433
  94. package/lib/implements/threaddb/pb/lstore_pb.js +0 -1085
  95. package/lib/implements/threaddb/pb/net.proto +0 -194
  96. package/lib/implements/threaddb/pb/net_pb.d.ts +0 -2349
  97. package/lib/implements/threaddb/pb/net_pb.js +0 -5525
  98. package/lib/implements/threaddb/pb/proto-custom-types.ts +0 -212
  99. package/lib/implements/util/client.ts +0 -72
  100. package/lib/implements/util/manager.ts +0 -146
  101. package/lib/implements/wallet/manager.ts +0 -671
  102. package/lib/index.ts +0 -57
  103. package/lib/interfaces/DCContext.ts +0 -51
  104. package/lib/interfaces/aiproxy-interface.ts +0 -145
  105. package/lib/interfaces/auth-interface.ts +0 -118
  106. package/lib/interfaces/cache-interface.ts +0 -22
  107. package/lib/interfaces/client-interface.ts +0 -11
  108. package/lib/interfaces/comment-interface.ts +0 -167
  109. package/lib/interfaces/components/news-component.ts +0 -0
  110. package/lib/interfaces/database-interface.ts +0 -169
  111. package/lib/interfaces/file-interface.ts +0 -120
  112. package/lib/interfaces/index.ts +0 -10
  113. package/lib/interfaces/keyvalue-interface.ts +0 -156
  114. package/lib/interfaces/message-interface.ts +0 -22
  115. package/lib/interfaces/util-interface.ts +0 -31
  116. package/lib/modules/aiproxy-module.ts +0 -246
  117. package/lib/modules/auth-module.ts +0 -753
  118. package/lib/modules/cache-module.ts +0 -99
  119. package/lib/modules/client-module.ts +0 -71
  120. package/lib/modules/comment-module.ts +0 -429
  121. package/lib/modules/components/news-components.ts +0 -390
  122. package/lib/modules/database-module.ts +0 -598
  123. package/lib/modules/file-module.ts +0 -291
  124. package/lib/modules/index.ts +0 -13
  125. package/lib/modules/keyvalue-module.ts +0 -379
  126. package/lib/modules/message-module.ts +0 -107
  127. package/lib/modules/util-module.ts +0 -148
  128. package/lib/polyfills/process-env-browser.ts +0 -1
  129. package/lib/proto/datasource.ts +0 -93
  130. package/lib/proto/dcnet.proto +0 -1601
  131. package/lib/proto/dcnet_proto.d.ts +0 -22857
  132. package/lib/proto/dcnet_proto.js +0 -55204
  133. package/lib/proto/dcnet_proto_sparse.js +0 -55166
  134. package/lib/proto/oidfetch.proto +0 -25
  135. package/lib/proto/oidfetch_proto.d.ts +0 -585
  136. package/lib/proto/oidfetch_proto.js +0 -1247
  137. package/lib/serverless/babel-browser.ts +0 -39
  138. package/lib/serverless/base_entity.ts +0 -78
  139. package/lib/serverless/base_repository.ts +0 -414
  140. package/lib/serverless/browser_schema_extractor.ts +0 -283
  141. package/lib/serverless/decorator_factory.ts +0 -322
  142. package/lib/util/BrowserLineReader.ts +0 -73
  143. package/lib/util/base64.ts +0 -105
  144. package/lib/util/bcrypt.ts +0 -206
  145. package/lib/util/curve25519Encryption.ts +0 -418
  146. package/lib/util/dccrypt.ts +0 -73
  147. package/lib/util/logger.ts +0 -104
  148. package/lib/util/utils.ts +0 -289
@@ -1,589 +0,0 @@
1
- import type { Libp2p } from "libp2p";
2
- import { ThreadID } from "@textile/threads-id";
3
- import { dcnet as dcnet_proto } from "../../../proto/dcnet_proto";
4
- import { net as net_pb} from "../pb/net_pb";
5
- import { Libp2pGrpcClient } from "grpc-libp2p-client";
6
- import {IThreadLogInfo, SymKey} from "../core/core";
7
- import {Multiaddr as TMultiaddr,multiaddr, registry} from '@multiformats/multiaddr'
8
- import { toString as uint8ArrayToString } from "uint8arrays/to-string";
9
- import { Key as ThreadKey } from '../common/key';
10
- import { Ed25519PubKey,Ed25519PrivKey } from "../../../common/dc-key/ed25519";
11
- import type { PublicKey,PrivateKey } from "@libp2p/interface";
12
- import { extractPublicKeyFromPeerId,extractPeerIdFromMultiaddr } from "../../../common/dc-key/keyManager";
13
- import { NewThreadOptions } from '../core/options';
14
- import {ThreadInfo } from '../core/core';
15
- import { CID } from 'multiformats/cid';
16
- import { PeerRecords, Protocol} from "./define";
17
- import {logToProto, RecordFromProto} from "../cbor/record";
18
- import { IRecord } from "../core/record";
19
- import { PeerId } from "@libp2p/interface";
20
- import {RecordToProto} from "../cbor/record";
21
- import { Net } from "../core/app";
22
- import { dcnet } from "../../../proto/dcnet_proto";
23
- import {ThreadMuliaddr} from "../core/core";
24
- import * as varint from 'uint8-varint'
25
- import { SymmetricKey } from '../common/key';
26
- import { decode } from 'multiformats/hashes/digest';
27
- import { peerIdFromMultihash } from '@libp2p/peer-id';
28
- import {
29
- PeerIDConverter,
30
- CidConverter,
31
- MultiaddrConverter,
32
- ThreadIDConverter,
33
- } from '../pb/proto-custom-types'
34
- import * as buffer from "buffer/";
35
- import { log } from "console";
36
- import { peerIdFromString } from "@libp2p/peer-id";
37
- import { ILogstore } from "../core/logstore";
38
- import { Errors } from "../core/db";
39
- const { Buffer } = buffer;
40
-
41
- export const GrpcStatus = {
42
- OK: 0,
43
- CANCELLED: 1,
44
- UNKNOWN: 2,
45
- INVALID_ARGUMENT: 3,
46
- DEADLINE_EXCEEDED: 4,
47
- NOT_FOUND: 5,
48
- ALREADY_EXISTS: 6,
49
- PERMISSION_DENIED: 7,
50
- RESOURCE_EXHAUSTED: 8,
51
- FAILED_PRECONDITION: 9,
52
- ABORTED: 10,
53
- OUT_OF_RANGE: 11,
54
- UNIMPLEMENTED: 12,
55
- INTERNAL: 13,
56
- UNAVAILABLE: 14,
57
- DATA_LOSS: 15,
58
- UNAUTHENTICATED: 16
59
- };
60
-
61
-
62
- interface Protocol {
63
- code: number
64
- size: number
65
- name: string
66
- resolvable?: boolean | undefined
67
- path?: boolean | undefined
68
- }
69
-
70
- export class DBGrpcClient {
71
- grpcClient: Libp2pGrpcClient;
72
- stream: any;
73
- token: string;
74
- net:Net;
75
-
76
- constructor(
77
- node: Libp2p,
78
- peerAddr: TMultiaddr,
79
- token: string,
80
- net:Net,
81
- protocol?: string
82
- ) {
83
- this.grpcClient = new Libp2pGrpcClient(node, peerAddr, token, protocol);
84
- this.token = token;
85
- this.net = net;
86
- }
87
-
88
-
89
-
90
- async requestThreadID(): Promise<string> {
91
- try {
92
- const message = new dcnet_proto.pb.ThreadIDRequest({});
93
- const messageBytes = dcnet_proto.pb.ThreadIDRequest.encode(message).finish();
94
- const responseData = await this.grpcClient.unaryCall(
95
- "/dcnet.pb.Service/RequestThreadID",
96
- messageBytes,
97
- 30000
98
- );
99
- const decoded = dcnet_proto.pb.ThreadIDReply.decode(responseData);
100
- return uint8ArrayToString(decoded.threadID);
101
- } catch (err) {
102
- console.error("RequestThreadID error:", err);
103
- throw err;
104
- }
105
- }
106
-
107
- async createThread(tid: string,opts:NewThreadOptions): Promise<ThreadInfo> {
108
- try {
109
- if (this.grpcClient.node == null || this.grpcClient.node.peerId == null) {
110
- throw new Error("p2pNode is null or node privateKey is null");
111
- }
112
- if (opts.threadKey == null) {
113
- throw new Error("threadKey is null");
114
- }
115
- const serverPeerId = await extractPeerIdFromMultiaddr(this.grpcClient.peerAddr);
116
- const sPubkey = await extractPublicKeyFromPeerId(serverPeerId);
117
-
118
- const message = new dcnet_proto.pb.CreateThreadRequest({});
119
- message.threadID = new TextEncoder().encode(tid);
120
- message.keys = await this.getThreadKeys(sPubkey, { threadKey: opts.threadKey, logKey: opts.logKey });
121
- message.blockheight = opts.blockHeight;
122
- message.signature = opts.signature;
123
- const messageBytes = dcnet_proto.pb.CreateThreadRequest.encode(message).finish();
124
- const responseData = await this.grpcClient.unaryCall(
125
- "/dcnet.pb.Service/CreateThread",
126
- messageBytes,
127
- 30000
128
- );
129
- const reply = dcnet_proto.pb.ThreadInfoReply.decode(responseData);
130
- const threadInfo = await this.threadInfoFromProto(reply);
131
- return threadInfo;
132
- } catch (err) {
133
- console.error("CreateThread error:", err);
134
- throw err;
135
- }
136
- }
137
-
138
- async addLogToThread(tid: string, lid: string, opts: NewThreadOptions): Promise<void> {
139
- try {
140
-
141
- if (this.grpcClient.node == null || this.grpcClient.node.peerId == null) {
142
- throw new Error("p2pNode is null or node privateKey is null");
143
- }
144
- const serverPeerId = this.grpcClient.node.peerId;
145
- const sPubkey = await extractPublicKeyFromPeerId(serverPeerId);
146
- const message = new dcnet_proto.pb.AddLogToThreadRequest({});
147
- message.threadID = new TextEncoder().encode(tid);
148
- message.logID = new TextEncoder().encode(lid);
149
- message.peerid = new TextEncoder().encode(serverPeerId.toString());
150
- message.blockheight = opts.blockHeight;
151
- message.signature = opts.signature;
152
- const messageBytes = dcnet_proto.pb.AddLogToThreadRequest.encode(message).finish();
153
- await this.grpcClient.unaryCall(
154
- "/dcnet.pb.Service/AddLogToThread",
155
- messageBytes,
156
- 30000
157
- );
158
- } catch (err:any) {
159
- if (err.message.includes("log has binded to thread")) {
160
- return
161
- }
162
- throw err;
163
- }
164
- }
165
-
166
-
167
- async threadInfoFromProto(reply: dcnet_proto.pb.IThreadInfoReply): Promise<ThreadInfo> {
168
- if (!reply.threadID) {
169
- throw new Error('Missing required field: threadID');
170
- }
171
-
172
- const threadID = ThreadID.fromString(new TextDecoder().decode(reply.threadID));
173
- const logs: IThreadLogInfo[] = reply.logs
174
- ? await Promise.all(
175
- reply.logs.map(async lg => {
176
- if (!lg.ID || !lg.pubKey) {
177
- throw new Error('Missing required fields in LogInfo: id or pubKey');
178
- }
179
- const id = PeerIDConverter.fromBytes(lg.ID);
180
- // //logid 解析更新
181
- // const multihash = decode(lg.ID);
182
- // const id = peerIdFromMultihash(multihash);
183
- const pubKey = Ed25519PubKey.publicKeyFromProto(lg.pubKey);
184
- let privKey : Ed25519PrivKey | undefined = undefined;
185
- if (lg.privKey?.length == 64) {
186
- privKey = Ed25519PrivKey.privateKeyFromProto(lg.privKey);
187
- }
188
- const addrs = lg.addrs?.map(addr => MultiaddrConverter.fromBytes(addr)) || [];
189
-
190
- const head = lg.head ? CidConverter.fromBytes(lg.head) :null;
191
-
192
- let counter = -1
193
- if (lg.counter && lg.counter.length > 0) {
194
- const counterBuffer = Buffer.from(lg.counter);
195
- counter = Number(counterBuffer.readBigUInt64BE(0));
196
- }
197
- return {
198
- id,
199
- pubKey,
200
- ...(privKey ? { privKey } : {}),
201
- addrs,
202
- managed: true,
203
- head: {
204
- id: head || CID.parse(''),
205
- counter,
206
- },
207
- };
208
- })
209
- )
210
- : [];
211
-
212
- const addrs: ThreadMuliaddr[] = [];
213
- if (reply.addrs && reply.addrs.length > 0) {
214
- for (const addrBytes of reply.addrs) {
215
- try {
216
- //addrBytes 移除code为406,长度为-1的数据
217
- // 处理含有 /thread 协议的多地址
218
- // thread 协议码为 406
219
- let processedBytes = this.removeThreadProtocol(addrBytes);
220
- // 使用处理后的字节创建多地址
221
- let addr = multiaddr(processedBytes);
222
- const threadMultiaddr = new ThreadMuliaddr(addr, threadID);
223
- addrs.push(threadMultiaddr);
224
- } catch (addrErr:any) {
225
- console.warn(`Skipping invalid multiaddr: ${addrErr.message}`);
226
- // Continue with other addresses
227
- }
228
- }
229
- }
230
- const threadInfo = new ThreadInfo(
231
- threadID,
232
- logs,
233
- addrs
234
- );
235
- return threadInfo;
236
- }
237
-
238
- removeThreadProtocol(bytes: Uint8Array): Uint8Array {
239
-
240
- let i = 0
241
- while (i < bytes.length) {
242
- const code = varint.decode(bytes, i)
243
- if (code == Protocol.code) {// 406,截取前面的数据
244
- return bytes.slice(0, i)
245
- }
246
- const n = varint.encodingLength(code)
247
- const p = protocols(code)
248
- const size = this.sizeForAddr(p, bytes.slice(i + n))
249
-
250
- if (size === 0) {
251
- i += n
252
- continue
253
- }
254
- const addr = bytes.slice(i + n, i + n + size)
255
- i += (size + n)
256
-
257
- if (i > bytes.length) {
258
- throw new Error('invalid multiaddr')
259
- }
260
- if (p.path === true) {
261
- break
262
- }
263
- }
264
- return bytes
265
- }
266
-
267
-
268
-
269
- sizeForAddr (p: Protocol, addr: Uint8Array | number[]): number {
270
- if (p.size > 0) {
271
- return p.size / 8
272
- } else if (p.size === 0) {
273
- return 0
274
- } else {
275
- const size = varint.decode(addr instanceof Uint8Array ? addr : Uint8Array.from(addr))
276
- return size + varint.encodingLength(size)
277
- }
278
- }
279
-
280
- async getThreadKeys(sPubkey: Ed25519PubKey, args: { threadKey: ThreadKey, logKey?: PrivateKey | PublicKey | undefined }): Promise<dcnet_proto.pb.Keys> {
281
- try {
282
- const threadKeyEncrypt = await sPubkey.encrypt(args.threadKey.toBytes());
283
- let logKeyEncrpt: Uint8Array;
284
- if (args.logKey) {
285
- if (args.logKey instanceof Ed25519PrivKey) {
286
- logKeyEncrpt = await sPubkey.encrypt(Ed25519PubKey.publicKeyToProto(args.logKey.publicKey));
287
- }else if (args.logKey instanceof Ed25519PubKey) {
288
- logKeyEncrpt = await sPubkey.encrypt(Ed25519PubKey.publicKeyToProto(args.logKey));
289
- }else{
290
- logKeyEncrpt = await sPubkey.encrypt(args.logKey.raw);
291
- }
292
- }else{
293
- logKeyEncrpt = await sPubkey.encrypt(new Uint8Array(0));
294
- }
295
- const keys = new dcnet_proto.pb.Keys({ threadKeyEncrpt: threadKeyEncrypt, logKeyEncrpt:logKeyEncrpt });
296
- return keys;
297
- } catch (err) {
298
- console.error("getThreadKeys error:", err);
299
- throw err;
300
- }
301
- }
302
-
303
-
304
-
305
-
306
-
307
- /**
308
- * 从特定对等点获取记录
309
- * 注意: 这是一个假设的实现,需要根据你的实际gRPC客户端实现来调整
310
- */
311
- async getRecordsFromPeer(
312
- req: any,
313
- serviceKey: SymmetricKey
314
- ): Promise<Record<string, PeerRecords>> {
315
- try {
316
-
317
- // 编码请求消息
318
- const messageBytes = net_pb.pb.GetRecordsRequest.encode(req).finish();
319
-
320
- // 调用 gRPC 方法
321
- const responseData = await this.grpcClient.unaryCall(
322
- "/net.pb.Service/GetRecords",
323
- messageBytes,
324
- 900000
325
- );
326
-
327
- // 解码响应
328
- const response = net_pb.pb.GetRecordsReply.decode(responseData);
329
-
330
- // 处理响应数据
331
- const result: Record<string, PeerRecords> = {};
332
-
333
- for (const logInfo of response.logs || []) {
334
- if (!logInfo.logID) continue;
335
-
336
- const logId = PeerIDConverter.fromBytes(logInfo.logID).toString();
337
- // const multihash = decode(logInfo.logID);
338
- // const logId = peerIdFromMultihash(multihash).toString();
339
- const rawRecords = logInfo.records || [];
340
-
341
- // 并行转换所有记录
342
- const recordPromises = rawRecords.map(async (rec) => {
343
- return await RecordFromProto(rec as net_pb.pb.Log.Record, serviceKey);
344
- });
345
-
346
- // 等待所有记录转换完成
347
- const unsortedRecords = await Promise.all(recordPromises);
348
-
349
- // 根据链表结构排序记录
350
- const sortedRecords = this.sortRecordsChain(unsortedRecords);
351
-
352
- result[logId] = {
353
- records: sortedRecords,
354
- counter: logInfo.log?.counter as number || 0
355
- };
356
- }
357
-
358
- return result;
359
- } catch (err) {
360
- console.error(`getRecordsFromPeer error:`, err);
361
- throw err;
362
- }
363
- }
364
-
365
-
366
- /**
367
- * 根据链表结构排序记录
368
- * 确保第二个记录的 prevID() 等于第一个记录的 blockID(),以此类推
369
- */
370
- private sortRecordsChain(records: IRecord[]): IRecord[] {
371
- if (records.length <= 1) {
372
- return records;
373
- }
374
-
375
- const sorted: IRecord[] = [];
376
- const recordMap = new Map<string, IRecord>();
377
- let headRecord: IRecord | null = null;
378
-
379
- // 建立 blockID 到记录的映射
380
- for (const record of records) {
381
- const blockId = record.blockID().toString();
382
- recordMap.set(blockId, record);
383
- }
384
-
385
- // 找到链表头部(没有前驱的记录)
386
- for (const record of records) {
387
- const prevId = record.prevID();
388
- if (!prevId || !recordMap.has(prevId.toString())) {
389
- // 这是头部记录(没有前驱或前驱不在当前记录集合中)
390
- headRecord = record;
391
- break;
392
- }
393
- }
394
-
395
- if (!headRecord) {
396
- // 如果找不到明确的头部,尝试找到最早的记录
397
- console.warn('No clear head record found, using first record as head');
398
- headRecord = records[0]? records[0] : null;
399
- }
400
-
401
- // 从头部开始构建有序链表
402
- let currentRecord = headRecord;
403
- const processed = new Set<string>();
404
-
405
- while (currentRecord && !processed.has(currentRecord.blockID().toString())) {
406
- sorted.push(currentRecord);
407
- processed.add(currentRecord.blockID().toString());
408
-
409
- // 查找下一个记录(prevID 指向当前记录的 blockID)
410
- const currentBlockId = currentRecord.blockID().toString();
411
- let nextRecord: IRecord | null = null;
412
-
413
- for (const record of records) {
414
- if (processed.has(record.blockID().toString())) {
415
- continue; // 已处理过
416
- }
417
-
418
- const prevId = record.prevID();
419
- if (prevId && prevId.toString() === currentBlockId) {
420
- nextRecord = record;
421
- break;
422
- }
423
- }
424
-
425
- currentRecord = nextRecord;
426
- }
427
-
428
- // 检查是否所有记录都被处理了
429
- if (sorted.length !== records.length) {
430
- console.warn(
431
- `Chain sorting incomplete: sorted ${sorted.length}/${records.length} records. ` +
432
- 'Some records may not form a continuous chain.'
433
- );
434
-
435
- // 将未处理的记录追加到末尾
436
- for (const record of records) {
437
- if (!processed.has(record.blockID().toString())) {
438
- sorted.push(record);
439
- }
440
- }
441
- }
442
-
443
- return sorted;
444
- }
445
-
446
- async pushRecordToPeer(
447
- tid: ThreadID,
448
- lid: PeerId,
449
- rec: IRecord,
450
- counter: number,
451
- logstore: ILogstore,
452
- ): Promise<void> {
453
- const body = new net_pb.pb.PushRecordRequest.Body();
454
- body.threadID = ThreadIDConverter.toBytes(tid.toString()) ;
455
- body.logID = PeerIDConverter.toBytes(lid.toString());
456
- body.record = await RecordToProto(this.net.bstore, rec);
457
- const message = new net_pb.pb.PushRecordRequest();
458
- message.body = body;
459
- message.counter = counter;
460
- // 编码请求
461
- const messageBytes = net_pb.pb.PushRecordRequest.encode(message).finish();
462
- // 调用gRPC方法
463
- await this.grpcClient.unaryCall(
464
- "/net.pb.Service/PushRecord",
465
- messageBytes,
466
- 30000, // 30秒超时
467
- );
468
- }
469
-
470
-
471
-
472
- async pushLogToPeer(
473
- tid: ThreadID,
474
- lid: PeerId,
475
- logstore: ILogstore,
476
- ): Promise<void> {
477
- try {
478
- const timeout = setTimeout(() => {
479
- throw new Error('Getting log information timed out');
480
- }, 10000); // 10秒超时 (PushTimeout)
481
- // 获取日志信息
482
- const log = await logstore.getLog(tid, lid);
483
- clearTimeout(timeout); // 清除超时
484
- // 准备日志推送请求
485
- const logBody = new net_pb.pb.PushLogRequest.Body();
486
- logBody.threadID = ThreadIDConverter.toBytes(tid.toString());
487
- logBody.log = await logToProto(log);
488
-
489
- const logRequest = new net_pb.pb.PushLogRequest();
490
- logRequest.body = logBody;
491
- // 推送缺失的日志
492
- const logMessageBytes = net_pb.pb.PushLogRequest.encode(logRequest).finish();
493
- await this.grpcClient.unaryCall(
494
- "/net.pb.Service/PushLog",
495
- logMessageBytes,
496
- 30000
497
- );
498
- } catch (logErr) {
499
- throw new Error(`Error pushing missing log: ${logErr instanceof Error ? logErr.message : String(logErr)}`);
500
- }
501
- }
502
-
503
- async exchangeEdges(
504
- req: net_pb.pb.ExchangeEdgesRequest,
505
- ): Promise<net_pb.pb.ExchangeEdgesReply> {
506
- try {
507
- const messageBytes = net_pb.pb.ExchangeEdgesRequest.encode(req).finish();
508
- // 调用 gRPC 方法
509
- const response = await this.grpcClient.unaryCall(
510
- "/net.pb.Service/ExchangeEdges",
511
- messageBytes,
512
- 30000
513
- );
514
- // 解码响应
515
- const reply = net_pb.pb.ExchangeEdgesReply.decode(response);
516
- return reply;
517
- } catch (err) {
518
- console.error("exchangeEdges error:", err);
519
- throw err;
520
- }
521
- }
522
-
523
- /**
524
- * 获取threaddb 中的日志
525
- * @param tid threaddb ID
526
- * @returns 日志信息数组
527
- */
528
- async getLogs(tid: ThreadID, sk:Uint8Array): Promise<net_pb.pb.GetLogsReply> {
529
- try {
530
- const body = new net_pb.pb.GetLogsRequest.Body();
531
- body.threadID = tid.toBytes();
532
- body.serviceKey = sk;
533
-
534
- const req = new net_pb.pb.GetLogsRequest();
535
- req.body = body;
536
- // 编码请求
537
- const messageBytes = net_pb.pb.GetLogsRequest.encode(req).finish();
538
-
539
- // 调用 gRPC 方法
540
- const response = await this.grpcClient.unaryCall(
541
- "/net.pb.Service/GetLogs",
542
- messageBytes,
543
- 30000 // 设置超时时间为30秒
544
- );
545
- // 解码响应
546
- const reply = net_pb.pb.GetLogsReply.decode(response);
547
- return reply
548
- } catch (err) {
549
- console.error(`getLogs error for peer ${this.grpcClient.peerAddr.toString()}:`, err);
550
- throw err;
551
- }
552
- }
553
-
554
- async getThreadFromPeer(tid: ThreadID): Promise<ThreadInfo> {
555
- try {
556
- const req = new dcnet.pb.GetThreadRequest;
557
- req.threadID = tid.toBytes();
558
-
559
- // 编码请求
560
- const messageBytes = dcnet.pb.GetThreadRequest.encode(req).finish();
561
-
562
- // 调用 gRPC 方法
563
- const response = await this.grpcClient.unaryCall(
564
- "/dcnet.pb.Service/GetThread",
565
- messageBytes,
566
- 30000 // 设置超时时间为30秒
567
- );
568
- // 解码响应
569
- const reply = dcnet.pb.ThreadInfoReply.decode(response);
570
- const threadInfo = await this.threadInfoFromProto(reply);
571
- return threadInfo
572
- } catch (err) {
573
- console.error(`getThreadFromPeer error for peer ${this.grpcClient.peerAddr.toString()}:`, err);
574
- throw err;
575
- }
576
- }
577
-
578
- }
579
- function protocols (proto: number | string): Protocol {
580
- const codec = registry.getProtocol(proto)
581
-
582
- return {
583
- code: codec.code,
584
- size: codec.size ?? 0,
585
- name: codec.name,
586
- resolvable: Boolean(codec.resolvable),
587
- path: Boolean(codec.path)
588
- }
589
- }