123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504 |
- /**
- * Pacifica签名器契约测试
- *
- * 验证IPacificaSigner接口的契约实现
- * 测试Ed25519签名、批量操作、消息序列化等Pacifica特定功能
- */
- import { describe, test, expect, beforeEach, afterEach } from '@jest/globals';
- import {
- PacificaSigner,
- PacificaSignRequest,
- PacificaSignResponse,
- PacificaVerifyRequest,
- PacificaOrderType,
- PacificaOrderMessage,
- PacificaCancelMessage,
- PACIFICA_CONSTANTS,
- Platform,
- SignResult
- } from '../../src/index';
- describe('IPacificaSigner Contract Tests', () => {
- let signer: PacificaSigner;
- const testAccountId = 'pacifica-signer-test-001';
- beforeEach(async () => {
- // 创建PacificaSigner实例并添加测试账户
- const { PacificaSigner } = await import('../../src/platforms/pacifica/PacificaSigner');
- signer = new PacificaSigner();
- // 添加测试账户私钥(64字符十六进制)
- const testPrivateKey = '1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef';
- signer.addAccount(testAccountId, testPrivateKey);
- });
- afterEach(async () => {
- // 清理资源
- });
- describe('平台接口验证', () => {
- test('应该正确标识Pacifica平台', () => {
- expect(signer.platform).toBe(Platform.PACIFICA);
- });
- });
- describe('Ed25519签名功能', () => {
- test('应该能对Pacifica订单进行签名', async () => {
- const orderMessage: PacificaOrderMessage = {
- order_type: PacificaOrderType.LIMIT,
- symbol: 'BTC-USD',
- side: 'buy',
- size: '0.001',
- price: '65000.00',
- client_id: 'test-order-001',
- timestamp: Date.now(),
- expiry: Date.now() + 300000
- };
- const messageBytes = new TextEncoder().encode(JSON.stringify(orderMessage));
- const request: PacificaSignRequest = {
- accountId: testAccountId,
- message: messageBytes,
- orderType: PacificaOrderType.LIMIT,
- options: {
- timeout: 30000,
- includeTimestamp: true,
- encoding: 'base64'
- }
- };
- const response = await signer.signOrder(request);
- expect(response.success).toBe(true);
- expect(response.signature).toBeDefined();
- expect(response.signature.length).toBe(PACIFICA_CONSTANTS.SIGNATURE_BASE64_LENGTH);
- expect(response.algorithm).toBe('ed25519');
- expect(response.publicKey).toBeDefined();
- expect(response.publicKey.length).toBe(PACIFICA_CONSTANTS.PUBLIC_KEY_BASE58_LENGTH);
- expect(response.orderType).toBe(PacificaOrderType.LIMIT);
- expect(response.timestamp).toBeInstanceOf(Date);
- expect(response.executionTime).toBeLessThan(50); // NFR-002: <50ms
- });
- test('应该能对市价单进行签名', async () => {
- const orderMessage: PacificaOrderMessage = {
- order_type: PacificaOrderType.MARKET,
- symbol: 'ETH-USD',
- side: 'sell',
- size: '0.1',
- client_id: 'market-order-001',
- timestamp: Date.now()
- };
- const messageBytes = new TextEncoder().encode(JSON.stringify(orderMessage));
- const request: PacificaSignRequest = {
- accountId: testAccountId,
- message: messageBytes,
- orderType: PacificaOrderType.MARKET
- };
- const response = await signer.signOrder(request);
- expect(response.success).toBe(true);
- expect(response.algorithm).toBe('ed25519');
- expect(response.orderType).toBe(PacificaOrderType.MARKET);
- });
- test('应该能对取消订单进行签名', async () => {
- const cancelMessage: PacificaCancelMessage = {
- action: 'cancel',
- order_type: 'cancel',
- order_id: 'order-to-cancel-123',
- timestamp: Date.now()
- };
- const messageBytes = new TextEncoder().encode(JSON.stringify(cancelMessage));
- const request: PacificaSignRequest = {
- accountId: testAccountId,
- message: messageBytes,
- orderType: PacificaOrderType.CANCEL
- };
- const response = await signer.signOrder(request);
- expect(response.success).toBe(true);
- expect(response.orderType).toBe(PacificaOrderType.CANCEL);
- });
- });
- describe('签名验证功能', () => {
- test('应该能验证有效的Ed25519签名', async () => {
- // 首先创建一个签名
- const orderMessage: PacificaOrderMessage = {
- order_type: PacificaOrderType.LIMIT,
- symbol: 'BTC-USD',
- side: 'buy',
- size: '0.001',
- price: '65000.00',
- client_id: 'verify-test-001',
- timestamp: Date.now()
- };
- const messageBytes = new TextEncoder().encode(JSON.stringify(orderMessage));
- const signResponse = await signer.signOrder({
- accountId: testAccountId,
- message: messageBytes,
- orderType: PacificaOrderType.LIMIT
- });
- expect(signResponse.success).toBe(true);
- // 然后验证签名
- const verifyRequest: PacificaVerifyRequest = {
- accountId: testAccountId,
- message: messageBytes,
- signature: signResponse.signature,
- publicKey: signResponse.publicKey,
- orderType: PacificaOrderType.LIMIT
- };
- const verifyResponse = await signer.verifySignature(verifyRequest);
- expect(verifyResponse.success).toBe(true);
- expect(verifyResponse.isValid).toBe(true);
- expect(verifyResponse.algorithm).toBe('ed25519');
- expect(verifyResponse.publicKey).toBe(signResponse.publicKey);
- expect(verifyResponse.timestamp).toBeInstanceOf(Date);
- expect(verifyResponse.verificationId).toBeDefined();
- });
- test('应该拒绝被篡改的消息签名', async () => {
- // 创建原始签名
- const originalMessage = new TextEncoder().encode('original message');
- const signResponse = await signer.signOrder({
- accountId: testAccountId,
- message: originalMessage,
- orderType: PacificaOrderType.MARKET
- });
- // 尝试验证不同的消息(篡改)
- const tamperedMessage = new TextEncoder().encode('tampered message');
- const verifyRequest: PacificaVerifyRequest = {
- accountId: testAccountId,
- message: tamperedMessage,
- signature: signResponse.signature,
- publicKey: signResponse.publicKey
- };
- const verifyResponse = await signer.verifySignature(verifyRequest);
- expect(verifyResponse.success).toBe(true); // 验证操作成功
- expect(verifyResponse.isValid).toBe(false); // 但签名无效
- });
- test('应该拒绝无效格式的签名', async () => {
- const message = new TextEncoder().encode('test message');
- const verifyRequest: PacificaVerifyRequest = {
- accountId: testAccountId,
- message: message,
- signature: 'invalid-signature-format',
- publicKey: 'valid-looking-public-key-base58'
- };
- const verifyResponse = await signer.verifySignature(verifyRequest);
- expect(verifyResponse.success).toBe(false);
- expect(verifyResponse.error).toBeDefined();
- expect(verifyResponse.error).toContain('INVALID');
- });
- });
- describe('公钥管理', () => {
- test('应该能获取账户公钥', async () => {
- const publicKey = await signer.getPublicKey(testAccountId);
- expect(publicKey).toBeDefined();
- expect(typeof publicKey).toBe('string');
- expect(publicKey.length).toBe(PACIFICA_CONSTANTS.PUBLIC_KEY_BASE58_LENGTH);
- // 验证Base58格式(基本检查)
- expect(/^[1-9A-HJ-NP-Za-km-z]+$/.test(publicKey)).toBe(true);
- });
- test('应该为不存在的账户返回错误', async () => {
- await expect(signer.getPublicKey('non-existent-account'))
- .rejects.toThrow('ACCOUNT_NOT_FOUND');
- });
- });
- describe('批量签名功能', () => {
- test('应该能执行批量签名操作', async () => {
- const orders: PacificaOrderMessage[] = [
- {
- order_type: PacificaOrderType.LIMIT,
- symbol: 'BTC-USD',
- side: 'buy',
- size: '0.001',
- price: '65000.00',
- client_id: 'batch-order-1',
- timestamp: Date.now()
- },
- {
- order_type: PacificaOrderType.MARKET,
- symbol: 'ETH-USD',
- side: 'sell',
- size: '0.1',
- client_id: 'batch-order-2',
- timestamp: Date.now()
- },
- {
- action: 'cancel',
- order_type: PacificaOrderType.CANCEL,
- order_id: 'order-to-cancel',
- timestamp: Date.now(),
- side: 'buy', // Add required fields for compatibility
- size: '0'
- } as any
- ];
- const requests: PacificaSignRequest[] = orders.map((order, index) => ({
- accountId: testAccountId,
- message: new TextEncoder().encode(JSON.stringify(order)),
- orderType: order.order_type as PacificaOrderType
- }));
- const startTime = Date.now();
- const responses = await signer.signBatch(requests);
- const totalTime = Date.now() - startTime;
- expect(responses).toHaveLength(requests.length);
- expect(totalTime).toBeLessThan(300); // 批量操作应该在300ms内完成
- responses.forEach((response, index) => {
- expect(response.success).toBe(true);
- expect(response.signature).toBeDefined();
- expect(response.algorithm).toBe('ed25519');
- expect(response.orderType).toBe(orders[index]?.order_type);
- expect(response.executionTime).toBeLessThan(50);
- });
- // 验证所有签名都是唯一的
- const signatures = responses.map(r => r.signature);
- const uniqueSignatures = new Set(signatures);
- expect(uniqueSignatures.size).toBe(signatures.length);
- });
- test('应该拒绝超过最大批量大小的请求', async () => {
- const requests: PacificaSignRequest[] = Array.from(
- { length: PACIFICA_CONSTANTS.MAX_BATCH_SIZE + 1 },
- (_, index) => ({
- accountId: testAccountId,
- message: new TextEncoder().encode(`batch message ${index}`),
- orderType: PacificaOrderType.MARKET
- })
- );
- await expect(signer.signBatch(requests))
- .rejects.toThrow('BATCH_SIZE_EXCEEDED');
- });
- test('应该处理批量请求中的部分失败', async () => {
- const requests: PacificaSignRequest[] = [
- {
- accountId: testAccountId,
- message: new TextEncoder().encode('valid message 1'),
- orderType: PacificaOrderType.LIMIT
- },
- {
- accountId: 'invalid-account',
- message: new TextEncoder().encode('valid message 2'),
- orderType: PacificaOrderType.MARKET
- },
- {
- accountId: testAccountId,
- message: new TextEncoder().encode('valid message 3'),
- orderType: PacificaOrderType.CANCEL
- }
- ];
- const responses = await signer.signBatch(requests);
- expect(responses).toHaveLength(3);
- expect(responses[0]?.success).toBe(true);
- expect(responses[1]?.success).toBe(false);
- expect(responses[1]?.error).toContain('ACCOUNT_NOT_FOUND');
- expect(responses[2]?.success).toBe(true);
- });
- });
- describe('签名选项和编码', () => {
- test('应该支持不同的签名编码格式', async () => {
- const message = new TextEncoder().encode('encoding test message');
- const encodings: Array<'base64' | 'base58' | 'hex'> = ['base64', 'base58', 'hex'];
- for (const encoding of encodings) {
- const request: PacificaSignRequest = {
- accountId: testAccountId,
- message: message,
- orderType: PacificaOrderType.MARKET,
- options: { encoding }
- };
- const response = await signer.signOrder(request);
- expect(response.success).toBe(true);
- expect(response.signature).toBeDefined();
- // 验证编码格式
- switch (encoding) {
- case 'base64':
- expect(/^[A-Za-z0-9+/]+=*$/.test(response.signature)).toBe(true);
- break;
- case 'base58':
- expect(/^[1-9A-HJ-NP-Za-km-z]+$/.test(response.signature)).toBe(true);
- break;
- case 'hex':
- expect(/^[0-9a-fA-F]+$/.test(response.signature)).toBe(true);
- break;
- }
- }
- });
- test('应该支持时间戳包含选项', async () => {
- const message = new TextEncoder().encode('timestamp test message');
- // 包含时间戳
- const withTimestamp = await signer.signOrder({
- accountId: testAccountId,
- message: message,
- orderType: PacificaOrderType.LIMIT,
- options: { includeTimestamp: true }
- });
- // 不包含时间戳
- const withoutTimestamp = await signer.signOrder({
- accountId: testAccountId,
- message: message,
- orderType: PacificaOrderType.LIMIT,
- options: { includeTimestamp: false }
- });
- expect(withTimestamp.success).toBe(true);
- expect(withoutTimestamp.success).toBe(true);
- // 签名应该不同(因为时间戳的存在)
- expect(withTimestamp.signature).not.toBe(withoutTimestamp.signature);
- });
- test('应该遵守签名超时设置', async () => {
- const message = new TextEncoder().encode('timeout test message');
- // 极短超时应该失败
- const shortTimeoutRequest: PacificaSignRequest = {
- accountId: testAccountId,
- message: message,
- orderType: PacificaOrderType.MARKET,
- options: { timeout: 1 } // 1ms
- };
- const response = await signer.signOrder(shortTimeoutRequest);
- expect(response.success).toBe(false);
- expect(response.error).toContain('TIMEOUT');
- });
- });
- describe('消息大小限制', () => {
- test('应该拒绝过大的消息', async () => {
- // 创建超过最大大小的消息
- const largeMessage = new Uint8Array(PACIFICA_CONSTANTS.MAX_MESSAGE_SIZE + 1);
- largeMessage.fill(65); // 填充'A'字符
- const request: PacificaSignRequest = {
- accountId: testAccountId,
- message: largeMessage,
- orderType: PacificaOrderType.MARKET
- };
- const response = await signer.signOrder(request);
- expect(response.success).toBe(false);
- expect(response.error).toContain('MESSAGE_TOO_LARGE');
- });
- test('应该接受最大大小以内的消息', async () => {
- // 创建恰好最大大小的消息
- const maxSizeMessage = new Uint8Array(PACIFICA_CONSTANTS.MAX_MESSAGE_SIZE);
- maxSizeMessage.fill(65);
- const request: PacificaSignRequest = {
- accountId: testAccountId,
- message: maxSizeMessage,
- orderType: PacificaOrderType.MARKET
- };
- const response = await signer.signOrder(request);
- expect(response.success).toBe(true);
- expect(response.signature).toBeDefined();
- });
- });
- describe('错误处理和边界条件', () => {
- test('应该处理空消息', async () => {
- const emptyMessage = new Uint8Array(0);
- const request: PacificaSignRequest = {
- accountId: testAccountId,
- message: emptyMessage,
- orderType: PacificaOrderType.MARKET
- };
- const response = await signer.signOrder(request);
- expect(response.success).toBe(false);
- expect(response.error).toContain('INVALID_MESSAGE');
- });
- test('应该处理无效的订单类型', async () => {
- const message = new TextEncoder().encode('test message');
- const request: PacificaSignRequest = {
- accountId: testAccountId,
- message: message,
- orderType: 'invalid_order_type' as any
- };
- const response = await signer.signOrder(request);
- expect(response.success).toBe(false);
- expect(response.error).toContain('INVALID_ORDER_TYPE');
- });
- test('应该在并发场景下保持稳定', async () => {
- const message = new TextEncoder().encode('concurrent test message');
- const concurrentRequests = 20;
- const promises = Array.from({ length: concurrentRequests }, (_, index) =>
- signer.signOrder({
- accountId: testAccountId,
- message: message,
- orderType: PacificaOrderType.MARKET
- })
- );
- const results = await Promise.all(promises);
- results.forEach((result, index) => {
- expect(result.success).toBe(true);
- expect(result.signature).toBeDefined();
- expect(result.executionTime).toBeLessThan(50);
- });
- // 验证所有签名都是唯一的
- const signatures = results.map(r => r.signature);
- const uniqueSignatures = new Set(signatures);
- expect(uniqueSignatures.size).toBe(signatures.length);
- });
- });
- });
|