Skip to content
This repository was archived by the owner on May 11, 2026. It is now read-only.

Commit 03c0842

Browse files
wa0x6eclaude
andcommitted
fix: reject alias creation when alias pair already exists
Adds a duplicate check in the alias writer's verify() step to return a clear error instead of relying on the DB primary key constraint. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent d412b03 commit 03c0842

3 files changed

Lines changed: 48 additions & 13 deletions

File tree

src/writer/alias.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,18 @@ export async function verify(message): Promise<any> {
1010
log.warn(`[writer] Wrong alias format ${JSON.stringify(schemaIsValid)}`);
1111
return Promise.reject('wrong alias format');
1212
}
13-
if (message.from === msg.payload.alias) {
13+
if (message.address === msg.payload.alias) {
1414
return Promise.reject('alias cannot be the same as the address');
1515
}
16+
17+
const existing = await db.queryAsync(
18+
'SELECT 1 FROM aliases WHERE address = ? AND alias = ? LIMIT 1',
19+
[message.address, msg.payload.alias]
20+
);
21+
if (existing.length > 0) {
22+
return Promise.reject('alias already exists');
23+
}
24+
1625
return true;
1726
}
1827

test/integration/helpers/alias.test.ts

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,58 @@
11
import { isExistingAlias } from '../../../src/helpers/alias';
22
import db, { sequencerDB } from '../../../src/helpers/mysql';
3+
import { verify } from '../../../src/writer/alias';
34
import { aliasesSqlFixtures } from '../../fixtures/alias';
45

56
describe('alias', () => {
67
const seed = Date.now().toFixed(0);
78

8-
beforeAll(async () => {
9-
await db.queryAsync('DELETE from snapshot_sequencer_test.aliases');
9+
beforeEach(async () => {
10+
await db.queryAsync('DELETE from snapshot_sequencer_test.aliases WHERE ipfs = ?', seed);
1011
await Promise.all(
1112
aliasesSqlFixtures.map(alias => {
12-
const values = {
13-
...alias,
14-
ipfs: seed
15-
};
16-
return db.queryAsync('INSERT INTO snapshot_sequencer_test.aliases SET ?', values);
13+
const values = { ...alias, ipfs: seed };
14+
return db.queryAsync(
15+
'INSERT INTO snapshot_sequencer_test.aliases SET ? ON DUPLICATE KEY UPDATE ipfs = VALUES(ipfs), created = VALUES(created)',
16+
values
17+
);
1718
})
1819
);
1920
});
2021

21-
afterEach(async () => {
22-
await db.queryAsync('DELETE from snapshot_sequencer_test.aliases where ipfs = ?', seed);
23-
});
24-
2522
afterAll(async () => {
23+
await db.queryAsync('DELETE from snapshot_sequencer_test.aliases WHERE ipfs = ?', seed);
2624
await db.endAsync();
2725
await sequencerDB.endAsync();
2826
});
2927

28+
describe('verify()', () => {
29+
it('should reject when alias already exists', async () => {
30+
const { address, alias } = aliasesSqlFixtures[0];
31+
const msg = {
32+
version: '0.1.4',
33+
timestamp: Math.floor(Date.now() / 1000),
34+
type: 'alias',
35+
payload: { alias }
36+
};
37+
38+
await expect(verify({ address, msg: JSON.stringify(msg) })).rejects.toMatch(
39+
'alias already exists'
40+
);
41+
});
42+
43+
it('should pass when alias does not exist', async () => {
44+
const address = '0x0000000000000000000000000000000000000001';
45+
const msg = {
46+
version: '0.1.4',
47+
timestamp: Math.floor(Date.now() / 1000),
48+
type: 'alias',
49+
payload: { alias: '0x0000000000000000000000000000000000000002' }
50+
};
51+
52+
await expect(verify({ address, msg: JSON.stringify(msg) })).resolves.toBeTruthy();
53+
});
54+
});
55+
3056
describe('isExistingAlias()', () => {
3157
it('should return true for valid alias', () => {
3258
expect(

test/unit/writer/alias.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as writer from '../../../src/writer/alias';
22
import input from '../../fixtures/writer-payload/alias.json';
33
import omit from 'lodash/omit';
44

5-
describe('writer/profile', () => {
5+
describe('writer/alias', () => {
66
describe('verify()', () => {
77
const msg = JSON.parse(input.msg);
88
const invalidMsg = [

0 commit comments

Comments
 (0)