Skip to content

Commit

Permalink
- Add pegout transaction created event assertions for rejected pegin …
Browse files Browse the repository at this point in the history
…test cases

- Moved logic to decode and encode utxo outpoint values to a util function.
- Moved pegout event names to a constant file.
  • Loading branch information
nathanieliov committed Jun 11, 2024
1 parent 13ea2e4 commit ce80157
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 26 deletions.
1 change: 1 addition & 0 deletions lib/2wp-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ const disableWhitelisting = async (rskTxHelper, btcTxHelper, blockDelay = 1) =>
module.exports = {
sendTxToBridge,
assertRefundUtxosSameAsPeginUtxos,
findPegoutCreatedEventAndAssertRefundUtxo,
createPegoutRequest,
sendPegin,
ensurePeginIsRegistered,
Expand Down
10 changes: 10 additions & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,15 @@ const PEGIN_REJECTION_REASONS = {
PEGIN_V1_INVALID_PAYLOAD_REASON: '4'
};

const PEGOUT_EVENTS = {
RELEASE_REQUEST_RECEIVED: "release_request_received",
RELEASE_REQUEST_REJECTED: "release_request_rejected",
RELEASE_REQUESTED: "release_requested",
BATCH_PEGOUT_CREATED: "batch_pegout_created",
PEGOUT_TRANSACTION_CREATED: "pegout_transaction_created",
PEGOUT_CONFIRMED: "pegout_confirmed"
}

module.exports = {
KEY_TYPE_BTC,
KEY_TYPE_RSK,
Expand All @@ -63,4 +72,5 @@ module.exports = {
GENESIS_FEDERATION_REDEEM_SCRIPT,
FEDERATION_ACTIVATION_AGE,
PEGIN_REJECTION_REASONS,
PEGOUT_EVENTS
};
30 changes: 11 additions & 19 deletions lib/tests/2wp.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ const { getDerivedRSKAddressInformation } = require('@rsksmart/btc-rsk-derivatio
const btcEthUnitConverter = require('@rsksmart/btc-eth-unit-converter');
const { sendTxToBridge, sendPegin, ensurePeginIsRegistered, donateToBridge } = require('../2wp-utils');
const { waitAndUpdateBridge } = require('../rsk-utils');
const {VarInt} = require("../varint");
const { decodeOutpointValues, encodeOutpointValuesAsMap } = require("../varint");
const {getBridgeState} = require("@rsksmart/bridge-state-data-parser");
const {PEGOUT_EVENTS} = require("../constants");

const DONATION_AMOUNT = 250;
const REJECTED_REASON = 1;
Expand Down Expand Up @@ -153,7 +154,7 @@ const execute = (description, getRskHost) => {

const isIris300AlreadyActive = await Runners.common.forks.iris300.isAlreadyActive();
if (isIris300AlreadyActive) {
const pegoutRequestReceivedEvent = await rskUtils.findEventInBlock(rskTxHelper, 'release_request_received');
const pegoutRequestReceivedEvent = await rskUtils.findEventInBlock(rskTxHelper, PEGOUT_EVENTS.RELEASE_REQUEST_RECEIVED);
expect(pegoutRequestReceivedEvent).to.not.be.null;
const btcDestinationAddress = pegoutRequestReceivedEvent.arguments.btcDestinationAddress;
expect(pegoutRequestReceivedEvent.arguments.sender.toLowerCase()).to.equal(ensure0x(recipientRskAddressInfo.address));
Expand All @@ -169,43 +170,34 @@ const execute = (description, getRskHost) => {
const pegoutCreatedValidations = async (localRskTxHelper) => {
const isPapyrus200AlreadyActive = await Runners.common.forks.papyrus200.isAlreadyActive();
if (isPapyrus200AlreadyActive) {
const pegoutRequestedEvent = await rskUtils.findEventInBlock(localRskTxHelper, 'release_requested');
const pegoutRequestedEvent = await rskUtils.findEventInBlock(localRskTxHelper, PEGOUT_EVENTS.RELEASE_REQUESTED);
expect(pegoutRequestedEvent).to.not.be.null;
expect(Number(pegoutRequestedEvent.arguments.amount)).to.equal(pegoutValueInSatoshis);
}
const isHop400AlreadyActive = await Runners.common.forks.hop400.isAlreadyActive();
if (isHop400AlreadyActive) {
const batchPegoutCreatedEvent = await rskUtils.findEventInBlock(localRskTxHelper, 'batch_pegout_created');
const batchPegoutCreatedEvent = await rskUtils.findEventInBlock(localRskTxHelper, PEGOUT_EVENTS.BATCH_PEGOUT_CREATED);
expect(batchPegoutCreatedEvent).to.not.be.null;
expect(batchPegoutCreatedEvent.arguments.releaseRskTxHashes.includes(pegoutTransaction.transactionHash)).to.be.true;
}

const isLovell700AlreadyActive = await Runners.common.forks.lovell700.isAlreadyActive();
if (isLovell700AlreadyActive) {
const pegoutTransactionCreatedEvent = await rskUtils.findEventInBlock(localRskTxHelper, 'pegout_transaction_created');
const pegoutTransactionCreatedEvent = await rskUtils.findEventInBlock(localRskTxHelper, PEGOUT_EVENTS.PEGOUT_TRANSACTION_CREATED);
expect(pegoutTransactionCreatedEvent).to.not.be.null;
const encodedUtxoOutpointValues = Buffer.from(removePrefix0x(pegoutTransactionCreatedEvent.arguments.utxoOutpointValues), 'hex');

const federationUtxoValues = activeFederationUtxosBeforePegout.reduce((map, utxo) => {
map[utxo.valueInSatoshis] = Buffer.from(new VarInt(utxo.valueInSatoshis).encode()).toString("hex");
return map;
}, {});
const federationUtxoValues = encodeOutpointValuesAsMap(activeFederationUtxosBeforePegout);

let offset = 0;
let idx = 0;
while (encodedUtxoOutpointValues.length > offset) {
let utxoOutpointValue = new VarInt(encodedUtxoOutpointValues, offset);
expect(utxoOutpointValue.value in federationUtxoValues).to.be.true
const outpointValues = decodeOutpointValues(encodedUtxoOutpointValues);

offset += utxoOutpointValue.getSizeInBytes();
idx++;
}
expect(outpointValues.every(value => value in federationUtxoValues)).to.be.true;
}
};

const pegoutConfirmedValidations = async (localRskTxHelper) => {
if (isFingerroot500AlreadyActive) {
const pegoutConfirmedEvent = await rskUtils.findEventInBlock(localRskTxHelper, 'pegout_confirmed');
const pegoutConfirmedEvent = await rskUtils.findEventInBlock(localRskTxHelper, PEGOUT_EVENTS.PEGOUT_CONFIRMED);
expect(pegoutConfirmedEvent).to.not.be.null;
}
};
Expand Down Expand Up @@ -243,7 +235,7 @@ const execute = (description, getRskHost) => {
const pegoutTransaction = await sendTxToBridge(rskTxHelper, PEGOUT_UNDER_MINIMUM_VALUE_IN_BTC, recipientRskAddressInfo.address);
const isIris300AlreadyActive = await Runners.common.forks.iris300.isAlreadyActive();
if (isIris300AlreadyActive) {
const pegoutRejectedEvent = await rskUtils.findEventInBlock(rskTxHelper, 'release_request_rejected');
const pegoutRejectedEvent = await rskUtils.findEventInBlock(rskTxHelper, PEGOUT_EVENTS.RELEASE_REQUEST_REJECTED);
expect(pegoutRejectedEvent).to.not.be.null;
const pegoutValueInSatoshis = Number(btcEthUnitConverter.btcToSatoshis(PEGOUT_UNDER_MINIMUM_VALUE_IN_BTC));
expect(Number(pegoutRejectedEvent.arguments.amount)).to.equal(pegoutValueInSatoshis);
Expand Down
23 changes: 22 additions & 1 deletion lib/varint.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,25 @@ class VarInt {
}
}

module.exports = { VarInt };
const decodeOutpointValues = (encodedUtxoOutpointValues) => {
let offset = 0;
let idx = 0;
const outpointValues = [];
while (encodedUtxoOutpointValues.length > offset) {
let utxoOutpointValue = new VarInt(encodedUtxoOutpointValues, offset);
outpointValues.push(utxoOutpointValue.value);
offset += utxoOutpointValue.getSizeInBytes();
idx++;
}
return outpointValues;
}

const encodeOutpointValuesAsMap = (utxos) => {
const encodeOutpointValues = utxos.reduce((map, utxo) => {
map[utxo.valueInSatoshis] = Buffer.from(new VarInt(utxo.valueInSatoshis).encode()).toString("hex");
return map;
}, {});
return encodeOutpointValues;
}

module.exports = { VarInt, decodeOutpointValues, encodeOutpointValuesAsMap };
44 changes: 38 additions & 6 deletions tests/02_00_05-2wp_version1.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
const { expect } = require('chai');
const peginVerifier = require('pegin-address-verificator');
const rskUtils = require('../lib/rsk-utils');
const { sendPegin, ensurePeginIsRegistered, assertRefundUtxosSameAsPeginUtxos } = require('../lib/2wp-utils');
const { sendPegin, ensurePeginIsRegistered, assertRefundUtxosSameAsPeginUtxos,
findPegoutCreatedEventAndAssertRefundUtxo
} = require('../lib/2wp-utils');
const { getBtcClient } = require('../lib/btc-client-provider');
const { getRskTransactionHelpers } = require('../lib/rsk-tx-helper-provider');
const { getDerivedRSKAddressInformation } = require('@rsksmart/btc-rsk-derivation');
const btcEthUnitConverter = require('@rsksmart/btc-eth-unit-converter');
const { ensure0x } = require('../lib/utils');
const { ensure0x, removePrefix0x} = require('../lib/utils');
const {
PEGIN_REJECTION_REASONS: { PEGIN_V1_INVALID_PAYLOAD_REASON }
} = require('../lib/constants');
PEGIN_REJECTION_REASONS: { PEGIN_V1_INVALID_PAYLOAD_REASON }, PEGOUT_EVENTS
} = require('../lib/constants');
const {encodeOutpointValuesAsMap, decodeOutpointValues} = require("../lib/varint");

const AMOUNT_TO_LOCK_IN_BTC = 2;

Expand Down Expand Up @@ -163,6 +166,8 @@ describe('Lock funds using peg-in protocol version 1', () => {
expect(rejectedPeginEvent.arguments.btcTxHash).to.equal(peginBtcTxHashWith0xPrefix);
expect(rejectedPeginEvent.arguments.reason).to.equal(PEGIN_V1_INVALID_PAYLOAD_REASON);

const amountSentInSatoshis = Number(btcEthUnitConverter.btcToSatoshis(AMOUNT_TO_LOCK_IN_BTC));
await findPegoutCreatedEventAndAssertRefundUtxo(rskTxHelper, btcTxHelper, senderAddressInformation.address, searchRejectedPeginEventFromBlock, latestBlock, amountSentInSatoshis);
});

it('should lock with multiple OP_RETURN outputs but only one for RSK', async () => {
Expand Down Expand Up @@ -239,6 +244,8 @@ describe('Lock funds using peg-in protocol version 1', () => {
expect(rejectedPeginEvent.arguments.btcTxHash).to.equal(peginBtcTxHashWith0xPrefix);
expect(rejectedPeginEvent.arguments.reason).to.equal(PEGIN_V1_INVALID_PAYLOAD_REASON);

const amountSentInSatoshis = Number(btcEthUnitConverter.btcToSatoshis(AMOUNT_TO_LOCK_IN_BTC));
await findPegoutCreatedEventAndAssertRefundUtxo(rskTxHelper, btcTxHelper, peginBtcTxHash, senderAddressInformation.address, searchRejectedPeginEventFromBlock, latestBlock, amountSentInSatoshis);
});

it('should refund lock with OP_RETURN output for RSK with invalid version number', async () => {
Expand Down Expand Up @@ -266,7 +273,33 @@ describe('Lock funds using peg-in protocol version 1', () => {

// Execute peg-in
const peginBtcTxHash = await sendPegin(rskTxHelper, btcTxHelper, senderAddressInformation, AMOUNT_TO_LOCK_IN_BTC, data);
await rskUtils.triggerRelease(rskTxHelpers, btcTxHelper);

const amountSentInSatoshis = Number(btcEthUnitConverter.btcToSatoshis(AMOUNT_TO_LOCK_IN_BTC));
const pegoutCreatedValidations = async (localRskTxHelper) => {
const isPapyrus200AlreadyActive = await Runners.common.forks.papyrus200.isAlreadyActive();
if (isPapyrus200AlreadyActive) {
const pegoutRequestedEvent = await rskUtils.findEventInBlock(localRskTxHelper, PEGOUT_EVENTS.RELEASE_REQUESTED);
expect(pegoutRequestedEvent).to.not.be.null;
}

const isLovell700AlreadyActive = await Runners.common.forks.lovell700.isAlreadyActive();
if (isLovell700AlreadyActive) {
const pegoutTransactionCreatedEvent = await rskUtils.findEventInBlock(localRskTxHelper, PEGOUT_EVENTS.PEGOUT_TRANSACTION_CREATED);
expect(pegoutTransactionCreatedEvent).to.not.be.null;
const encodedUtxoOutpointValues = Buffer.from(removePrefix0x(pegoutTransactionCreatedEvent.arguments.utxoOutpointValues), 'hex');

const federationUtxoValues = encodeOutpointValuesAsMap({"valueInSatoshis": amountSentInSatoshis});
const outpointValues = decodeOutpointValues(encodedUtxoOutpointValues);

expect(outpointValues.every(value => value in federationUtxoValues)).to.be.true;
}
};

const callbacks = {
pegoutCreatedCallback: pegoutCreatedValidations
};

await rskUtils.triggerRelease(rskTxHelpers, btcTxHelper, callbacks);

// Assert
const finalSenderBalance = await btcTxHelper.getAddressBalance(senderAddressInformation.address);
Expand All @@ -292,6 +325,5 @@ describe('Lock funds using peg-in protocol version 1', () => {
expect(rejectedPeginEvent).to.not.be.null;
expect(rejectedPeginEvent.arguments.btcTxHash).to.equal(peginBtcTxHashWith0xPrefix);
expect(rejectedPeginEvent.arguments.reason).to.equal(PEGIN_V1_INVALID_PAYLOAD_REASON);

});
});

0 comments on commit ce80157

Please sign in to comment.