Skip to content

Commit 94b8447

Browse files
committed
Refactor competitions entity
1 parent 4b96500 commit 94b8447

File tree

7 files changed

+109
-101
lines changed

7 files changed

+109
-101
lines changed

src/app.controller.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,6 @@ export class AppController {
5858
return this.appService.getTokenBalances(dto)
5959
}
6060

61-
@Get('/winners')
62-
getWinners(@Query() dto: GetTokenWinnersDto) {
63-
return this.appService.getTokenWinners(dto)
64-
}
65-
6661
@Get('/candles')
6762
async getCandles(@Query() dto: GetCandlesDto) {
6863
return await this.appService.getCandles(dto)
@@ -97,6 +92,11 @@ export class AppController {
9792
return this.appService.getTrades(dto)
9893
}
9994

95+
@Get('/competitions')
96+
getCompetitions() {
97+
return this.appService.getCompetitions()
98+
}
99+
100100
@Get('/tokenBurns')
101101
getTokenBurns(@Query() dto: GetTokenBurnsDto) {
102102
return this.appService.getTokenBurns(dto)

src/app.service.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
import {Injectable, Logger} from '@nestjs/common';
22
import {DataSource, EntityManager, MoreThan} from "typeorm";
3-
import {Comment, LiquidityProvision, Token, TokenBalance, TokenBurn, TokenWinner, Trade, UserAccount} from "./entities";
3+
import {
4+
Comment,
5+
CompetitionEntity,
6+
LiquidityProvision,
7+
Token,
8+
TokenBalance,
9+
TokenBurn,
10+
Trade,
11+
UserAccount
12+
} from "./entities";
413
import {AddCommentDto, GetCommentsDto} from "./dto/comment.dto";
514
import {GetTokenBalancesDto, GetTokenBurnsDto, GetTokensDto, GetTokenWinnersDto} from "./dto/token.dto";
615
import {GetCandlesDto, GetTradesDto} from "./dto/trade.dto";
@@ -77,16 +86,6 @@ export class AppService {
7786
})
7887
}
7988

80-
async getTokenWinners(dto: GetTokenWinnersDto) {
81-
return await this.dataSource.manager.find(TokenWinner, {
82-
order: {
83-
timestamp: 'desc'
84-
},
85-
take: dto.limit,
86-
skip: dto.offset,
87-
})
88-
}
89-
9089
async getTrades(dto: GetTradesDto){
9190
return await this.dataSource.manager.find(Trade, {
9291
where: {
@@ -102,6 +101,16 @@ export class AppService {
102101
})
103102
}
104103

104+
async getCompetitions() {
105+
return await this.dataSource.manager.find(CompetitionEntity, {
106+
relations: ['winnerToken'],
107+
where: {},
108+
order: {
109+
competitionId: 'desc'
110+
}
111+
})
112+
}
113+
105114
async getTokenBurns(dto: GetTokenBurnsDto){
106115
return await this.dataSource.manager.find(TokenBurn, {
107116
where: {

src/entities/competition.entity.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ import {
22
Column,
33
CreateDateColumn,
44
Entity,
5+
OneToOne,
56
PrimaryGeneratedColumn,
7+
JoinColumn
68
} from 'typeorm';
79
import { ApiProperty } from '@nestjs/swagger';
10+
import {Token} from "./token.entity";
11+
812
@Entity({ name: 'competitions' })
913
export class CompetitionEntity {
1014
@ApiProperty()
@@ -24,8 +28,21 @@ export class CompetitionEntity {
2428
competitionId: number;
2529

2630
@ApiProperty()
27-
@Column({ type: 'bigint' })
28-
timestamp: number;
31+
@Column({ type: 'bigint', nullable: false })
32+
timestampStart: number;
33+
34+
@ApiProperty()
35+
@Column({ type: 'bigint', nullable: true })
36+
timestampEnd: number;
37+
38+
@ApiProperty()
39+
@Column('bool', { default: false })
40+
isCompleted: boolean;
41+
42+
@ApiProperty()
43+
@OneToOne((type) => Token, token => token.competition)
44+
@JoinColumn()
45+
winnerToken: Token | null
2946

3047
@ApiProperty()
3148
@CreateDateColumn({ name: 'createdAt' })

src/entities/index.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import { IndexerState } from './indexer.state.entity';
44
import { Trade } from './trade.entity';
55
import { Comment } from './comment.entity';
66
import { TokenBalance } from './token.balances.entity';
7-
import { TokenWinner } from './token.winner.entity';
87
import { SignInRequestEntity } from './signin.entity';
98
import { TokenBurn } from './token.burn.entity';
109
import { LiquidityProvision } from './liquidity.provision.entity';
@@ -17,7 +16,6 @@ const entities = [
1716
Trade,
1817
Comment,
1918
TokenBalance,
20-
TokenWinner,
2119
SignInRequestEntity,
2220
TokenBurn,
2321
LiquidityProvision,
@@ -31,7 +29,6 @@ export {
3129
Trade,
3230
Comment,
3331
TokenBalance,
34-
TokenWinner,
3532
SignInRequestEntity,
3633
TokenBurn,
3734
LiquidityProvision,

src/entities/token.entity.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@ import {UserAccount} from "./user-account.entity";
1414
import {TokenMetadata} from "../types";
1515
import {Trade} from "./trade.entity";
1616
import Decimal from "decimal.js";
17+
import {CompetitionEntity} from "./competition.entity";
1718

1819
class ColumnNumericTransformer {
1920
to(data: string): string {
2021
return data;
2122
}
2223
from(data: number): string {
23-
return new Decimal(data).toFixed()
24+
return data ? new Decimal(data).toFixed() : '0'
2425
}
2526
}
2627

@@ -57,9 +58,15 @@ export class Token {
5758
@Column({ type: 'json', nullable: true })
5859
uriData: TokenMetadata | null;
5960

60-
@ApiProperty()
61-
@Column({ type: 'integer' })
62-
competitionId: number;
61+
// @ApiProperty()
62+
// @Column({ type: 'integer' })
63+
// competitionId: number;
64+
65+
@ManyToOne(() => CompetitionEntity, {
66+
eager: true
67+
})
68+
@JoinTable()
69+
competition: CompetitionEntity
6370

6471
@ApiProperty()
6572
@Column({ type: 'bigint' })

src/entities/token.winner.entity.ts

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/indexer/indexer.service.ts

Lines changed: 54 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ import {Injectable, Logger} from '@nestjs/common';
22
import {Contract, ContractAbi, EventLog, Web3} from "web3";
33
import {TokenMetadata, TradeType} from "../types";
44
import axios from "axios";
5-
import process from "process";
5+
import * as process from "process";
66
import {
77
CompetitionEntity,
88
IndexerState,
99
LiquidityProvision,
1010
Token,
1111
TokenBalance,
1212
TokenBurn,
13-
TokenWinner,
1413
Trade
1514
} from "../entities";
1615
import {ConfigService} from "@nestjs/config";
@@ -107,37 +106,27 @@ export class IndexerService {
107106
return
108107
}
109108

110-
const existedWinner = await transactionalEntityManager.findOne(TokenWinner, {
111-
where: {
112-
token: {
113-
address: winnerAddress,
114-
},
115-
competitionId,
116-
timestamp
117-
}
109+
const token = await this.appService.getTokenByAddress(winnerAddress, transactionalEntityManager)
110+
if(!token) {
111+
this.logger.error(`Failed to add winner: winner token not found in database, winnerAddress=${winnerAddress}, exit`)
112+
process.exit(1)
113+
}
114+
115+
const competition = await transactionalEntityManager.findOne(CompetitionEntity, {
116+
where: { competitionId }
118117
})
118+
if(!competition) {
119+
this.logger.error(`Failed to add winner: competition=${competitionId} not found in database, exit`)
120+
process.exit(1)
121+
}
119122

120-
if(!existedWinner) {
121-
const token = await this.appService.getTokenByAddress(winnerAddress, transactionalEntityManager)
122-
if(!token) {
123-
this.logger.error(`Failed to add winner: winner token not found in database, winnerAddress=${winnerAddress}, exit`)
124-
process.exit(1)
125-
}
123+
token.isWinner = true
124+
await transactionalEntityManager.save(token)
126125

127-
token.isWinner = true
126+
competition.winnerToken = token
127+
await transactionalEntityManager.save(competition)
128128

129-
await transactionalEntityManager.save(token)
130-
await transactionalEntityManager.insert(TokenWinner, {
131-
token,
132-
timestamp,
133-
competitionId,
134-
txnHash,
135-
blockNumber
136-
})
137-
this.logger.log(`Added new token winner=${winnerAddress}, competitionId=${competitionId}, timestamp=${timestamp}`)
138-
} else {
139-
this.logger.warn(`Token winner=${winnerAddress}, competitionId=${competitionId}, timestamp=${timestamp} already exists, skip`)
140-
}
129+
this.logger.log(`Added new token winner=${winnerAddress}, competitionId=${competitionId}, timestamp=${timestamp}`)
141130
}
142131

143132
private async processCreateTokenEvent(event: EventLog, transactionalEntityManager: EntityManager) {
@@ -170,17 +159,32 @@ export class IndexerService {
170159
}
171160
}
172161

162+
const competition = await transactionalEntityManager.findOne(CompetitionEntity, {
163+
where: {},
164+
order: {
165+
competitionId: 'DESC'
166+
}
167+
})
168+
if(!competition) {
169+
this.logger.error(`Create token: current competition is missing in DB; exit`)
170+
process.exit(1)
171+
}
172+
if(competition.isCompleted) {
173+
this.logger.error(`Create token: current competition is completed, new competitions has not started yet; exit`)
174+
process.exit(1)
175+
}
176+
173177
await transactionalEntityManager.insert(Token, {
174178
txnHash,
175179
address: tokenAddress,
176180
blockNumber: Number(event.blockNumber),
177181
name,
178182
symbol,
179-
competitionId,
180183
timestamp,
181184
user,
182185
uri,
183186
uriData,
187+
competition
184188
});
185189
this.logger.log(`Create token: address=${tokenAddress}, name=${name}, symbol=${symbol}, uri=${uri}, creator=${creatorAddress}, competitionId=${competitionId}, txnHash=${txnHash}`);
186190
}
@@ -370,11 +374,26 @@ export class IndexerService {
370374
const values = event.returnValues
371375
const competitionId = Number(values['competitionId'] as bigint)
372376
const timestamp = Number(values['timestamp'] as bigint)
377+
378+
const competitions = await this.appService.getCompetitions()
379+
if(competitions.length > 0) {
380+
const currentCompetition = competitions[0]
381+
if(currentCompetition) {
382+
currentCompetition.isCompleted = true
383+
currentCompetition.timestampEnd = timestamp
384+
await transactionalEntityManager.save(currentCompetition)
385+
}
386+
387+
}
388+
373389
await transactionalEntityManager.insert(CompetitionEntity, {
374390
txnHash,
375391
blockNumber: Number(event.blockNumber),
376392
competitionId,
377-
timestamp,
393+
timestampStart: timestamp,
394+
timestampEnd: null,
395+
isCompleted: false,
396+
winnerToken: null,
378397
});
379398
this.logger.log(`NewCompetitionStarted: competitionId=${competitionId}, timestamp=${timestamp}, txnHash=${txnHash}`);
380399
}
@@ -413,6 +432,10 @@ export class IndexerService {
413432
}
414433

415434
if(toBlock - fromBlock >= 1) {
435+
const newCompetitionEvents = await this.tokenFactoryContract.getPastEvents('allEvents', {
436+
fromBlock, toBlock, topics: [ this.web3.utils.sha3('NewCompetitionStarted(uint256,uint256)')],
437+
}) as EventLog[];
438+
416439
const setWinnerEvents = await this.tokenFactoryContract.getPastEvents('allEvents', {
417440
fromBlock, toBlock, topics: [ this.web3.utils.sha3('SetWinner(address,uint256,uint256)')],
418441
}) as EventLog[];
@@ -421,10 +444,6 @@ export class IndexerService {
421444
fromBlock, toBlock, topics: [ this.web3.utils.sha3('WinnerLiquidityAdded(address,address,address,address,uint256,uint128,uint256,uint256,uint256)')],
422445
}) as EventLog[];
423446

424-
const newCompetitionEvents = await this.tokenFactoryContract.getPastEvents('allEvents', {
425-
fromBlock, toBlock, topics: [ this.web3.utils.sha3('NewCompetitionStarted(uint256,uint256)')],
426-
}) as EventLog[];
427-
428447
const tokenCreatedEvents = await this.tokenFactoryContract.getPastEvents('allEvents', {
429448
fromBlock,
430449
toBlock,

0 commit comments

Comments
 (0)