diff --git a/package.json b/package.json index dd4d1b24..76f8b4a6 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "scripts": { "prepack": "tasegir run --watch node_modules/.bin/oclif-dev -- manifest && sed -i '' 's#\"./src/cli\"#\"./lib/cli\"#g' package.json", "postpack": "sed -i '' 's#\"./lib/cli\"#\"./src/cli\"#g' package.json", - "bin": "tasegir run --watch ./bin/run -- ", + "bin": "tasegir run ./bin/run -- ", "compile": "tasegir compile", "docs": "typedoc --mode modules --excludeNotExported --readme none --excludePrivate --tsconfig ./node_modules/tasegir/src/config/tsconfig.json --exclude 'src/providers/*,test/**/*' --out docs src", "types-check": "tasegir types-check", diff --git a/src/cli/start.ts b/src/cli/start.ts index 818a33dc..2999b651 100644 --- a/src/cli/start.ts +++ b/src/cli/start.ts @@ -108,13 +108,13 @@ ${formattedServices}` const resetPromise = new Promise(resolve => { appFactory({ appResetCallBack: () => resolve() - }).then((application: { app: Application, stop: () => void }) => { + }).then(({ app, stop }) => { // Lets save the function that stops the app - stopCallback = application.stop + stopCallback = stop // Start server const port = config.get('port') - const server = application.app.listen(port) + const server = app.listen(port) server.on('listening', () => logger.info(`Server started on port ${port}`) diff --git a/src/services/storage/handlers/stake.ts b/src/services/storage/handlers/stake.ts index 1ac6345f..539b2674 100644 --- a/src/services/storage/handlers/stake.ts +++ b/src/services/storage/handlers/stake.ts @@ -1,4 +1,5 @@ import { EventData } from 'web3-eth-contract' +import BigNumber from 'bignumber.js' import { loggingFactory } from '../../../logger' import { Handler } from '../../../definitions' @@ -11,13 +12,13 @@ const handlers = { async Staked (event: EventData, { stakeService }: StorageServices): Promise { const { user: account, total, token, amount } = event.returnValues - const stake = await StakeModel.findOne({ where: { token, account } }) + let stake = await StakeModel.findOne({ where: { token, account } }) if (!stake) { - throw new Error(`Stake for acoount ${account}, token ${token} not created`) + stake = new StakeModel({ account, token, total: 0 }) } - stake.total = total + stake.total = new BigNumber(stake.total).plus(amount) await stake.save() logger.info(`Account ${account} stake amount ${amount}, final balance ${total}`) @@ -29,18 +30,18 @@ const handlers = { async Unstaked (event: EventData, { stakeService }: StorageServices): Promise { const { user: account, total, token, amount } = event.returnValues - const stake = await StakeModel.findOne({ where: { token, account } }) + let stake = await StakeModel.findOne({ where: { token, account } }) if (!stake) { - throw new Error(`Stake for acoount ${account}, token ${token} not created`) + stake = new StakeModel({ account, token, total: 0 }) } - stake.total = total + stake.total = new BigNumber(stake.total).minus(amount) await stake.save() logger.info(`Account ${account} stake amount ${amount}, final balance ${total}`) if (stakeService.emit) { - stakeService.emit('updated', stake!.toJSON()) + stakeService.emit('updated', stake.toJSON()) } } } @@ -51,22 +52,10 @@ function isValidEvent (value: string): value is keyof typeof handlers { const handler: Handler = { events: ['Staked', 'Unstaked'], - async process (event: EventData, services: StorageServices): Promise { + process (event: EventData, services: StorageServices): Promise { if (!isValidEvent(event.event)) { return Promise.reject(new Error(`Unknown event ${event.event}`)) } - const { user: account, token } = event.returnValues - const stake = await StakeModel.findOne({ where: { account, token } }) - - // Create stake row if not exist - if (!stake) { - const stakeFromDb = await StakeModel.create({ account, token, total: '0' }) - logger.debug('Stake created: ', stakeFromDb.toJSON()) - - if (services.stakeService.emit) { - services.stakeService.emit('created', stakeFromDb.toJSON()) - } - } return handlers[event.event](event, services) } diff --git a/src/services/storage/index.ts b/src/services/storage/index.ts index bddece55..47758354 100644 --- a/src/services/storage/index.ts +++ b/src/services/storage/index.ts @@ -11,7 +11,7 @@ import { EventEmitter } from 'events' import { ethFactory } from '../../blockchain' import { getEventsEmitterForService, isServiceInitialized } from '../../blockchain/utils' import { REORG_OUT_OF_RANGE_EVENT_NAME } from '../../blockchain/events' -import { Application, CachedService, ServiceAddresses } from '../../definitions' +import { Application, CachedService, Logger, ServiceAddresses } from '../../definitions' import { loggingFactory } from '../../logger' import { errorHandler, waitForReadyApp } from '../../utils' import Agreement from './models/agreement.model' @@ -43,13 +43,14 @@ export interface StorageServices { stakeService: StakeService } -const SERVICE_NAME = 'storage' -const STORAGE_MANAGER = 'storageManager' -const STAKING = 'staking' +const STORAGE_MANAGER = 'storage.storageManager' +const STAKING = 'storage.staking' -const logger = loggingFactory(SERVICE_NAME) +const storageLogger = loggingFactory('storage') +const storageManagerLogger = loggingFactory(STORAGE_MANAGER) +const stakingLogger = loggingFactory(STAKING) -function precacheContract (eventEmitter: EventEmitter, services: StorageServices, eth: Eth): Promise { +function precacheContract (eventEmitter: EventEmitter, services: StorageServices, eth: Eth, logger: Logger): Promise { return new Promise((resolve, reject) => { const dataQueue: EventData[] = [] const dataQueuePusher = (event: EventData): void => { dataQueue.push(event) } @@ -77,8 +78,8 @@ function precacheContract (eventEmitter: EventEmitter, services: StorageServices async function precache (possibleEth?: Eth): Promise { const eth = possibleEth || ethFactory() - const storageEventsEmitter = getEventsEmitterForService(`${SERVICE_NAME}.${STORAGE_MANAGER}`, eth, storageManagerContract.abi as AbiItem[]) - const stakingEventsEmitter = getEventsEmitterForService(`${SERVICE_NAME}.${STAKING}`, eth, stakingContract.abi as AbiItem[]) + const storageEventsEmitter = getEventsEmitterForService(`${STORAGE_MANAGER}`, eth, storageManagerContract.abi as AbiItem[]) + const stakingEventsEmitter = getEventsEmitterForService(`${STAKING}`, eth, stakingContract.abi as AbiItem[]) const services: StorageServices = { stakeService: new StakeService({ Model: StakeModel }), @@ -87,19 +88,19 @@ async function precache (possibleEth?: Eth): Promise { } // Precache Storage Manager - await precacheContract(storageEventsEmitter, services, eth) + await precacheContract(storageEventsEmitter, services, eth, storageManagerLogger) // Precache Staking - await precacheContract(stakingEventsEmitter, services, eth) + await precacheContract(stakingEventsEmitter, services, eth, stakingLogger) } const storage: CachedService = { async initialize (app: Application): Promise<{ stop: () => void }> { if (!config.get('storage.enabled')) { - logger.info('Storage service: disabled') + storageLogger.info('Storage service: disabled') return { stop: () => undefined } } - logger.info('Storage service: enabled') + storageLogger.info('Storage service: enabled') await waitForReadyApp(app) @@ -125,28 +126,28 @@ const storage: CachedService = { const reorgEmitterService = app.service(ServiceAddresses.REORG_EMITTER) // We require services to be precached before running server - if (!isServiceInitialized(`${SERVICE_NAME}.${STORAGE_MANAGER}`)) { - return logger.critical('Storage service is not initialized! Run precache command.') + if (!isServiceInitialized(`${STORAGE_MANAGER}`) || !isServiceInitialized(STAKING)) { + return storageLogger.critical('Storage service is not initialized! Run precache command.') } const eth = app.get('eth') as Eth const confirmationService = app.service(ServiceAddresses.CONFIRMATIONS) // Storage Manager watcher - const storageManagerEventsEmitter = getEventsEmitterForService(`${SERVICE_NAME}.${STORAGE_MANAGER}`, eth, storageManagerContract.abi as AbiItem[]) - storageManagerEventsEmitter.on('newEvent', errorHandler(eventProcessor(services, eth), logger)) + const storageManagerEventsEmitter = getEventsEmitterForService(`${STORAGE_MANAGER}`, eth, storageManagerContract.abi as AbiItem[]) + storageManagerEventsEmitter.on('newEvent', errorHandler(eventProcessor(services, eth), storageManagerLogger)) storageManagerEventsEmitter.on('error', (e: Error) => { - logger.error(`There was unknown error in Events Emitter! ${e}`) + storageManagerLogger.error(`There was unknown error in Events Emitter! ${e}`) }) storageManagerEventsEmitter.on('newConfirmation', (data) => confirmationService.emit('newConfirmation', data)) storageManagerEventsEmitter.on('invalidConfirmation', (data) => confirmationService.emit('invalidConfirmation', data)) storageManagerEventsEmitter.on(REORG_OUT_OF_RANGE_EVENT_NAME, (blockNumber: number) => reorgEmitterService.emitReorg(blockNumber, 'storage')) // Staking watcher - const stakingEventsEmitter = getEventsEmitterForService(`${SERVICE_NAME}.${STAKING}`, eth, stakingContract.abi as AbiItem[]) - stakingEventsEmitter.on('newEvent', errorHandler(eventProcessor(services, eth), logger)) + const stakingEventsEmitter = getEventsEmitterForService(`${STAKING}`, eth, stakingContract.abi as AbiItem[]) + stakingEventsEmitter.on('newEvent', errorHandler(eventProcessor(services, eth), stakingLogger)) stakingEventsEmitter.on('error', (e: Error) => { - logger.error(`There was unknown error in Events Emitter! ${e}`) + stakingLogger.error(`There was unknown error in Events Emitter! ${e}`) }) stakingEventsEmitter.on('newConfirmation', (data) => confirmationService.emit('newConfirmation', data)) stakingEventsEmitter.on('invalidConfirmation', (data) => confirmationService.emit('invalidConfirmation', data)) @@ -166,7 +167,7 @@ const storage: CachedService = { const agreementsCount = await Agreement.destroy({ where: {}, truncate: true, cascade: true }) const offersCount = await Offer.destroy({ where: {}, truncate: true, cascade: true }) const stakeCount = await StakeModel.destroy({ where: {}, truncate: true, cascade: true }) - logger.info(`Removed ${priceCount} billing plans entries, ${stakeCount} stakes, ${offersCount} offers and ${agreementsCount} agreements`) + storageLogger.info(`Removed ${priceCount} billing plans entries, ${stakeCount} stakes, ${offersCount} offers and ${agreementsCount} agreements`) const store = getObject() delete store['storage.storageManager.lastFetchedBlockNumber'] diff --git a/test/services/storage/processor.spec.ts b/test/services/storage/processor.spec.ts index e919e00e..1d3c8075 100644 --- a/test/services/storage/processor.spec.ts +++ b/test/services/storage/processor.spec.ts @@ -429,18 +429,7 @@ describe('Storage services: Events Processor', () => { expect(createdStake).to.be.instanceOf(StakeModel) expect(createdStake?.account).to.be.eql(account) expect(createdStake?.token).to.be.eql(token) - expect(stakeServiceEmitSpy).to.have.been.calledWith('created') - }) - it('should not create if existed', async () => { - const total = 1000 - const event = eventMock({ - event: 'Staked', - returnValues: { user: account, total, token, amount: 1000 } - }) - await StakeModel.create({ account, token, total: '0' }) - await processor(event) - - expect(stakeServiceEmitSpy).to.have.not.been.calledWith('created') + expect(stakeServiceEmitSpy).to.have.been.calledWith('updated') }) describe('Staked', () => { it('should update total', async () => {