@f2a/network 0.1.2 → 0.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 (226) hide show
  1. package/README.md +278 -63
  2. package/dist/cli/commands.d.ts.map +1 -1
  3. package/dist/cli/commands.js +29 -2
  4. package/dist/cli/commands.js.map +1 -1
  5. package/dist/cli/config.d.ts +176 -0
  6. package/dist/cli/config.d.ts.map +1 -0
  7. package/dist/cli/config.js +386 -0
  8. package/dist/cli/config.js.map +1 -0
  9. package/dist/cli/daemon.d.ts +54 -0
  10. package/dist/cli/daemon.d.ts.map +1 -0
  11. package/dist/cli/daemon.js +572 -0
  12. package/dist/cli/daemon.js.map +1 -0
  13. package/dist/cli/index.js +90 -16
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/init.d.ts +13 -0
  16. package/dist/cli/init.d.ts.map +1 -0
  17. package/dist/cli/init.js +352 -0
  18. package/dist/cli/init.js.map +1 -0
  19. package/dist/core/e2ee-crypto.d.ts +127 -1
  20. package/dist/core/e2ee-crypto.d.ts.map +1 -1
  21. package/dist/core/e2ee-crypto.js +446 -12
  22. package/dist/core/e2ee-crypto.js.map +1 -1
  23. package/dist/core/f2a.d.ts +2 -1
  24. package/dist/core/f2a.d.ts.map +1 -1
  25. package/dist/core/f2a.js +6 -2
  26. package/dist/core/f2a.js.map +1 -1
  27. package/dist/core/identity/encrypted-key-store.d.ts +19 -0
  28. package/dist/core/identity/encrypted-key-store.d.ts.map +1 -0
  29. package/dist/core/identity/encrypted-key-store.js +72 -0
  30. package/dist/core/identity/encrypted-key-store.js.map +1 -0
  31. package/dist/core/identity/identity-manager.d.ts +133 -0
  32. package/dist/core/identity/identity-manager.d.ts.map +1 -0
  33. package/dist/core/identity/identity-manager.js +454 -0
  34. package/dist/core/identity/identity-manager.js.map +1 -0
  35. package/dist/core/identity/index.d.ts +8 -0
  36. package/dist/core/identity/index.d.ts.map +1 -0
  37. package/dist/core/identity/index.js +7 -0
  38. package/dist/core/identity/index.js.map +1 -0
  39. package/dist/core/identity/types.d.ts +70 -0
  40. package/dist/core/identity/types.d.ts.map +1 -0
  41. package/dist/core/identity/types.js +17 -0
  42. package/dist/core/identity/types.js.map +1 -0
  43. package/dist/core/p2p-network.d.ts +26 -0
  44. package/dist/core/p2p-network.d.ts.map +1 -1
  45. package/dist/core/p2p-network.js +434 -105
  46. package/dist/core/p2p-network.js.map +1 -1
  47. package/dist/core/reputation-security.d.ts +15 -0
  48. package/dist/core/reputation-security.d.ts.map +1 -1
  49. package/dist/core/reputation-security.js +73 -3
  50. package/dist/core/reputation-security.js.map +1 -1
  51. package/dist/core/reputation.d.ts +129 -4
  52. package/dist/core/reputation.d.ts.map +1 -1
  53. package/dist/core/reputation.js +294 -1
  54. package/dist/core/reputation.js.map +1 -1
  55. package/dist/core/review-committee.d.ts +2 -2
  56. package/dist/core/review-committee.d.ts.map +1 -1
  57. package/dist/core/review-committee.js +17 -0
  58. package/dist/core/review-committee.js.map +1 -1
  59. package/dist/daemon/control-server.d.ts.map +1 -1
  60. package/dist/daemon/control-server.js +44 -1
  61. package/dist/daemon/control-server.js.map +1 -1
  62. package/dist/daemon/webhook.d.ts +3 -0
  63. package/dist/daemon/webhook.d.ts.map +1 -1
  64. package/dist/daemon/webhook.js +318 -6
  65. package/dist/daemon/webhook.js.map +1 -1
  66. package/dist/index.d.ts +3 -3
  67. package/dist/index.d.ts.map +1 -1
  68. package/dist/index.js +7 -3
  69. package/dist/index.js.map +1 -1
  70. package/dist/types/index.d.ts +4 -0
  71. package/dist/types/index.d.ts.map +1 -1
  72. package/dist/types/index.js.map +1 -1
  73. package/dist/types/result.d.ts +1 -1
  74. package/dist/types/result.d.ts.map +1 -1
  75. package/dist/types/result.js.map +1 -1
  76. package/dist/utils/crypto-utils.d.ts +17 -0
  77. package/dist/utils/crypto-utils.d.ts.map +1 -0
  78. package/dist/utils/crypto-utils.js +28 -0
  79. package/dist/utils/crypto-utils.js.map +1 -0
  80. package/dist/utils/logger.d.ts +1 -0
  81. package/dist/utils/logger.d.ts.map +1 -1
  82. package/dist/utils/logger.js +9 -3
  83. package/dist/utils/logger.js.map +1 -1
  84. package/dist/utils/rate-limiter.d.ts.map +1 -1
  85. package/dist/utils/rate-limiter.js +3 -1
  86. package/dist/utils/rate-limiter.js.map +1 -1
  87. package/dist/utils/signature.d.ts +47 -1
  88. package/dist/utils/signature.d.ts.map +1 -1
  89. package/dist/utils/signature.js +166 -11
  90. package/dist/utils/signature.js.map +1 -1
  91. package/package.json +9 -1
  92. package/.github/workflows/ci.yml +0 -113
  93. package/.github/workflows/publish.yml +0 -60
  94. package/MONOREPO.md +0 -58
  95. package/SKILL.md +0 -137
  96. package/dist/adapters/openclaw.d.ts +0 -103
  97. package/dist/adapters/openclaw.d.ts.map +0 -1
  98. package/dist/adapters/openclaw.js +0 -297
  99. package/dist/adapters/openclaw.js.map +0 -1
  100. package/dist/core/connection-manager.d.ts +0 -80
  101. package/dist/core/connection-manager.d.ts.map +0 -1
  102. package/dist/core/connection-manager.js +0 -235
  103. package/dist/core/connection-manager.js.map +0 -1
  104. package/dist/core/connection-manager.test.d.ts +0 -2
  105. package/dist/core/connection-manager.test.d.ts.map +0 -1
  106. package/dist/core/connection-manager.test.js +0 -52
  107. package/dist/core/connection-manager.test.js.map +0 -1
  108. package/dist/core/identity.d.ts +0 -47
  109. package/dist/core/identity.d.ts.map +0 -1
  110. package/dist/core/identity.js +0 -130
  111. package/dist/core/identity.js.map +0 -1
  112. package/dist/core/identity.test.d.ts +0 -2
  113. package/dist/core/identity.test.d.ts.map +0 -1
  114. package/dist/core/identity.test.js +0 -43
  115. package/dist/core/identity.test.js.map +0 -1
  116. package/dist/core/serverless.d.ts +0 -155
  117. package/dist/core/serverless.d.ts.map +0 -1
  118. package/dist/core/serverless.js +0 -615
  119. package/dist/core/serverless.js.map +0 -1
  120. package/dist/daemon/webhook.test.d.ts +0 -2
  121. package/dist/daemon/webhook.test.d.ts.map +0 -1
  122. package/dist/daemon/webhook.test.js +0 -24
  123. package/dist/daemon/webhook.test.js.map +0 -1
  124. package/dist/protocol/messages.d.ts +0 -739
  125. package/dist/protocol/messages.d.ts.map +0 -1
  126. package/dist/protocol/messages.js +0 -188
  127. package/dist/protocol/messages.js.map +0 -1
  128. package/dist/protocol/messages.test.d.ts +0 -2
  129. package/dist/protocol/messages.test.d.ts.map +0 -1
  130. package/dist/protocol/messages.test.js +0 -55
  131. package/dist/protocol/messages.test.js.map +0 -1
  132. package/docs/F2A-PROTOCOL.md +0 -61
  133. package/docs/MOBILE_BOOTSTRAP_DESIGN.md +0 -126
  134. package/docs/a2a-lessons.md +0 -316
  135. package/docs/middleware-guide.md +0 -448
  136. package/docs/readme-update-checklist.md +0 -90
  137. package/docs/reputation-guide.md +0 -396
  138. package/docs/rfcs/001-reputation-system.md +0 -712
  139. package/docs/security-design.md +0 -247
  140. package/install.sh +0 -231
  141. package/packages/openclaw-adapter/README.md +0 -510
  142. package/packages/openclaw-adapter/openclaw.plugin.json +0 -106
  143. package/packages/openclaw-adapter/package.json +0 -40
  144. package/packages/openclaw-adapter/src/announcement-queue.test.ts +0 -449
  145. package/packages/openclaw-adapter/src/announcement-queue.ts +0 -403
  146. package/packages/openclaw-adapter/src/capability-detector.test.ts +0 -99
  147. package/packages/openclaw-adapter/src/capability-detector.ts +0 -183
  148. package/packages/openclaw-adapter/src/claim-handlers.test.ts +0 -974
  149. package/packages/openclaw-adapter/src/claim-handlers.ts +0 -482
  150. package/packages/openclaw-adapter/src/connector.business.test.ts +0 -583
  151. package/packages/openclaw-adapter/src/connector.ts +0 -795
  152. package/packages/openclaw-adapter/src/index.test.ts +0 -82
  153. package/packages/openclaw-adapter/src/index.ts +0 -18
  154. package/packages/openclaw-adapter/src/integration.e2e.test.ts +0 -829
  155. package/packages/openclaw-adapter/src/logger.ts +0 -51
  156. package/packages/openclaw-adapter/src/network-client.test.ts +0 -266
  157. package/packages/openclaw-adapter/src/network-client.ts +0 -251
  158. package/packages/openclaw-adapter/src/network-recovery.test.ts +0 -465
  159. package/packages/openclaw-adapter/src/node-manager.test.ts +0 -136
  160. package/packages/openclaw-adapter/src/node-manager.ts +0 -429
  161. package/packages/openclaw-adapter/src/plugin.test.ts +0 -439
  162. package/packages/openclaw-adapter/src/plugin.ts +0 -104
  163. package/packages/openclaw-adapter/src/reputation.test.ts +0 -221
  164. package/packages/openclaw-adapter/src/reputation.ts +0 -368
  165. package/packages/openclaw-adapter/src/task-guard.test.ts +0 -502
  166. package/packages/openclaw-adapter/src/task-guard.ts +0 -860
  167. package/packages/openclaw-adapter/src/task-queue.concurrency.test.ts +0 -462
  168. package/packages/openclaw-adapter/src/task-queue.edge-cases.test.ts +0 -284
  169. package/packages/openclaw-adapter/src/task-queue.persistence.test.ts +0 -408
  170. package/packages/openclaw-adapter/src/task-queue.ts +0 -668
  171. package/packages/openclaw-adapter/src/tool-handlers.test.ts +0 -906
  172. package/packages/openclaw-adapter/src/tool-handlers.ts +0 -574
  173. package/packages/openclaw-adapter/src/types.ts +0 -361
  174. package/packages/openclaw-adapter/src/webhook-pusher.test.ts +0 -188
  175. package/packages/openclaw-adapter/src/webhook-pusher.ts +0 -220
  176. package/packages/openclaw-adapter/src/webhook-server.test.ts +0 -580
  177. package/packages/openclaw-adapter/src/webhook-server.ts +0 -202
  178. package/packages/openclaw-adapter/tsconfig.json +0 -20
  179. package/src/cli/commands.test.ts +0 -157
  180. package/src/cli/commands.ts +0 -129
  181. package/src/cli/index.test.ts +0 -77
  182. package/src/cli/index.ts +0 -234
  183. package/src/core/autonomous-economy.test.ts +0 -291
  184. package/src/core/autonomous-economy.ts +0 -428
  185. package/src/core/e2ee-crypto.test.ts +0 -125
  186. package/src/core/e2ee-crypto.ts +0 -246
  187. package/src/core/f2a.test.ts +0 -269
  188. package/src/core/f2a.ts +0 -618
  189. package/src/core/p2p-network.test.ts +0 -199
  190. package/src/core/p2p-network.ts +0 -1432
  191. package/src/core/reputation-security.test.ts +0 -403
  192. package/src/core/reputation-security.ts +0 -562
  193. package/src/core/reputation.test.ts +0 -260
  194. package/src/core/reputation.ts +0 -576
  195. package/src/core/review-committee.test.ts +0 -380
  196. package/src/core/review-committee.ts +0 -401
  197. package/src/core/token-manager.test.ts +0 -133
  198. package/src/core/token-manager.ts +0 -140
  199. package/src/daemon/control-server.test.ts +0 -216
  200. package/src/daemon/control-server.ts +0 -292
  201. package/src/daemon/index.test.ts +0 -85
  202. package/src/daemon/index.ts +0 -89
  203. package/src/daemon/main.ts +0 -44
  204. package/src/daemon/start.ts +0 -29
  205. package/src/daemon/webhook.test.ts +0 -68
  206. package/src/daemon/webhook.ts +0 -105
  207. package/src/index.test.ts +0 -436
  208. package/src/index.ts +0 -72
  209. package/src/types/index.test.ts +0 -87
  210. package/src/types/index.ts +0 -341
  211. package/src/types/result.ts +0 -68
  212. package/src/utils/benchmark.ts +0 -237
  213. package/src/utils/logger.ts +0 -331
  214. package/src/utils/middleware.ts +0 -229
  215. package/src/utils/rate-limiter.ts +0 -207
  216. package/src/utils/signature.ts +0 -136
  217. package/src/utils/validation.ts +0 -186
  218. package/tests/docker/Dockerfile.node +0 -23
  219. package/tests/docker/Dockerfile.runner +0 -18
  220. package/tests/docker/docker-compose.test.yml +0 -73
  221. package/tests/integration/message-passing.test.ts +0 -109
  222. package/tests/integration/multi-node.test.ts +0 -92
  223. package/tests/integration/p2p-connection.test.ts +0 -83
  224. package/tests/integration/test-config.ts +0 -32
  225. package/tsconfig.json +0 -21
  226. package/vitest.config.ts +0 -26
@@ -1,562 +0,0 @@
1
- /**
2
- * F2A 信誉安全机制
3
- * Phase 3: 链式签名、邀请制、挑战机制
4
- */
5
-
6
- import { createHash, createSign, createVerify } from 'crypto';
7
- import { Logger } from '../utils/logger.js';
8
- import { ReputationEntry, ReputationManager } from './reputation.js';
9
-
10
- // ============================================================================
11
- // 类型定义
12
- // ============================================================================
13
-
14
- /**
15
- * 签名信誉事件
16
- */
17
- export interface SignedReputationEvent {
18
- peerId: string;
19
- delta: number;
20
- prevHash: string;
21
- timestamp: number;
22
- signatures: ReviewerSignature[];
23
- }
24
-
25
- /**
26
- * 评审者签名
27
- */
28
- export interface ReviewerSignature {
29
- reviewerId: string;
30
- signature: string;
31
- }
32
-
33
- /**
34
- * 邀请记录
35
- */
36
- export interface InvitationRecord {
37
- inviterId: string;
38
- inviteeId: string;
39
- invitationSignature: string;
40
- timestamp: number;
41
- }
42
-
43
- /**
44
- * 邀请规则配置
45
- */
46
- export interface InvitationConfig {
47
- minInviterReputation: number;
48
- maxInvitations: number;
49
- initialScoreMultiplier: number;
50
- jointLiability: boolean;
51
- jointLiabilityRate: number;
52
- }
53
-
54
- /**
55
- * 挑战记录
56
- */
57
- export interface ChallengeRecord {
58
- challengerId: string;
59
- targetId: string;
60
- reason: 'invalid_history' | 'collusion' | 'fake_signatures' | 'score_manipulation';
61
- evidence: string;
62
- stake: number;
63
- timestamp: number;
64
- status: 'pending' | 'success' | 'failed';
65
- }
66
-
67
- /**
68
- * 挑战结果
69
- */
70
- export interface ChallengeResult {
71
- success: boolean;
72
- reward: number;
73
- reason: string;
74
- }
75
-
76
- // ============================================================================
77
- // 默认配置
78
- // ============================================================================
79
-
80
- const DEFAULT_INVITATION_CONFIG: InvitationConfig = {
81
- minInviterReputation: 60,
82
- maxInvitations: 5,
83
- initialScoreMultiplier: 0.5,
84
- jointLiability: true,
85
- jointLiabilityRate: 0.3,
86
- };
87
-
88
- // ============================================================================
89
- // 链式签名管理器
90
- // ============================================================================
91
-
92
- export class ChainSignatureManager {
93
- private eventChains: Map<string, SignedReputationEvent[]> = new Map();
94
- private logger: Logger;
95
-
96
- constructor() {
97
- this.logger = new Logger({ component: 'ChainSignature' });
98
- }
99
-
100
- /**
101
- * 获取事件链
102
- */
103
- getEventChain(peerId: string): SignedReputationEvent[] {
104
- return this.eventChains.get(peerId) || [];
105
- }
106
-
107
- /**
108
- * 添加签名事件
109
- */
110
- addSignedEvent(event: SignedReputationEvent): boolean {
111
- // 验证 prevHash
112
- const chain = this.getEventChain(event.peerId);
113
-
114
- if (chain.length === 0) {
115
- if (event.prevHash !== 'genesis') {
116
- this.logger.error('Invalid genesis event', { peerId: event.peerId });
117
- return false;
118
- }
119
- } else {
120
- const lastEvent = chain[chain.length - 1];
121
- const expectedPrevHash = this.hashEvent(lastEvent);
122
-
123
- if (event.prevHash !== expectedPrevHash) {
124
- this.logger.error('Chain broken', { peerId: event.peerId });
125
- return false;
126
- }
127
- }
128
-
129
- chain.push(event);
130
- this.eventChains.set(event.peerId, chain);
131
- return true;
132
- }
133
-
134
- /**
135
- * 验证事件链完整性
136
- */
137
- verifyChain(peerId: string): boolean {
138
- const chain = this.getEventChain(peerId);
139
-
140
- if (chain.length === 0) return true;
141
-
142
- let prevHash = 'genesis';
143
-
144
- for (const event of chain) {
145
- // 检查 prevHash
146
- if (event.prevHash !== prevHash) {
147
- this.logger.error('Chain verification failed', {
148
- peerId,
149
- eventIndex: chain.indexOf(event),
150
- });
151
- return false;
152
- }
153
-
154
- prevHash = this.hashEvent(event);
155
- }
156
-
157
- return true;
158
- }
159
-
160
- /**
161
- * 计算事件哈希
162
- */
163
- hashEvent(event: SignedReputationEvent): string {
164
- const data = JSON.stringify({
165
- peerId: event.peerId,
166
- delta: event.delta,
167
- prevHash: event.prevHash,
168
- timestamp: event.timestamp,
169
- });
170
- return createHash('sha256').update(data).digest('hex');
171
- }
172
-
173
- /**
174
- * 创建签名事件
175
- */
176
- createSignedEvent(
177
- peerId: string,
178
- delta: number,
179
- signatures: ReviewerSignature[]
180
- ): SignedReputationEvent {
181
- const chain = this.getEventChain(peerId);
182
- const lastEvent = chain.length > 0 ? chain[chain.length - 1] : null;
183
-
184
- return {
185
- peerId,
186
- delta,
187
- prevHash: lastEvent ? this.hashEvent(lastEvent) : 'genesis',
188
- timestamp: Date.now(),
189
- signatures,
190
- };
191
- }
192
-
193
- /**
194
- * 从事件链计算信誉分
195
- */
196
- calculateScoreFromChain(peerId: string, initialScore: number = 70): number {
197
- const chain = this.getEventChain(peerId);
198
- let score = initialScore;
199
-
200
- for (const event of chain) {
201
- score = Math.max(0, Math.min(100, score + event.delta));
202
- }
203
-
204
- return score;
205
- }
206
-
207
- /**
208
- * 导出事件链
209
- */
210
- exportChain(peerId: string): string {
211
- const chain = this.getEventChain(peerId);
212
- return JSON.stringify(chain);
213
- }
214
-
215
- /**
216
- * 导入事件链
217
- */
218
- importChain(peerId: string, data: string): boolean {
219
- try {
220
- const chain = JSON.parse(data) as SignedReputationEvent[];
221
- this.eventChains.set(peerId, chain);
222
- return this.verifyChain(peerId);
223
- } catch {
224
- return false;
225
- }
226
- }
227
- }
228
-
229
- // ============================================================================
230
- // 邀请管理器
231
- // ============================================================================
232
-
233
- export class InvitationManager {
234
- private config: InvitationConfig;
235
- private reputationManager: ReputationManager;
236
- private invitations: Map<string, InvitationRecord[]> = new Map();
237
- private inviteeToInviter: Map<string, string> = new Map();
238
- private logger: Logger;
239
-
240
- constructor(
241
- reputationManager: ReputationManager,
242
- config: Partial<InvitationConfig> = {}
243
- ) {
244
- this.config = { ...DEFAULT_INVITATION_CONFIG, ...config };
245
- this.reputationManager = reputationManager;
246
- this.logger = new Logger({ component: 'InvitationManager' });
247
- }
248
-
249
- /**
250
- * 创建邀请
251
- */
252
- createInvitation(
253
- inviterId: string,
254
- inviteeId: string
255
- ): { success: boolean; invitation?: InvitationRecord; error?: string } {
256
- // 检查邀请者信誉
257
- const inviterRep = this.reputationManager.getReputation(inviterId);
258
-
259
- if (inviterRep.score < this.config.minInviterReputation) {
260
- return {
261
- success: false,
262
- error: `Inviter reputation ${inviterRep.score} below minimum ${this.config.minInviterReputation}`,
263
- };
264
- }
265
-
266
- // 检查邀请配额
267
- const invitationCount = this.getInvitationCount(inviterId);
268
-
269
- if (invitationCount >= this.config.maxInvitations) {
270
- return {
271
- success: false,
272
- error: `Invitation quota exhausted (${invitationCount}/${this.config.maxInvitations})`,
273
- };
274
- }
275
-
276
- // 检查是否已被邀请
277
- if (this.inviteeToInviter.has(inviteeId)) {
278
- return {
279
- success: false,
280
- error: 'Invitee already invited by another node',
281
- };
282
- }
283
-
284
- // 创建邀请记录
285
- const invitation: InvitationRecord = {
286
- inviterId,
287
- inviteeId,
288
- invitationSignature: this.generateSignature(inviterId, inviteeId),
289
- timestamp: Date.now(),
290
- };
291
-
292
- // 记录邀请
293
- const inviterInvitations = this.invitations.get(inviterId) || [];
294
- inviterInvitations.push(invitation);
295
- this.invitations.set(inviterId, inviterInvitations);
296
- this.inviteeToInviter.set(inviteeId, inviterId);
297
-
298
- // 设置被邀请者的初始信誉
299
- const initialScore = Math.max(
300
- 30,
301
- Math.floor(inviterRep.score * this.config.initialScoreMultiplier)
302
- );
303
- // 使用 ReputationManager 的公开方法设置初始分数
304
- this.reputationManager.setInitialScore(inviteeId, initialScore);
305
-
306
- this.logger.info('Invitation created', {
307
- inviterId: inviterId.slice(0, 16),
308
- inviteeId: inviteeId.slice(0, 16),
309
- initialScore,
310
- });
311
-
312
- return { success: true, invitation };
313
- }
314
-
315
- /**
316
- * 获取邀请者
317
- */
318
- getInviter(inviteeId: string): string | null {
319
- return this.inviteeToInviter.get(inviteeId) || null;
320
- }
321
-
322
- /**
323
- * 获取邀请数量
324
- */
325
- getInvitationCount(inviterId: string): number {
326
- return this.invitations.get(inviterId)?.length || 0;
327
- }
328
-
329
- /**
330
- * 执行连带责任惩罚
331
- */
332
- applyJointLiability(inviteeId: string, penalty: number): void {
333
- if (!this.config.jointLiability) return;
334
-
335
- const inviterId = this.getInviter(inviteeId);
336
- if (!inviterId) return;
337
-
338
- const jointPenalty = Math.floor(penalty * this.config.jointLiabilityRate);
339
-
340
- this.reputationManager.recordFailure(
341
- inviterId,
342
- `joint-liability-${inviteeId}`,
343
- `Joint liability for invitee ${inviteeId}`,
344
- -jointPenalty
345
- );
346
-
347
- this.logger.warn('Joint liability applied', {
348
- inviterId: inviterId.slice(0, 16),
349
- inviteeId: inviteeId.slice(0, 16),
350
- jointPenalty,
351
- });
352
- }
353
-
354
- /**
355
- * 获取所有邀请
356
- */
357
- getAllInvitations(): InvitationRecord[] {
358
- const all: InvitationRecord[] = [];
359
- for (const invitations of this.invitations.values()) {
360
- all.push(...invitations);
361
- }
362
- return all;
363
- }
364
-
365
- /**
366
- * 生成签名
367
- */
368
- private generateSignature(inviterId: string, inviteeId: string): string {
369
- const data = `${inviterId}:${inviteeId}:${Date.now()}`;
370
- return createHash('sha256').update(data).digest('hex');
371
- }
372
- }
373
-
374
- // ============================================================================
375
- // 挑战管理器
376
- // ============================================================================
377
-
378
- export class ChallengeManager {
379
- private reputationManager: ReputationManager;
380
- private chainManager: ChainSignatureManager;
381
- private challenges: Map<string, ChallengeRecord[]> = new Map();
382
- private logger: Logger;
383
-
384
- constructor(
385
- reputationManager: ReputationManager,
386
- chainManager: ChainSignatureManager
387
- ) {
388
- this.reputationManager = reputationManager;
389
- this.chainManager = chainManager;
390
- this.logger = new Logger({ component: 'ChallengeManager' });
391
- }
392
-
393
- /**
394
- * 提交挑战
395
- */
396
- submitChallenge(
397
- challengerId: string,
398
- targetId: string,
399
- reason: ChallengeRecord['reason'],
400
- evidence: string,
401
- stake: number = 10
402
- ): ChallengeRecord {
403
- const challenge: ChallengeRecord = {
404
- challengerId,
405
- targetId,
406
- reason,
407
- evidence,
408
- stake,
409
- timestamp: Date.now(),
410
- status: 'pending',
411
- };
412
-
413
- const targetChallenges = this.challenges.get(targetId) || [];
414
- targetChallenges.push(challenge);
415
- this.challenges.set(targetId, targetChallenges);
416
-
417
- this.logger.info('Challenge submitted', {
418
- challengerId: challengerId.slice(0, 16),
419
- targetId: targetId.slice(0, 16),
420
- reason,
421
- });
422
-
423
- return challenge;
424
- }
425
-
426
- /**
427
- * 处理挑战
428
- */
429
- processChallenge(challenge: ChallengeRecord): ChallengeResult {
430
- const targetId = challenge.targetId;
431
-
432
- // 1. 验证事件链
433
- if (challenge.reason === 'invalid_history' || challenge.reason === 'fake_signatures') {
434
- const chainValid = this.chainManager.verifyChain(targetId);
435
-
436
- if (!chainValid) {
437
- // 挑战成功
438
- this.reputationManager.recordFailure(
439
- targetId,
440
- 'challenge-invalid-chain',
441
- 'Invalid reputation chain detected',
442
- -50
443
- );
444
-
445
- // 奖励挑战者
446
- this.reputationManager.recordReviewReward(
447
- challenge.challengerId,
448
- challenge.stake * 2
449
- );
450
-
451
- challenge.status = 'success';
452
- return { success: true, reward: challenge.stake * 2, reason: 'Invalid chain detected' };
453
- }
454
- }
455
-
456
- // 2. 检测合谋
457
- if (challenge.reason === 'collusion') {
458
- const collusionScore = this.detectCollusion(targetId);
459
-
460
- if (collusionScore > 0.8) {
461
- // 合谋检测成功
462
- this.reputationManager.recordFailure(
463
- targetId,
464
- 'challenge-collusion',
465
- 'Collusion detected',
466
- -30
467
- );
468
-
469
- this.reputationManager.recordReviewReward(
470
- challenge.challengerId,
471
- challenge.stake * 1.5
472
- );
473
-
474
- challenge.status = 'success';
475
- return { success: true, reward: challenge.stake * 1.5, reason: 'Collusion detected' };
476
- }
477
- }
478
-
479
- // 3. 分数操纵检测
480
- if (challenge.reason === 'score_manipulation') {
481
- const chain = this.chainManager.getEventChain(targetId);
482
- const calculatedScore = this.chainManager.calculateScoreFromChain(targetId);
483
- const claimedScore = this.reputationManager.getReputation(targetId).score;
484
-
485
- if (Math.abs(calculatedScore - claimedScore) > 10) {
486
- // 分数不一致
487
- this.reputationManager.recordFailure(
488
- targetId,
489
- 'challenge-score-manipulation',
490
- 'Score manipulation detected',
491
- -20
492
- );
493
-
494
- this.reputationManager.recordReviewReward(
495
- challenge.challengerId,
496
- challenge.stake * 1.5
497
- );
498
-
499
- challenge.status = 'success';
500
- return { success: true, reward: challenge.stake * 1.5, reason: 'Score manipulation detected' };
501
- }
502
- }
503
-
504
- // 挑战失败
505
- this.reputationManager.recordReviewPenalty(
506
- challenge.challengerId,
507
- -challenge.stake * 0.5,
508
- 'Failed challenge'
509
- );
510
-
511
- challenge.status = 'failed';
512
- return { success: false, reward: 0, reason: 'Challenge failed' };
513
- }
514
-
515
- /**
516
- * 合谋检测算法
517
- */
518
- detectCollusion(nodeId: string): number {
519
- const entry = this.reputationManager.getReputation(nodeId);
520
-
521
- // 分析评审历史
522
- const successEvents = entry.history.filter(e => e.type === 'task_success');
523
-
524
- if (successEvents.length < 5) return 0;
525
-
526
- // 简单检测:如果所有成功事件都是同一任务类型,可疑度低
527
- // 如果成功事件分数波动极大,可疑度高
528
- const deltas = successEvents.map(e => e.delta);
529
- const avgDelta = deltas.reduce((a, b) => a + b, 0) / deltas.length;
530
- const variance = deltas.reduce((sum, d) => sum + Math.pow(d - avgDelta, 2), 0) / deltas.length;
531
-
532
- // 方差越大,可疑度越高
533
- const normalizedVariance = Math.min(1, variance / 100);
534
-
535
- return normalizedVariance;
536
- }
537
-
538
- /**
539
- * 获取挑战历史
540
- */
541
- getChallenges(targetId: string): ChallengeRecord[] {
542
- return this.challenges.get(targetId) || [];
543
- }
544
-
545
- /**
546
- * 获取待处理挑战
547
- */
548
- getPendingChallenges(): ChallengeRecord[] {
549
- const all: ChallengeRecord[] = [];
550
- for (const challenges of this.challenges.values()) {
551
- all.push(...challenges.filter(c => c.status === 'pending'));
552
- }
553
- return all;
554
- }
555
- }
556
-
557
- // 默认导出
558
- export default {
559
- ChainSignatureManager,
560
- InvitationManager,
561
- ChallengeManager,
562
- };