fix: withdrawal processor

This commit is contained in:
nikdementev 2021-07-14 16:56:28 +03:00
parent 20d71a731a
commit 268dd097b7
No known key found for this signature in database
GPG Key ID: 769B05D57CF16FE2
9 changed files with 58 additions and 29 deletions

3
example.env Normal file
View File

@ -0,0 +1,3 @@
RPC_URL=
PRIVATE_KEY=
SERVICE_FEE=0.05

View File

@ -1,12 +1,5 @@
export const baseConfig = () => ({ export const baseConfig = () => ({
port: parseInt(process.env.PORT, 10) || 8080, port: parseInt(process.env.PORT, 10) || 8080,
txManager: { gasLimit: 400000,
privateKey: '', fee: process.env.SERVICE_FEE,
rpcUrl: '',
config: {
CONFIRMATIONS: '',
MAX_GAS_PRICE: '',
THROW_ON_REVERT: false,
},
},
}); });

View File

@ -1,2 +1,4 @@
export * from './configuration'; export * from './configuration';
export * from './bull.config'; export * from './bull.config';
export * from './txManager.config';

View File

@ -0,0 +1,11 @@
import { registerAs } from '@nestjs/config';
export default registerAs('txManager', () => ({
privateKey: process.env.PRIVATE_KEY,
rpcUrl: process.env.RPC_URL,
config: {
CONFIRMATIONS: '4',
MAX_GAS_PRICE: '100',
THROW_ON_REVERT: false,
},
}));

View File

@ -5,11 +5,14 @@ import { NestExpressApplication } from '@nestjs/platform-express';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule); try {
const app = await NestFactory.create<NestExpressApplication>(AppModule, { cors: true });
const configService = app.get(ConfigService); const configService = app.get(ConfigService);
await app.listen(configService.get('port')); await app.listen(configService.get('port'));
} catch (err) {
console.log('err', err.message)
}
} }
bootstrap() bootstrap()
.then((result) => console.log('result', result))
.catch((e) => console.log('error', e.message));

View File

@ -9,6 +9,7 @@ import { InjectQueue, Process, Processor } from '@nestjs/bull';
import { toWei } from '@/utilities'; import { toWei } from '@/utilities';
import { getGasPrice } from '@/services'; import { getGasPrice } from '@/services';
import { getTornadoPool } from '@/contracts'; import { getTornadoPool } from '@/contracts';
import txMangerConfig from '@/config/txManager.config';
import { BaseProcessor } from './base.processor'; import { BaseProcessor } from './base.processor';
@ -18,7 +19,6 @@ export interface Withdrawal {
amount: string; amount: string;
txHash: string; txHash: string;
status: string; status: string;
contract: string;
confirmations: number; confirmations: number;
} }
@ -41,7 +41,7 @@ export class WithdrawalProcessor extends BaseProcessor<Withdrawal> {
const { args, amount } = job.data; const { args, amount } = job.data;
await this.checkFee({ fee: args[4], amount }); await this.checkFee({ fee: args[6], amount });
await this.submitTx(job); await this.submitTx(job);
} catch (err) { } catch (err) {
await job.moveToFailed(err, true); await job.moveToFailed(err, true);
@ -49,7 +49,7 @@ export class WithdrawalProcessor extends BaseProcessor<Withdrawal> {
} }
async submitTx(job: Job<Withdrawal>) { async submitTx(job: Job<Withdrawal>) {
const txManager = new TxManager(this.configService.get('txManager')); const txManager = new TxManager(txMangerConfig());
const prepareTx = await this.prepareTransaction(job.data); const prepareTx = await this.prepareTransaction(job.data);
const tx = await txManager.createTx(prepareTx); const tx = await txManager.createTx(prepareTx);
@ -89,7 +89,7 @@ export class WithdrawalProcessor extends BaseProcessor<Withdrawal> {
} }
async prepareTransaction({ proof, args, amount }) { async prepareTransaction({ proof, args, amount }) {
const contract = getTornadoPool(1); const contract = getTornadoPool(5);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
@ -98,34 +98,31 @@ export class WithdrawalProcessor extends BaseProcessor<Withdrawal> {
...args, ...args,
]); ]);
const gasLimit = this.configService.get<number>('gasLimits'); const gasLimit = this.configService.get<number>('gasLimit');
return { return {
data, data,
gasLimit, gasLimit,
value: amount, value: BigNumber.from(0)._hex,
to: contract.address, to: contract.address,
}; };
} }
async checkFee({ fee, amount }) { async checkFee({ fee, amount }) {
const gasLimit = this.configService.get<number>('gasLimits'); const gasLimit = this.configService.get<number>('gasLimit');
const { fast } = await getGasPrice(1); const { fast } = await getGasPrice(5);
const expense = BigNumber.from(toWei(fast.toString(), 'gwei')).mul( const expense = BigNumber.from(toWei(fast.toString(), 'gwei')).mul(
gasLimit, gasLimit,
); );
const serviceFee = this.configService.get<number>('fee'); const serviceFee = this.configService.get<number>('fee');
const feePercent = BigNumber.from(amount).mul(serviceFee * 1e10).div(100 * 1e10)
const feePercent = BigNumber.from(toWei(amount))
.mul(toWei(serviceFee.toString()))
.div(100);
const desiredFee = expense.add(feePercent); const desiredFee = expense.add(feePercent);
if (fee.lt(desiredFee)) { if (BigNumber.from(fee).lt(desiredFee)) {
throw new Error( throw new Error(
'Provided fee is not enough. Probably it is a Gas Price spike, try to resubmit.', 'Provided fee is not enough. Probably it is a Gas Price spike, try to resubmit.',
); );

View File

@ -1,4 +1,4 @@
import { Controller, Get } from '@nestjs/common'; import { Controller, Body, Get, Post } from '@nestjs/common';
import { StatusService } from './stat.service'; import { StatusService } from './stat.service';
@ -15,4 +15,11 @@ export class StatusController {
async main(): Promise<string> { async main(): Promise<string> {
return this.service.main(); return this.service.main();
} }
@Post('/withdrawal')
async withdrawal(_, @Body() { body }: any): Promise<string> {
console.log('body', body)
return await this.service.withdrawal(JSON.parse(body))
}
} }

View File

@ -4,9 +4,12 @@ import { ConfigModule } from '@nestjs/config';
import { StatusService } from './stat.service'; import { StatusService } from './stat.service';
import { StatusController } from './stat.controller'; import { StatusController } from './stat.controller';
import { QueueModule } from '@/modules';
@Module({ @Module({
imports: [ConfigModule], imports: [ConfigModule, QueueModule],
providers: [StatusService], providers: [StatusService],
controllers: [StatusController], controllers: [StatusController],
exports: [],
}) })
export class StatusModule {} export class StatusModule {}

View File

@ -1,7 +1,11 @@
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
import { Queue } from 'bull';
import { InjectQueue } from '@nestjs/bull';
@Injectable() @Injectable()
class StatusService { class StatusService {
constructor(@InjectQueue('withdrawal') private withdrawalQueue: Queue) {}
async status(): Promise<Health> { async status(): Promise<Health> {
return { return {
status: '', status: '',
@ -12,6 +16,12 @@ class StatusService {
main(): string { main(): string {
return `This is <a href=https://tornado.cash>tornado.cash</a> Relayer service. Check the <a href=/status>/status</a> for settings`; return `This is <a href=https://tornado.cash>tornado.cash</a> Relayer service. Check the <a href=/status>/status</a> for settings`;
} }
async withdrawal(data): Promise<string> {
const job = await this.withdrawalQueue.add(data)
return String(job.id);
}
} }
export { StatusService }; export { StatusService };