Skip to content

Commit

Permalink
Updates test to use the new get2wpBalances function
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy-then committed Sep 30, 2024
1 parent 099f712 commit 1a99856
Showing 1 changed file with 62 additions and 62 deletions.
124 changes: 62 additions & 62 deletions lib/tests/2wp.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ const expect = require('chai').expect;
const BN = require('bn.js');
const { getBridge } = require('../precompiled-abi-forks-util');
const { getBtcClient } = require('../btc-client-provider');
const { getRskTransactionHelper } = require('../rsk-tx-helper-provider');
const { getRskTransactionHelper, getRskTransactionHelpers } = require('../rsk-tx-helper-provider');
const { satoshisToBtc, btcToSatoshis, satoshisToWeis } = require('@rsksmart/btc-eth-unit-converter');
const { findEventInBlock } = require('../rsk-utils');
const { PEGIN_EVENTS } = require("../constants");
const { findEventInBlock, triggerRelease } = require('../rsk-utils');
const { PEGIN_EVENTS, PEGIN_REJECTION_REASONS } = require("../constants");
const { sendPegin,
ensurePeginIsRegistered,
createSenderRecipientInfo,
createExpectedPeginBtcEvent,
get2wpBalances,
mineForPeginRegistration,
createExpectedRejectedPeginEvent,
} = require('../2wp-utils');
const { getBtcAddressBalanceInSatoshis, waitForBitcoinMempoolToGetTxs } = require('../btc-utils');
const { ensure0x } = require('../utils');
Expand All @@ -20,6 +21,7 @@ const { createPeginV1TxData } = require('pegin-address-verificator');

let btcTxHelper;
let rskTxHelper;
let rskTxHelpers;
let bridge;
let federationAddress;
let minimumPeginValueInSatoshis;
Expand All @@ -33,6 +35,7 @@ const execute = (description, getRskHost) => {

btcTxHelper = getBtcClient();
rskTxHelper = getRskTransactionHelper(getRskHost());
rskTxHelpers = getRskTransactionHelpers();
bridge = getBridge(rskTxHelper.getClient());

federationAddress = await bridge.methods.getFederationAddress().call();
Expand Down Expand Up @@ -286,81 +289,45 @@ const execute = (description, getRskHost) => {

});

it('should do legacy pegin with multiple inputs from different accounts and one output to the federation with value exactly minimum', async () => {
it('should reject a legacy pegin with the value exactly below minimum', async () => {

// Arrange

const initial2wpBalances = await get2wpBalances(rskTxHelper, btcTxHelper);
const initialFederationAddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, federationAddress);
const sender1RecipientInfo = await createSenderRecipientInfo(rskTxHelper, btcTxHelper);
const sender2RecipientInfo = await createSenderRecipientInfo(rskTxHelper, btcTxHelper);
const initialSender1AddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, sender1RecipientInfo.btcSenderAddressInfo.address);
const initialSender2AddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, sender2RecipientInfo.btcSenderAddressInfo.address);

const sender1PeginValueInSatoshis = minimumPeginValueInSatoshis;
const sender2PeginValueInSatoshis = minimumPeginValueInSatoshis;
const peginValueInSatoshis = sender1PeginValueInSatoshis + sender2PeginValueInSatoshis;

const sender1UtxosInfo = await getSenderUtxosInfo(sender1RecipientInfo, satoshisToBtc(sender1PeginValueInSatoshis));
const sender2UtxosInfo = await getSenderUtxosInfo(sender2RecipientInfo, satoshisToBtc(sender2PeginValueInSatoshis));

const sender1ChangeInSatoshis = btcToSatoshis(sender1UtxosInfo.change);
const sender2ChangeInSatoshis = btcToSatoshis(sender2UtxosInfo.change);

const tx = new bitcoinJsLib.Transaction();

// Adding inputs
addInputs(tx, sender1UtxosInfo);
addInputs(tx, sender2UtxosInfo);

// Adding output to federation
addOutputToFed(tx, peginValueInSatoshis);

// Adding change outputs
addChangeOutputs(tx, sender1RecipientInfo.btcSenderAddressInfo.address, sender1ChangeInSatoshis);
addChangeOutputs(tx, sender2RecipientInfo.btcSenderAddressInfo.address, sender2ChangeInSatoshis);

// Signing the transaction
const sender1PrivateKey = sender1RecipientInfo.btcSenderAddressInfo.privateKey;
const sender2PrivateKey = sender2RecipientInfo.btcSenderAddressInfo.privateKey;
const sendersPrivateKeys = [sender1PrivateKey, sender2PrivateKey];
const signedTx = await btcTxHelper.nodeClient.signTransaction(tx.toHex(), [], sendersPrivateKeys);
const senderRecipientInfo = await createSenderRecipientInfo(rskTxHelper, btcTxHelper);
const initialSenderAddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo.btcSenderAddressInfo.address);
// The minimum pegin value minus 1 satoshis
const peginValueInSatoshis = minimumPeginValueInSatoshis - 1;

// Act

// Sending the pegin and ensuring the pegin is registered
const btcPeginTxHash = await btcTxHelper.nodeClient.sendTransaction(signedTx);
await pushPegin(btcPeginTxHash);
const blockNumberBeforePegin = await rskTxHelper.getBlockNumber();

const btcPeginTxHash = await sendPegin(rskTxHelper, btcTxHelper, senderRecipientInfo.btcSenderAddressInfo, satoshisToBtc(peginValueInSatoshis));
// Funds of a pegin with value below minimum are lost. But calling triggerRelease here to ensure that nothing will be refunded.
await triggerRelease(rskTxHelpers, btcTxHelper);

// Assert

const isBtcTxHashAlreadyProcessed = await bridge.methods.isBtcTxHashAlreadyProcessed(btcPeginTxHash).call();
expect(isBtcTxHashAlreadyProcessed).to.be.true;
// The btc pegin tx is not marked as processed by the bridge
await assertPeginTxHashNotProcessed(btcPeginTxHash);

// The expected pegin_btc event should be emitted with the expected values
const recipient1RskAddressChecksumed = rskTxHelper.getClient().utils.toChecksumAddress(ensure0x(sender1RecipientInfo.rskRecipientRskAddressInfo.address));
const expectedEvent = createExpectedPeginBtcEvent(PEGIN_EVENTS.PEGIN_BTC, recipient1RskAddressChecksumed, btcPeginTxHash, peginValueInSatoshis);
const btcTxHashProcessedHeight = Number(await bridge.methods.getBtcTxHashProcessedHeight(btcPeginTxHash).call());
const peginBtcEvent = await findEventInBlock(rskTxHelper, expectedEvent.name, btcTxHashProcessedHeight);
expect(peginBtcEvent).to.be.deep.equal(expectedEvent);
await assert2wpBalancesPeginRejectedBelowMinimum(initial2wpBalances, peginValueInSatoshis);

// The federation address should have received the total amount sent by the senders
await assertExpectedRejectedPeginEventIsEmitted(btcPeginTxHash, blockNumberBeforePegin, PEGIN_REJECTION_REASONS.INVALID_AMOUNT);

// The federation balance is increased by the pegin value
const finalFederationAddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, federationAddress);
expect(finalFederationAddressBalanceInSatoshis).to.be.equal(initialFederationAddressBalanceInSatoshis + peginValueInSatoshis);

// The senders should have their balances reduced by the amount sent to the federation and the fee
const finalSender1AddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, sender1RecipientInfo.btcSenderAddressInfo.address);
expect(finalSender1AddressBalanceInSatoshis).to.be.equal(initialSender1AddressBalanceInSatoshis - sender1PeginValueInSatoshis - btcFeeInSatoshis);

const finalSender2AddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, sender2RecipientInfo.btcSenderAddressInfo.address);
expect(finalSender2AddressBalanceInSatoshis).to.be.equal(initialSender2AddressBalanceInSatoshis - sender2PeginValueInSatoshis - btcFeeInSatoshis);

// Only the first sender should have the total amount in rsk since in legacy pegins the rsk address is derived from the first input.
const finalRskRecipient1Balance = Number(await rskTxHelper.getBalance(sender1RecipientInfo.rskRecipientRskAddressInfo.address));
expect(finalRskRecipient1Balance).to.be.equal(Number(satoshisToWeis(peginValueInSatoshis)));
// The sender address balance is decreased by the pegin value and the btc fee
const finalSenderAddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo.btcSenderAddressInfo.address);
expect(finalSenderAddressBalanceInSatoshis).to.be.equal(initialSenderAddressBalanceInSatoshis - peginValueInSatoshis - btcFeeInSatoshis);

// Other senders should have 0 balance in rsk.
const finalRskRecipient2Balance = Number(await rskTxHelper.getBalance(sender2RecipientInfo.rskRecipientRskAddressInfo.address));
expect(finalRskRecipient2Balance).to.be.equal(0);
// The recipient rsk address balance is zero
const finalRskRecipientBalance = Number(await rskTxHelper.getBalance(senderRecipientInfo.rskRecipientRskAddressInfo.address));
expect(finalRskRecipientBalance).to.be.equal(0);

});

Expand All @@ -376,6 +343,13 @@ const assertExpectedPeginBtcEventIsEmitted = async (btcPeginTxHash, rskRecipient
expect(peginBtcEvent).to.be.deep.equal(expectedEvent);
};

const assertExpectedRejectedPeginEventIsEmitted = async (btcPeginTxHash, blockNumberBeforePegin, rejectionReason) => {
const expectedEvent = createExpectedRejectedPeginEvent(PEGIN_EVENTS.REJECTED_PEGIN, btcPeginTxHash, rejectionReason);
const currentBlockNumber = await rskTxHelper.getBlockNumber();
const rejectedPeginEvent = await findEventInBlock(rskTxHelper, expectedEvent.name, blockNumberBeforePegin, currentBlockNumber);
expect(rejectedPeginEvent).to.be.deep.equal(expectedEvent);
};

/**
* Gets the final 2wp balances (Federation, Bridge utxos and bridge rsk balances) and compares them to the `initial2wpBalances` to assert the expected values based on a successful pegin.
* Checks that after a successful pegin, the federation and Bridge utxos balances are increased and the Bridge rsk balance is decreased, by the `peginValueInSatoshis` amount.
Expand All @@ -396,6 +370,25 @@ const assert2wpBalancesAfterSuccessfulPegin = async (initial2wpBalances, peginVa

};

/**
* Gets the final 2wp balances (Federation, Bridge utxos and bridge rsk balances) and compares them to the `initial2wpBalances` to assert the expected values based on a rejected pegin due to low amount.
* Checks that after a rejected pegin because of a low amount (below minimum), the federation balance is increased by the peginValueInSatoshis amount, because the funds will not be refunded, while the Bridge utxos and Bridge rsk balances stay intact.
* @param {{federationAddressBalanceInSatoshis: number, bridgeUtxosBalanceInSatoshis: number, bridgeBalanceInWeisBN: BN}} initial2wpBalances
* @param {number} peginValueInSatoshis the value of the pegin in satoshis by which only the federation balance is to be increased.
* @returns {Promise<void>}
*/
const assert2wpBalancesPeginRejectedBelowMinimum = async (initial2wpBalances, peginValueInSatoshis) => {

const final2wpBalances = await get2wpBalances(rskTxHelper, btcTxHelper);

expect(final2wpBalances.federationAddressBalanceInSatoshis).to.be.equal(initial2wpBalances.federationAddressBalanceInSatoshis + peginValueInSatoshis);

expect(final2wpBalances.bridgeUtxosBalanceInSatoshis).to.be.equal(initial2wpBalances.bridgeUtxosBalanceInSatoshis);

expect(final2wpBalances.bridgeBalanceInWeisBN.eq(initial2wpBalances.bridgeBalanceInWeisBN)).to.be.true;

};

const addInputs = (tx, utxos) => {
utxos.forEach(utxo => {
tx.addInput(Buffer.from(utxo.txid, 'hex').reverse(), utxo.vout);
Expand All @@ -417,6 +410,13 @@ const addOutput = (tx, address, outputValueInSatoshis) => {
}
};

const assertPeginTxHashNotProcessed = async (btcPeginTxHash) => {
const isBtcTxHashAlreadyProcessed = await bridge.methods.isBtcTxHashAlreadyProcessed(btcPeginTxHash).call();
expect(isBtcTxHashAlreadyProcessed).to.be.false;
const btcTxHashProcessedHeight = Number(await bridge.methods.getBtcTxHashProcessedHeight(btcPeginTxHash).call());
expect(btcTxHashProcessedHeight).to.be.equal(-1);
};

module.exports = {
execute,
};

0 comments on commit 1a99856

Please sign in to comment.