Skip to content

Commit

Permalink
Merge pull request #133 from sotatek-dev/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
Sotatek-TanHoang authored Oct 3, 2024
2 parents eab5062 + ef71303 commit 074f6c9
Show file tree
Hide file tree
Showing 38 changed files with 522 additions and 428 deletions.
73 changes: 59 additions & 14 deletions design/bridge-eth-mina.puml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ title Lock From Eth to Mina
actor User
boundary fe as "Frontend"
control be as "Backend"
boundary evm_crawler as "EVM crawler"
boundary mina_validator as "Mina signature validators"
boundary mina_sender as "Mina tx sender"
boundary mina_crawler as "Mina crawler"
participant Ethereum
participant Mina
control evm_crawler as "EVM crawler"
control job_provider as "Job provider"
database db as "Database"
queue queue1 as "Queue"
control mina_validator as "Mina signature validators"
control mina_sender as "Mina tx sender"
control mina_crawler as "Mina crawler"
participant Mina
autonumber

group#LightGreen User lock token from Evm
group#LightGreen (1) User lock token from Evm

User -> fe : select network to bridge

Expand All @@ -35,7 +37,7 @@ group#LightGreen User lock token from Evm


end
group#LightGreen Crawler evm fetch lock tx
group#LightGreen (2) Crawler evm fetch lock tx
evm_crawler->Ethereum: fetch lock events
activate Ethereum
Ethereum --> evm_crawler: return locked tx events
Expand All @@ -46,27 +48,69 @@ group#LightGreen Crawler evm fetch lock tx
db --> evm_crawler: saved tx with status waiting to be unlocked
deactivate db
end
group#LightGreen System unlock token to Mina
group#LightGreen (3) Job Provider create queued job
loop
par
job_provider->db: get pending transaction need signatures
activate db
db --> job_provider: list of pending transaction
deactivate db
job_provider -> queue1: send jobs to queue
activate queue1
queue1 --> job_provider: success
deactivate queue1
else
job_provider->db: get validated transaction ready to be sent
activate db
db --> job_provider: list of ready transaction
deactivate db
job_provider -> queue1: send jobs to queue
activate queue1
queue1 --> job_provider: success
deactivate queue1
end
end
end
group#LightGreen (4) Job Validator process generating signature for tx

mina_validator -> db: get pending unlock tx and verify theirs signature
queue1 -> mina_validator: trigger job
activate mina_validator
mina_validator --> db: get data for needed for queued job
activate db
db --> mina_validator: update signature
db --> mina_validator: needed data
deactivate db
deactivate mina_validator

mina_sender -> db: get signatured verified tx
mina_validator -->mina_validator: generated the signature

mina_validator -> db: save the signature
activate db
db --> mina_validator: save success
deactivate db

mina_validator --> queue1: job completed
deactivate mina_validator
end
group#LightGreen (5) Job Sender process sending tx to Mina network

queue1 -> mina_sender: trigger sender by queued job
activate mina_sender
db -> mina_sender: return tx
mina_sender --> db: get data for needed for queued job
activate db
db --> mina_sender: needed data
deactivate db

mina_sender -> Mina: prove, send tx
mina_sender --> mina_sender: build transaction

mina_sender -> Mina: Send the tx to Mina
activate Mina
Mina --> mina_sender: return tx hash
deactivate Mina
mina_sender --> mina_sender: wait for the tx to be applied
mina_sender --> queue1: job completed
deactivate mina_sender

end
group#LightGreen (6) Mina crawler confirms sent tx
mina_crawler -> Mina: get unlock events
activate mina_crawler
activate Mina
Expand All @@ -79,5 +123,6 @@ group#LightGreen System unlock token to Mina
deactivate db
end


@enduml

75 changes: 60 additions & 15 deletions design/bridge-mina-eth.puml
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@ title Lock From Mina to Eth
actor User
boundary fe as "Frontend"
control be as "Backend"
boundary evm_crawler as "Mina crawler"
boundary mina_validator as "Mina signature validators"
boundary mina_sender as "Evm tx sender"
boundary mina_crawler as "Evm crawler"
participant Ethereum as "Mina"
participant Mina as "Evm"
participant Ethereum as "MINA"
control evm_crawler as "MINA crawler"
control job_provider as "Job provider"
database db as "Database"
queue queue1 as "Queue"
control mina_validator as "EVM signature validators"
control mina_sender as "EVM tx sender"
control mina_crawler as "EVM crawler"
participant Mina as "EVM"
autonumber

group#LightGreen User lock token from Mina
group#LightGreen (1) User lock token from Evm

User -> fe : select network to bridge

Expand All @@ -35,7 +37,7 @@ group#LightGreen User lock token from Mina


end
group#LightGreen Crawler Mina fetch lock tx
group#LightGreen (2) Crawler evm fetch lock tx
evm_crawler->Ethereum: fetch lock events
activate Ethereum
Ethereum --> evm_crawler: return locked tx events
Expand All @@ -46,27 +48,69 @@ group#LightGreen Crawler Mina fetch lock tx
db --> evm_crawler: saved tx with status waiting to be unlocked
deactivate db
end
group#LightGreen System unlock token to Evm
group#LightGreen (3) Job Provider create queued job
loop
par
job_provider->db: get pending transaction need signatures
activate db
db --> job_provider: list of pending transaction
deactivate db
job_provider -> queue1: send jobs to queue
activate queue1
queue1 --> job_provider: success
deactivate queue1
else
job_provider->db: get validated transaction ready to be sent
activate db
db --> job_provider: list of ready transaction
deactivate db
job_provider -> queue1: send jobs to queue
activate queue1
queue1 --> job_provider: success
deactivate queue1
end
end
end
group#LightGreen (4) Job Validator process generating signature for tx

mina_validator -> db: get pending unlock tx and verify theirs signature
queue1 -> mina_validator: trigger job
activate mina_validator
mina_validator --> db: get data for needed for queued job
activate db
db --> mina_validator: update signature
db --> mina_validator: needed data
deactivate db
deactivate mina_validator

mina_sender -> db: get signatured verified tx
mina_validator -->mina_validator: generated the signature

mina_validator -> db: save the signature
activate db
db --> mina_validator: save success
deactivate db

mina_validator --> queue1: job completed
deactivate mina_validator
end
group#LightGreen (5) Job Sender process sending tx to Mina network

queue1 -> mina_sender: trigger sender by queued job
activate mina_sender
db -> mina_sender: return tx
mina_sender --> db: get data for needed for queued job
activate db
db --> mina_sender: needed data
deactivate db

mina_sender -> Mina: prove, send tx
mina_sender --> mina_sender: build transaction

mina_sender -> Mina: Send the tx to EVM
activate Mina
Mina --> mina_sender: return tx hash
deactivate Mina
mina_sender --> mina_sender: wait for the tx to be applied
mina_sender --> queue1: job completed
deactivate mina_sender

end
group#LightGreen (6) Mina crawler confirms sent tx
mina_crawler -> Mina: get unlock events
activate mina_crawler
activate Mina
Expand All @@ -79,5 +123,6 @@ group#LightGreen System unlock token to Evm
deactivate db
end


@enduml

11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
"@types/jest": "^29.5.2",
"@types/node": "^20.16.5",
"@types/supertest": "^2.0.12",
"@types/web3": "^1.2.2",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
Expand All @@ -91,5 +92,4 @@
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
}

}
7 changes: 3 additions & 4 deletions src/config/common.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ConfigService } from '@nestjs/config';

import { ENetworkName } from '../constants/blockchain.constant.js';
import { EEnvKey } from '../constants/env.constant.js';
import { RpcFactory } from '../shared/modules/web3/web3.module.js';
import { ETHBridgeContract } from '../shared/modules/web3/web3.service.js';
Expand All @@ -10,14 +9,14 @@ async function createRpcService(configService: ConfigService) {
}

async function createRpcEthService(configService: ConfigService) {
return await RpcFactory(configService, ENetworkName.ETH);
return await RpcFactory(configService);
}
function getEthBridgeAddress(configService: ConfigService) {
return configService.get<string>(EEnvKey.ETH_BRIDGE_CONTRACT_ADDRESS);
}

function getEthBridgeStartBlock(configService: ConfigService) {
return +configService.get<number>(EEnvKey.ETH_BRIDGE_START_BLOCK);
return +configService.get<number>(EEnvKey.ETH_BRIDGE_START_BLOCK)!;
}

async function initializeEthContract(configService: ConfigService) {
Expand All @@ -28,6 +27,6 @@ async function initializeEthContract(configService: ConfigService) {
]);

// Instantiate the ETHBridgeContract with the resolved dependencies
return new ETHBridgeContract(rpcEthService, address, _startBlock);
return new ETHBridgeContract(rpcEthService, address!, _startBlock);
}
export { createRpcService, createRpcEthService, getEthBridgeAddress, getEthBridgeStartBlock, initializeEthContract };
1 change: 1 addition & 0 deletions src/constants/blockchain.constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export enum EEventStatus {
COMPLETED = 'completed',
FAILED = 'failed',
NOTOKENPAIR = 'noTokenPair',
CANNOT_PROCESS = 'cannotProcess',
}

export enum ETokenPairStatus {
Expand Down
10 changes: 5 additions & 5 deletions src/core/base-repository.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Repository, SelectQueryBuilder } from 'typeorm';
import { ObjectLiteral, Repository, SelectQueryBuilder } from 'typeorm';

import { EDirection } from '../constants/api.constant.js';
import { ETableName } from '../constants/entity.constant.js';
import { IPagination } from '../shared/interfaces/pagination.interface.js';

export abstract class BaseRepository<E> extends Repository<E> {
export abstract class BaseRepository<E extends ObjectLiteral> extends Repository<E> {
protected abstract alias: ETableName;

protected createQb() {
Expand All @@ -25,9 +25,9 @@ export abstract class BaseRepository<E> extends Repository<E> {
queryBuilder.take(data.limit);
}
if (data.page && data.useLimit) {
queryBuilder.offset((data.page - 1) * data.limit);
queryBuilder.offset((data.page - 1) * data.limit!);
} else if (data.page) {
queryBuilder.skip((data.page - 1) * data.limit);
queryBuilder.skip((data.page - 1) * data.limit!);
}
if (data.sortBy) {
if (!selections || selections?.includes(`${this.alias}.${data.sortBy}`)) {
Expand All @@ -51,7 +51,7 @@ export abstract class BaseRepository<E> extends Repository<E> {
}

if (data.page) {
queryBuilder.offset((data.page - 1) * data.limit);
queryBuilder.offset((data.page - 1) * data.limit!);
}

if (data.sortBy) {
Expand Down
3 changes: 2 additions & 1 deletion src/database/repositories/common-configuration.repository.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { UpdateCommonConfigBodyDto } from 'modules/users/dto/common-config-request.dto.js';
import { EntityRepository } from 'nestjs-typeorm-custom-repository';

import { ETableName } from '../../constants/entity.constant.js';
Expand All @@ -14,7 +15,7 @@ export class CommonConfigRepository extends BaseRepository<CommonConfig> {
.getOne();
}

public updateCommonConfig(id: number, updateConfig) {
public updateCommonConfig(id: number, updateConfig: UpdateCommonConfigBodyDto) {
return this.createQueryBuilder(`${this.alias}`)
.update(CommonConfig)
.set(updateConfig)
Expand Down
8 changes: 4 additions & 4 deletions src/database/repositories/event-log.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { ETableName } from '../../constants/entity.constant.js';
import { MAX_RETRIES } from '../../constants/service.constant.js';
import { BaseRepository } from '../../core/base-repository.js';
import { EventLog } from '../../modules/crawler/entities/event-logs.entity.js';
import { GetHistoryDto } from '../../modules/users/dto/history-response.dto.js';
import { GetHistoryDto, GetHistoryOfUserDto } from '../../modules/users/dto/history-response.dto.js';
import { endOfDayUnix, nowUnix, startOfDayUnix } from '../../shared/utils/time.js';

@EntityRepository(EventLog)
export class EventLogRepository extends BaseRepository<EventLog> {
protected alias: ETableName = ETableName.EVENT_LOGS;

public async getEventLockWithNetwork(network: ENetworkName, threshold?: number): Promise<EventLog> {
public async getEventLockWithNetwork(network: ENetworkName, threshold?: number): Promise<EventLog | null> {
const qb = this.createQueryBuilder(`${this.alias}`);
qb.innerJoinAndSelect(`${this.alias}.validator`, 'signature');

Expand Down Expand Up @@ -98,7 +98,7 @@ export class EventLogRepository extends BaseRepository<EventLog> {
.execute();
}

public async getHistoriesOfUser(address: string, options) {
public async getHistoriesOfUser(address: string, options: GetHistoryOfUserDto) {
const queryBuilder = this.createQb();
queryBuilder
.where(`LOWER(${this.alias}.sender_address) = :address OR LOWER(${this.alias}.receive_address) = :address`, {
Expand Down Expand Up @@ -150,7 +150,7 @@ export class EventLogRepository extends BaseRepository<EventLog> {
return queryBuilder.getManyAndCount();
}

public async sumAmountBridgeOfUserInDay(address) {
public async sumAmountBridgeOfUserInDay(address: string) {
const qb = this.createQb();
qb.select([`${this.alias}.sender_address`, `SUM(CAST(${this.alias}.amount_from as DECIMAL(100,2))) as totalamount`])
.where(`${this.alias}.sender_address = :address`, { address })
Expand Down
Loading

0 comments on commit 074f6c9

Please sign in to comment.