Skip to content

Commit

Permalink
release btc process update
Browse files Browse the repository at this point in the history
		I've updated the release_btc evento processing on the daemon simplifying the validations
		with the past states of the pegout
  • Loading branch information
ronaldsg20 committed Jul 20, 2023
1 parent 9b80f0b commit 8be37a4
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 53 deletions.
1 change: 1 addition & 0 deletions src/__tests__/unit/services/pegout-data.processor.unit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ describe('Service: PegoutDataProcessor', () => {
getLastByOriginatingRskTxHash: sinon.stub(),
getLastByOriginatingRskTxHashNewest: sinon.stub(),
getAllNotFinishedByBtcRecipientAddress: sinon.stub(),
getPegoutByRecipientAndCreationTx: sinon.stub(),
set: sinon.stub(),
getManyWaitingForConfirmationNewest: sinon.stub(),
getManyWaitingForSignaturesNewest: sinon.stub(),
Expand Down
1 change: 1 addition & 0 deletions src/models/types/bridge-transaction-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export interface ExtendedBridgeEvent extends BridgeEvent{
protocolVersion: string;
senderBtcAddress: string;
releaseRskTxHashes: string;
releaseRskTxHash: string;
};
}
84 changes: 34 additions & 50 deletions src/services/pegout-data.processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ServicesBindings } from '../dependency-injection-bindings';
import * as bitcoin from 'bitcoinjs-lib';
import {BridgeService} from './bridge.service';
import * as constants from '../constants';
import { ensure0x, remove0x } from '../utils/hex-utils';
import {ensure0x, ensureRskHashLength, remove0x} from '../utils/hex-utils';
import { PegoutStatusBuilder } from './pegout-status/pegout-status-builder';
import {ExtendedBridgeEvent} from "../models/types/bridge-transaction-parser";
import { sha256 } from '../utils/sha256-utils';
Expand All @@ -34,7 +34,6 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor {
}

getFilters(): BridgeDataFilterModel[] {
// TODO: add BRIDGE_METHODS.RELEASE_BTC = 'releaseBtc' when this method is available in the bridge abis.
return [
new BridgeDataFilterModel(getBridgeSignature(BRIDGE_METHODS.UPDATE_COLLECTIONS)),
new BridgeDataFilterModel(getBridgeSignature(BRIDGE_METHODS.ADD_SIGNATURE)),
Expand Down Expand Up @@ -131,60 +130,45 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor {
if(network === constants.NETWORK_MAINNET){
btcNetwork = bitcoin.networks.bitcoin;
}

const currentBlockHeight = extendedBridgeTx.blockNumber;
const pegoutMinimumConfirmations = Number(process.env.RSK_PEGOUT_MINIMUM_CONFIRMATIONS);
const batchPegoutCreationTx = releaseBTCEvent.arguments.releaseRskTxHash;

for(let output of parsedBtcTransaction.outs) {
let address = bitcoin.address.fromOutputScript(output.script, btcNetwork);

const dbPegoutsWithThisAddress = await this.pegoutStatusDataService.getAllNotFinishedByBtcRecipientAddress(address);
const address = bitcoin.address.fromOutputScript(output.script, btcNetwork);

if(!dbPegoutsWithThisAddress || dbPegoutsWithThisAddress.length == 0) {
const dbPegout = await this.pegoutStatusDataService.getPegoutByRecipientAndCreationTx(address, batchPegoutCreationTx);
if(!dbPegout || dbPegout.length !== 1 ) {
this.logger.trace(`[processSignedStatusByRtx]: Not found any pegout related to this output ${address} - btachpegoutcreationTx: ${batchPegoutCreationTx}`);
continue;
}

this.logger.trace(`[processSignedStatusByRtx] found a pegout to be released: ${dbPegoutsWithThisAddress.length}`);

const dbPegoutsWithEnoughConfirmations: PegoutStatusDbDataModel[] = dbPegoutsWithThisAddress.filter(dbPegout => {
const blockHeightDiff = currentBlockHeight - dbPegout.rskBlockHeight;
return blockHeightDiff >= pegoutMinimumConfirmations;
});

let index = 0;
for(let oldPegoutStatus of dbPegoutsWithEnoughConfirmations) {
const originatingRskTxHash = oldPegoutStatus.originatingRskTxHash;

this.logger.trace(`[processSignedStatusByRtx] Got a pegout waiting signatures.`);
this.logPegoutData(oldPegoutStatus);

const newPegoutStatus = PegoutStatusDbDataModel.clonePegoutStatusInstance(oldPegoutStatus);
newPegoutStatus.setRskTxInformation(extendedBridgeTx);
newPegoutStatus.btcRawTransaction = rawTx;
newPegoutStatus.btcTxHash = parsedBtcTransaction.getHash().toString('hex');
newPegoutStatus.isNewestStatus = true;
newPegoutStatus.status = PegoutStatus.RELEASE_BTC;
newPegoutStatus.valueInSatoshisToBeReceived = output.value;
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
const [thePegout] = dbPegout;
this.logger.trace(`[processSignedStatusByRtx] found a pegout to be released: ${thePegout.originatingRskTxHash}`);

const originatingRskTxHash = thePegout.originatingRskTxHash;
this.logPegoutData(thePegout);

const newPegoutStatus = PegoutStatusDbDataModel.clonePegoutStatusInstance(thePegout);
newPegoutStatus.setRskTxInformation(extendedBridgeTx);
newPegoutStatus.btcRawTransaction = rawTx;
newPegoutStatus.btcTxHash = parsedBtcTransaction.getHash().toString('hex');
newPegoutStatus.isNewestStatus = true;
newPegoutStatus.status = PegoutStatus.RELEASE_BTC;
newPegoutStatus.valueInSatoshisToBeReceived = output.value;
newPegoutStatus.feeInSatoshisToBePaid = newPegoutStatus.valueRequestedInSatoshis - newPegoutStatus.valueInSatoshisToBeReceived;
newPegoutStatus.btcRawTxInputsHash = this.getInputsHash(parsedBtcTransaction);
newPegoutStatus.rskTxHash = `${extendedBridgeTx.txHash}___${thePegout.batchPegoutIndex}`;

this.logPegoutData(newPegoutStatus);
this.logger.trace(`[processSignedStatusByRtx] PegOut being released
with amount in weis: ${(await this.getTxFromRskTransaction(originatingRskTxHash)).valueInWeis}`);

try {
oldPegoutStatus.isNewestStatus = false;
await this.save(oldPegoutStatus);
await this.save(newPegoutStatus);
} catch(e) {
this.logger.warn('[processSignedStatusByRtx] There was a problem with the storage', e);
}
index++;
try {
thePegout.isNewestStatus = false;
await this.save(thePegout);
await this.save(newPegoutStatus);
} catch(e) {
this.logger.warn('[processSignedStatusByRtx] There was a problem with the storage', e);
}

}

}

private async processBatchPegouts(extendedBridgeTx: ExtendedBridgeTx): Promise<void> {
Expand Down Expand Up @@ -257,13 +241,13 @@ export class PegoutDataProcessor implements FilteredBridgeTransactionProcessor {
): Promise<void> {
try {
const bridgeState = await this.bridgeService.getBridgeState(blockNumber);
const batchedPegout = bridgeState.pegoutsWaitingForConfirmations.find(pegout => pegout.rskTxHash === remove0x(txHash));
const batchedPegout = bridgeState.pegoutsWaitingForConfirmations.find(pegout => ensureRskHashLength(pegout.rskTxHash) === remove0x(txHash));

if(!batchedPegout) {
this.logger.debug(`[addValueInSatoshisToBeReceivedAndFee] did not find the batched pegout in the bridge state pegoutsWaitingForConfirmations. [rsktxhash: ${txHash}][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: ${txHash}][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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export interface PegoutStatusDataService extends GenericDataService<PegoutStatus
getManyByRskTxHashes(originatingRskTxHashes: Array<string>): Promise<PegoutStatusDbDataModel[]>;
getManyByBtcRawTxInputsHashNewest(btcRawTxInputsHash: string): Promise<PegoutStatusDbDataModel[]>;
getAllNotFinishedByBtcRecipientAddress(btcRecipientAddress: string): Promise<PegoutStatusDbDataModel[]>;
getPegoutByRecipientAndCreationTx(btcRecipientAddress: string, batchPegoutRskTxHash: string ): Promise<PegoutStatusDbDataModel[]>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const PegoutStatusSchema = new mongoose.Schema({
rskBlockHash: {type: String, required: true},
btcRawTxInputsHash: {type: String},
batchPegoutIndex: {type: String},
batchPegoutRskTxHash: {type: Number},
batchPegoutRskTxHash: {type: String},
changedByEvent: {type: String},
updatedAt: {type: Date},
});
Expand Down Expand Up @@ -99,13 +99,19 @@ export class PegoutStatusMongoDbDataService extends MongoDbDataService<PegoutSta
}

public async getAllNotFinishedByBtcRecipientAddress(btcRecipientAddress: string): Promise<PegoutStatusDbDataModel[]> {
const isNewestStatus = true;
const pegoutDocuments = await this.getConnector()
.find({status: {$ne: PegoutStatus.RELEASE_BTC}, isNewestStatus, btcRecipientAddress})
.find({status: PegoutStatus.WAITING_FOR_CONFIRMATION, btcRecipientAddress})
.exec();
return pegoutDocuments.map(PegoutStatusDbDataModel.clonePegoutStatusInstance);
}

public async getPegoutByRecipientAndCreationTx(btcRecipientAddress: string, batchPegoutRskTxHash: string ): Promise<PegoutStatusDbDataModel[]> {
const pegoutDocuments = await this.getConnector()
.find({status: PegoutStatus.WAITING_FOR_CONFIRMATION, btcRecipientAddress, batchPegoutRskTxHash})
.exec();
return pegoutDocuments.map(PegoutStatusDbDataModel.clonePegoutStatusInstance);
}

public async getManyWaitingForConfirmationNewest(): Promise<PegoutStatusDbDataModel[]> {
const pegoutsDocuments = await this.getConnector()
.find({status: PegoutStatus.WAITING_FOR_CONFIRMATION, isNewestStatus: true})
Expand Down
11 changes: 11 additions & 0 deletions src/utils/hex-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,14 @@ export const ensure0x = (value: string) => {
export const remove0x = (value: string) => {
return !value.startsWith('0x') ? value : value.substring(2);
}

export const ensureRskHashLength = (hash: string) => {
const length = hash.length;
if(length === 64) {
return hash;
} else if (length === 63) {
return '0' + hash;
} else if (length === 66) {
return remove0x(hash);
}
}

0 comments on commit 8be37a4

Please sign in to comment.