diff --git a/package-lock.json b/package-lock.json index e52f29db..29e1fdbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1241,6 +1241,22 @@ "fast-deep-equal": "^3.1.3" } }, + "@rsksmart/bridge-state-data-parser": { + "version": "git+https://github.com/rsksmart/bridge-state-data-parser.git#5a5df64762f9a1b33e3e994568098ae3e3e1fe58", + "from": "git+https://github.com/rsksmart/bridge-state-data-parser.git#allow-block-argument", + "requires": { + "@rsksmart/rsk-precompiled-abis": "^5.0.0-FINGERROOT", + "ethereumjs-util": "^7.0.10", + "web3": "^1.5.2" + }, + "dependencies": { + "@rsksmart/rsk-precompiled-abis": { + "version": "5.0.0-FINGERROOT", + "resolved": "https://registry.npmjs.org/@rsksmart/rsk-precompiled-abis/-/rsk-precompiled-abis-5.0.0-FINGERROOT.tgz", + "integrity": "sha512-mKaKicuEzyLqQgnWZOBfyjdzMGjdGDqcGWkH4jXK7Edd8u62np0B7GUJLoXjHFDP6G28A/HqROx1tlGoJJcQ4Q==" + } + } + }, "@rsksmart/rsk-precompiled-abis": { "version": "git+https://github.com/rsksmart/precompiled-abis.git#665b79f5bb591e3fd54e267b5f775c6a1b0c9b76", "from": "git+https://github.com/rsksmart/precompiled-abis.git#5.0.0-FINGERROOT" @@ -2758,20 +2774,23 @@ "fill-range": "^7.0.1" } }, - "bridge-state-data-parser": { - "version": "git+https://github.com/rsksmart/bridge-state-data-parser.git#6cff95be09663e2f81bd65f3843dbf01f2765598", - "from": "git+https://github.com/rsksmart/bridge-state-data-parser.git#v1.1.0", - "requires": { - "@rsksmart/rsk-precompiled-abis": "^5.0.0-FINGERROOT", - "ethereumjs-util": "^7.0.10", - "web3": "^1.5.2" - } - }, "bridge-transaction-parser": { "version": "git+https://github.com/rsksmart/bridge-transaction-parser.git#0c21c2c95e357fdbabb3b365805270b156215e4e", "from": "git+https://github.com/rsksmart/bridge-transaction-parser.git#v0.5.0-beta", "requires": { - "@rsksmart/rsk-precompiled-abis": "^5.0.0-FINGERROOT" + "@rsksmart/rsk-precompiled-abis-fingerroot500": "npm:@rsksmart/rsk-precompiled-abis@^5.0.0-FINGERROOT" + }, + "dependencies": { + "@rsksmart/rsk-precompiled-abis": { + "version": "5.0.0-FINGERROOT", + "resolved": "https://registry.npmjs.org/@rsksmart/rsk-precompiled-abis/-/rsk-precompiled-abis-5.0.0-FINGERROOT.tgz", + "integrity": "sha512-mKaKicuEzyLqQgnWZOBfyjdzMGjdGDqcGWkH4jXK7Edd8u62np0B7GUJLoXjHFDP6G28A/HqROx1tlGoJJcQ4Q==" + }, + "@rsksmart/rsk-precompiled-abis-fingerroot500": { + "version": "npm:@rsksmart/rsk-precompiled-abis@5.0.0-FINGERROOT", + "resolved": "https://registry.npmjs.org/@rsksmart/rsk-precompiled-abis/-/rsk-precompiled-abis-5.0.0-FINGERROOT.tgz", + "integrity": "sha512-mKaKicuEzyLqQgnWZOBfyjdzMGjdGDqcGWkH4jXK7Edd8u62np0B7GUJLoXjHFDP6G28A/HqROx1tlGoJJcQ4Q==" + } } }, "brorand": { diff --git a/package.json b/package.json index 454c6f04..81b58899 100644 --- a/package.json +++ b/package.json @@ -59,11 +59,11 @@ "@loopback/rest": "^9.1.1", "@loopback/rest-explorer": "^5.0.9", "@loopback/service-proxy": "^3.0.5", + "@rsksmart/bridge-state-data-parser": "git+https://github.com/rsksmart/bridge-state-data-parser.git#allow-block-argument", "@rsksmart/rsk-precompiled-abis": "git+https://github.com/rsksmart/precompiled-abis.git#5.0.0-FINGERROOT", "@types/mongoose": "^5.11.97", "big.js": "^6.1.1", "bitcoinjs-lib": "^6.0.1", - "bridge-state-data-parser": "https://github.com/rsksmart/bridge-state-data-parser#v1.1.0", "bridge-transaction-parser": "git+https://github.com/rsksmart/bridge-transaction-parser.git#v0.5.0-beta", "dotenv": "^8.6.0", "jssha": "^3.2.0", diff --git a/src/__tests__/unit/services/pegout-data.processor.unit.ts b/src/__tests__/unit/services/pegout-data.processor.unit.ts index 154cb897..ca709a34 100644 --- a/src/__tests__/unit/services/pegout-data.processor.unit.ts +++ b/src/__tests__/unit/services/pegout-data.processor.unit.ts @@ -10,7 +10,7 @@ import {bridge} from '@rsksmart/rsk-precompiled-abis'; import { PegoutStatus, PegoutStatusDbDataModel } from '../../../models/rsk/pegout-status-data-model'; import { BridgeService } from '../../../services'; import * as constants from '../../../constants'; -import { BridgeState } from 'bridge-state-data-parser'; +import { BridgeState } from '@rsksmart/bridge-state-data-parser'; import { ExtendedBridgeEvent } from '../../../models/types/bridge-transaction-parser'; import { remove0x, ensure0x } from '../../../utils/hex-utils'; @@ -680,7 +680,7 @@ describe('Service: PegoutDataProcessor', () => { it('handles BATCH_PEGOUT_CREATED status', async () => { sandbox.stub(process.env, 'NETWORK').value(constants.NETWORK_MAINNET); - const mockedPegoutStatusDataService:PegoutStatusDataService = + const mockedPegoutStatusDataService:PegoutStatusDataService = { deleteByRskBlockHeight: sinon.stub(), getManyByOriginatingRskTxHash: sinon.stub(), @@ -698,7 +698,7 @@ describe('Service: PegoutDataProcessor', () => { start: sinon.stub(), stop: sinon.stub() }; - + const mockedBridgeService = sinon.createStubInstance(BridgeService) as SinonStubbedInstance & BridgeService; const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); const createdOn = new Date(); @@ -759,7 +759,7 @@ describe('Service: PegoutDataProcessor', () => { let allPegoutTxs = remove0x(batchPegoutsEvent!.arguments.releaseRskTxHashes); let totalHashes = allPegoutTxs.length / 64; - + expect(totalHashes).equal(9); let eventData = ''; @@ -813,7 +813,7 @@ describe('Service: PegoutDataProcessor', () => { it('returns same valueInSatoshisToBeReceived when did not find pegout in pegoutsWaitingForConfirmations', async () => { const mockedPegoutStatusDataService = sinon.createStubInstance(PegoutStatusMongoDbDataService) as SinonStubbedInstance; const mockedBridgeService = sinon.createStubInstance(BridgeService) as SinonStubbedInstance & BridgeService; - const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); + const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); const mockedPegoutStatus = new PegoutStatusDbDataModel(); mockedPegoutStatus.originatingRskTxHash = rskTxHash; mockedPegoutStatus.valueInSatoshisToBeReceived = 1000; @@ -821,11 +821,11 @@ describe('Service: PegoutDataProcessor', () => { await thisService['addValueInSatoshisToBeReceivedAndFee'](mockedPegoutStatus); expect(mockedPegoutStatus.valueInSatoshisToBeReceived).equal(1000); }) - + it('returns same valueInSatoshisToBeReceived when found a pegout but did not find an output containing the btcRecipientAddress', async () => { const mockedPegoutStatusDataService = sinon.createStubInstance(PegoutStatusMongoDbDataService) as SinonStubbedInstance; const mockedBridgeService = sinon.createStubInstance(BridgeService) as SinonStubbedInstance & BridgeService; - const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); + const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); const mockedPegoutStatus = new PegoutStatusDbDataModel(); mockedPegoutStatus.originatingRskTxHash = '0x5628682b56ef179e066fd12ee25a84436def371b0a11b45cf1d8308ed06f4698'; mockedPegoutStatus.valueInSatoshisToBeReceived = 1000; @@ -837,10 +837,10 @@ describe('Service: PegoutDataProcessor', () => { it('returns calculated valueInSatoshisToBeReceived when found pegout in pegoutsWaitingForConfirmations', async () => { const mockedPegoutStatusDataService = sinon.createStubInstance(PegoutStatusMongoDbDataService) as SinonStubbedInstance; const mockedBridgeService = sinon.createStubInstance(BridgeService) as SinonStubbedInstance & BridgeService; - const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); + const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); const mockedPegoutStatus = new PegoutStatusDbDataModel(); mockedPegoutStatus.originatingRskTxHash = '0x5628682b56ef179e066fd12ee25a84436def371b0a11b45cf1d8308ed06f4698'; - mockedPegoutStatus.btcRawTransaction = btcRawTx2; + mockedPegoutStatus.btcRawTransaction = btcRawTx2; mockedPegoutStatus.btcRecipientAddress = 'mpKPLWXnmqjtXyoqi5yRBYgmF4PswMGj55'; // output address with value 337100 from raw tx mockedBridgeService.getBridgeState.resolves(bridgeState); await thisService['addValueInSatoshisToBeReceivedAndFee'](mockedPegoutStatus); @@ -850,7 +850,7 @@ describe('Service: PegoutDataProcessor', () => { it('processIndividualPegout', async () => { const mockedPegoutStatusDataService = sinon.createStubInstance(PegoutStatusMongoDbDataService) as SinonStubbedInstance; const mockedBridgeService = sinon.createStubInstance(BridgeService) as SinonStubbedInstance & BridgeService; - const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); + const thisService = new PegoutDataProcessor(mockedPegoutStatusDataService, mockedBridgeService); const extendedBridgeTx: ExtendedBridgeTx = { txHash: "0x6843cfeaafe38e1044ec5638877ff766015b44887d32c7aef7daec84aa3af7c5", @@ -901,7 +901,7 @@ describe('Service: PegoutDataProcessor', () => { expect(hasEvent).true; expect(releaseRequestedEvent).not.null; - + await thisService['processIndividualPegout'](extendedBridgeTx); sinon.assert.calledTwice(mockedPegoutStatusDataService.set); }) diff --git a/src/services/bridge.service.ts b/src/services/bridge.service.ts index 20336e88..0f3a178f 100644 --- a/src/services/bridge.service.ts +++ b/src/services/bridge.service.ts @@ -3,7 +3,7 @@ import {getLogger, Logger} from 'log4js'; import Web3 from 'web3'; import {Contract} from 'web3-eth-contract'; import bridgeTransactionParser, {Transaction} from 'bridge-transaction-parser'; -import { getBridgeState, BridgeState} from 'bridge-state-data-parser'; +import { getBridgeState, BridgeState } from '@rsksmart/bridge-state-data-parser'; export class BridgeService { private bridgeContract: Contract; @@ -112,8 +112,8 @@ export class BridgeService { return await bridgeTransactionParser.getBridgeTransactionByTxHash(this.web3, txHash); } - public async getBridgeState(): Promise { - return await getBridgeState(this.web3); + public async getBridgeState(defaultBlock: string | number = 'latest'): Promise { + return await getBridgeState(this.web3, defaultBlock); } } diff --git a/src/services/pegout-data.processor.ts b/src/services/pegout-data.processor.ts index 4f4c58b5..896b8ced 100644 --- a/src/services/pegout-data.processor.ts +++ b/src/services/pegout-data.processor.ts @@ -157,7 +157,7 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor { this.logger.trace(`[processSignedStatusByRtx] Got a pegout waiting signatures.`); this.logPegoutData(oldPegoutStatus); - + const newPegoutStatus = PegoutStatusDbDataModel.clonePegoutStatusInstance(oldPegoutStatus); newPegoutStatus.setRskTxInformation(extendedBridgeTx); newPegoutStatus.btcRawTransaction = rawTx; @@ -168,7 +168,7 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor { newPegoutStatus.feeInSatoshisToBePaid = newPegoutStatus.valueRequestedInSatoshis - newPegoutStatus.valueInSatoshisToBeReceived; newPegoutStatus.btcRawTxInputsHash = this.getInputsHash(parsedBtcTransaction); newPegoutStatus.rskTxHash = `${extendedBridgeTx.txHash}___${index}`; - + this.logPegoutData(newPegoutStatus); this.logger.trace(`[processSignedStatusByRtx] PegOut being released with amount in weis: ${(await this.getTxFromRskTransaction(originatingRskTxHash)).valueInWeis}`); @@ -233,8 +233,8 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor { this.logPegoutData(newClonedPegoutStatus); this.logger.trace(`[processBatchPegouts] PegOut waiting for confirmations with amount in weis: ${(await this.getTxFromRskTransaction(originatingRskTxHash)).valueInWeis}`); - - await this.addBatchValueInSatoshisToBeReceivedAndFee(newClonedPegoutStatus, extendedBridgeTx.txHash); + + await this.addBatchValueInSatoshisToBeReceivedAndFee(newClonedPegoutStatus, extendedBridgeTx.txHash, extendedBridgeTx.blockNumber); try { // Update previous status as outdated @@ -251,16 +251,19 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor { } - private async addBatchValueInSatoshisToBeReceivedAndFee(pegoutStatus: PegoutStatusDbDataModel, rskTxHash: string): Promise { + private async addBatchValueInSatoshisToBeReceivedAndFee( + pegoutStatus: PegoutStatusDbDataModel, + txHash: string, blockNumber: number, + ): Promise { try { - const bridgeState = await this.bridgeService.getBridgeState(); - const batchedPegout = bridgeState.pegoutsWaitingForConfirmations.find(pegout => pegout.rskTxHash === rskTxHash); + const bridgeState = await this.bridgeService.getBridgeState(blockNumber); + const batchedPegout = bridgeState.pegoutsWaitingForConfirmations.find(pegout => pegout.rskTxHash === remove0x(txHash)); if(!batchedPegout) { - this.logger.debug(`[addValueInSatoshisToBeReceivedAndFee] did not find the batched pegout in the bridge state pegoutsWaitingForConfirmations. [rsktxhash: ${rskTxHash}][originatingRskTxHash:${pegoutStatus.originatingRskTxHash}]`); + this.logger.debug(`[addValueInSatoshisToBeReceivedAndFee] did not find the batched pegout in the bridge state pegoutsWaitingForConfirmations. [rsktxhash: ${txHash}][originatingRskTxHash:${pegoutStatus.originatingRskTxHash}]`); return; } - this.logger.debug(`[addValueInSatoshisToBeReceivedAndFee] Got the batched pegout in the bridge state pegoutsWaitingForConfirmations. [rsktxhash: ${rskTxHash}][originatingRskTxHash:${pegoutStatus.originatingRskTxHash}]`); + this.logger.debug(`[addValueInSatoshisToBeReceivedAndFee] Got the batched pegout in the bridge state pegoutsWaitingForConfirmations. [rsktxhash: ${txHash}][originatingRskTxHash:${pegoutStatus.originatingRskTxHash}]`); const parsedBtcTransaction = bitcoin.Transaction.fromHex(batchedPegout.btcRawTx);