t029_simple_bridge_test.ts 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /**
  2. * T029 简化测试:账户管理器桥接服务
  3. * 测试桥接器的核心功能,不依赖完整的系统编译
  4. */
  5. import { logger } from '../src/utils/logger.js'
  6. // 模拟现有的 AccountManager
  7. class MockAccountManager {
  8. private accounts: any[] = []
  9. private accountStates = new Map<string, any>()
  10. setAccounts(accounts: any[]) {
  11. this.accounts = accounts
  12. this.initializeAccountStates()
  13. }
  14. getAccounts(): any[] {
  15. return this.accounts
  16. }
  17. getAccountState(accountId: string): any {
  18. return this.accountStates.get(accountId)
  19. }
  20. getAllAccountStates(): Map<string, any> {
  21. return this.accountStates
  22. }
  23. private initializeAccountStates(): void {
  24. this.accounts.forEach((account, index) => {
  25. const accountId = `pacifica-${index + 1}`
  26. this.accountStates.set(accountId, {
  27. totalTrades: 0,
  28. netPosition: 0,
  29. totalVolume: 0,
  30. lastBalance: 1000 + Math.random() * 5000,
  31. availableBalance: 800 + Math.random() * 3000,
  32. marginUsed: 200 + Math.random() * 1000,
  33. needsRebalance: false,
  34. })
  35. })
  36. }
  37. }
  38. // 模拟新的数据模型管理器
  39. class MockExchangeAccountManager {
  40. private accounts = new Map<string, any>()
  41. addAccount(account: any): void {
  42. this.accounts.set(account.accountId, account)
  43. }
  44. getAllAccounts(): any[] {
  45. return Array.from(this.accounts.values())
  46. }
  47. }
  48. class MockRiskEnvelopeManager {
  49. private envelopes = new Map<string, any>()
  50. addEnvelope(envelope: any): void {
  51. this.envelopes.set(envelope.envelopeId, envelope)
  52. }
  53. getAllEnvelopes(): any[] {
  54. return Array.from(this.envelopes.values())
  55. }
  56. }
  57. class MockMonitoringEventManager {
  58. private events: any[] = []
  59. addEvent(event: any): void {
  60. this.events.push(event)
  61. }
  62. getAllEvents(): any[] {
  63. return this.events
  64. }
  65. }
  66. // 模拟 AccountSyncService
  67. class MockAccountSyncService {
  68. async syncAccounts(request: any): Promise<any> {
  69. logger.info(`模拟账户同步: ${request.accounts.length} 个账户`)
  70. // 模拟同步结果
  71. const results = request.accounts.map((account: any) => ({
  72. accountId: account.accountId,
  73. exchange: account.exchange,
  74. balances: [
  75. {
  76. asset: 'USDC',
  77. total: '1000.0',
  78. available: '800.0',
  79. locked: '200.0'
  80. }
  81. ],
  82. positions: [],
  83. utilization: {
  84. current: 0.2,
  85. targetMin: 0.5,
  86. targetMax: 0.8,
  87. needsRebalance: true
  88. },
  89. syncedAt: new Date()
  90. }))
  91. return {
  92. requestId: request.requestId,
  93. results,
  94. errors: []
  95. }
  96. }
  97. }
  98. // 简化的桥接器实现
  99. class SimpleAccountManagerBridge {
  100. private isRunning = false
  101. private syncStats = {
  102. totalSyncs: 0,
  103. successfulSyncs: 0,
  104. failedSyncs: 0,
  105. lastError: null as string | null
  106. }
  107. constructor(
  108. private legacyAccountManager: MockAccountManager,
  109. private accountSyncService: MockAccountSyncService,
  110. private exchangeAccountManager: MockExchangeAccountManager,
  111. private monitoringManager: MockMonitoringEventManager,
  112. private riskManager: MockRiskEnvelopeManager
  113. ) {}
  114. async start(): Promise<void> {
  115. logger.info('启动简化账户管理器桥接器')
  116. await this.initializeExchangeAccounts()
  117. this.isRunning = true
  118. }
  119. async stop(): Promise<void> {
  120. logger.info('停止简化账户管理器桥接器')
  121. this.isRunning = false
  122. }
  123. private async initializeExchangeAccounts(): Promise<void> {
  124. logger.info('初始化 ExchangeAccount 数据')
  125. const legacyAccounts = this.legacyAccountManager.getAccounts()
  126. const accountStates = this.legacyAccountManager.getAllAccountStates()
  127. for (let i = 0; i < legacyAccounts.length; i++) {
  128. const legacyAccount = legacyAccounts[i]
  129. const accountId = `pacifica-${i + 1}`
  130. const accountState = accountStates.get(accountId)
  131. if (!accountState) {
  132. logger.warn(`找不到账户状态: ${accountId}`)
  133. continue
  134. }
  135. // 创建新的 ExchangeAccount
  136. const exchangeAccount = {
  137. accountId,
  138. exchange: 'pacifica',
  139. accountName: legacyAccount.name || `Pacifica Account ${i + 1}`,
  140. publicKey: legacyAccount.account,
  141. proxyProfile: 'default',
  142. utilizationTargetMin: 0.5,
  143. utilizationTargetMax: 0.8,
  144. deltaThreshold: 0.0005,
  145. maxPositionValue: 10000,
  146. stopLossConfigId: 'default',
  147. status: 'active',
  148. createdAt: new Date(),
  149. updatedAt: new Date()
  150. }
  151. this.exchangeAccountManager.addAccount(exchangeAccount)
  152. await this.createRiskEnvelope(accountId, exchangeAccount)
  153. logger.info(`初始化账户: ${accountId} (${exchangeAccount.accountName})`)
  154. }
  155. logger.info(`初始化完成,共处理 ${legacyAccounts.length} 个账户`)
  156. }
  157. private async createRiskEnvelope(accountId: string, exchangeAccount: any): Promise<void> {
  158. const riskEnvelope = {
  159. envelopeId: `envelope-${accountId}`,
  160. accountId,
  161. maxDrawdownPercent: 5.0,
  162. maxLeverage: 1.0,
  163. deltaThreshold: exchangeAccount.deltaThreshold,
  164. slippageTolerance: 0.001,
  165. emergencyStopLossSeconds: 30,
  166. createdAt: new Date(),
  167. updatedAt: new Date()
  168. }
  169. this.riskManager.addEnvelope(riskEnvelope)
  170. logger.debug(`创建风险包络: ${accountId}`)
  171. }
  172. async triggerManualSync(): Promise<any> {
  173. logger.info('执行手动账户同步')
  174. this.syncStats.totalSyncs++
  175. try {
  176. const legacyAccounts = this.legacyAccountManager.getAccounts()
  177. const syncRequest = {
  178. requestId: `sync-${Date.now()}`,
  179. accounts: legacyAccounts.map((_, index) => ({
  180. accountId: `pacifica-${index + 1}`,
  181. exchange: 'pacifica',
  182. nonce: Date.now()
  183. }))
  184. }
  185. const syncResponse = await this.accountSyncService.syncAccounts(syncRequest)
  186. if (syncResponse.errors.length === 0) {
  187. this.syncStats.successfulSyncs++
  188. this.syncStats.lastError = null
  189. } else {
  190. this.syncStats.failedSyncs++
  191. this.syncStats.lastError = syncResponse.errors[0]?.message || 'Unknown error'
  192. }
  193. logger.info(`账户同步完成: ${syncResponse.results.length} 成功, ${syncResponse.errors.length} 失败`)
  194. return {
  195. success: true,
  196. message: '手动同步完成',
  197. syncStats: { ...this.syncStats }
  198. }
  199. } catch (error: any) {
  200. this.syncStats.failedSyncs++
  201. this.syncStats.lastError = error.message
  202. return {
  203. success: false,
  204. message: `手动同步失败: ${error.message}`,
  205. syncStats: { ...this.syncStats }
  206. }
  207. }
  208. }
  209. getBridgeStats(): any {
  210. return {
  211. legacyAccounts: this.legacyAccountManager.getAccounts().length,
  212. exchangeAccounts: this.exchangeAccountManager.getAllAccounts().length,
  213. riskEnvelopes: this.riskManager.getAllEnvelopes().length,
  214. syncStats: { ...this.syncStats },
  215. isRunning: this.isRunning
  216. }
  217. }
  218. }
  219. async function main() {
  220. logger.info('=== T029 简化桥接器测试 ===')
  221. try {
  222. // 1. 创建模拟组件
  223. const mockAccountManager = new MockAccountManager()
  224. const mockExchangeAccountManager = new MockExchangeAccountManager()
  225. const mockRiskManager = new MockRiskEnvelopeManager()
  226. const mockMonitoringManager = new MockMonitoringEventManager()
  227. const mockAccountSyncService = new MockAccountSyncService()
  228. // 2. 模拟账户配置
  229. const mockAccounts = [
  230. {
  231. id: '1',
  232. name: 'Pacifica Account 1',
  233. account: '0x1234567890abcdef1234567890abcdef12345678',
  234. privateKey: 'mock_private_key_1'
  235. },
  236. {
  237. id: '2',
  238. name: 'Pacifica Account 2',
  239. account: '0xabcdef1234567890abcdef1234567890abcdef12',
  240. privateKey: 'mock_private_key_2'
  241. }
  242. ]
  243. // 3. 设置账户
  244. mockAccountManager.setAccounts(mockAccounts)
  245. // 4. 创建桥接器
  246. const bridge = new SimpleAccountManagerBridge(
  247. mockAccountManager,
  248. mockAccountSyncService,
  249. mockExchangeAccountManager,
  250. mockMonitoringManager,
  251. mockRiskManager
  252. )
  253. // 5. 启动桥接器
  254. logger.info('启动桥接器...')
  255. await bridge.start()
  256. // 6. 检查初始状态
  257. const initialStats = bridge.getBridgeStats()
  258. logger.info('初始桥接统计:', initialStats)
  259. // 7. 执行手动同步
  260. logger.info('执行手动同步...')
  261. const syncResult = await bridge.triggerManualSync()
  262. logger.info('同步结果:', syncResult)
  263. // 8. 检查同步后状态
  264. const finalStats = bridge.getBridgeStats()
  265. logger.info('最终桥接统计:', finalStats)
  266. // 9. 验证数据一致性
  267. logger.info('验证数据一致性...')
  268. const legacyAccounts = mockAccountManager.getAccounts()
  269. const exchangeAccounts = mockExchangeAccountManager.getAllAccounts()
  270. const riskEnvelopes = mockRiskManager.getAllEnvelopes()
  271. logger.info(`验证结果:`)
  272. logger.info(`- 现有账户: ${legacyAccounts.length}`)
  273. logger.info(`- 新架构账户: ${exchangeAccounts.length}`)
  274. logger.info(`- 风险包络: ${riskEnvelopes.length}`)
  275. logger.info(`- 数据一致性: ${legacyAccounts.length === exchangeAccounts.length ? '✅' : '❌'}`)
  276. // 10. 停止桥接器
  277. await bridge.stop()
  278. logger.info('=== T029 简化桥接器测试完成 ===')
  279. } catch (error: any) {
  280. logger.error('T029 测试失败:', { error: error.message, stack: error.stack })
  281. process.exit(1)
  282. }
  283. }
  284. // 运行测试
  285. if (import.meta.url === `file://${process.argv[1]}`) {
  286. main().catch(error => {
  287. logger.error('测试运行失败:', error)
  288. process.exit(1)
  289. })
  290. }