Skip to content

Commit

Permalink
Merge pull request #140 from rsksmart/add-pegout-with-fee-above-value…
Browse files Browse the repository at this point in the history
…-test

Adds 'should reject and refund a pegout when fee per kb is above valu…
  • Loading branch information
marcos-iov authored Oct 31, 2024
2 parents 2d07a07 + 01deb04 commit 1aecc22
Show file tree
Hide file tree
Showing 5 changed files with 883 additions and 176 deletions.
10 changes: 10 additions & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,13 @@ const PEGIN_V1_RSKT_PREFIX_HEX = '52534b54';
const MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS = 250_000;
const DEFAULT_RSK_ADDRESS_FUNDING_IN_BTC = 0.5;

const FEE_PER_KB_CHANGER_PRIVATE_KEY = '6a4b49312b91e203ddfb9bc2d900ebbd46fbede46a7462e770bedcb11ad405e9';
const FEE_PER_KB_CHANGER_ADDRESS = '53f8f6dabd612b6137215ddd7758bb5cdd638922';

const FEE_PER_KB_RESPONSE_CODES = {
SUCCESSFUL_VOTE: 1,
};

module.exports = {
KEY_TYPE_BTC,
KEY_TYPE_RSK,
Expand All @@ -143,4 +150,7 @@ module.exports = {
MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS,
DEFAULT_RSK_ADDRESS_FUNDING_IN_BTC,
PEGOUT_REJECTION_REASONS,
FEE_PER_KB_CHANGER_PRIVATE_KEY,
FEE_PER_KB_CHANGER_ADDRESS,
FEE_PER_KB_RESPONSE_CODES,
};
30 changes: 28 additions & 2 deletions lib/rsk-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ const { getRskTransactionHelpers } = require('../lib/rsk-tx-helper-provider');
const { wait, retryWithCheck, removePrefix0x } = require('./utils');
const { waitForBitcoinMempoolToGetTxs } = require('./btc-utils');
const { getLogger } = require('../logger');
const { PEGOUT_EVENTS } = require('./constants');
const {
PEGOUT_EVENTS,
FEE_PER_KB_CHANGER_PRIVATE_KEY,
FEE_PER_KB_CHANGER_ADDRESS,
FEE_PER_KB_RESPONSE_CODES,
} = require('./constants');
const BtcTransactionHelper = require('btc-transaction-helper/btc-transaction-helper');

const BTC_TO_RSK_MINIMUM_ACCEPTABLE_CONFIRMATIONS = 3;
Expand Down Expand Up @@ -502,7 +507,27 @@ const getFedsPubKeys = async (bridge) => {
FEDS_PUBKEYS_LIST.push(removePrefix0x(fedPubKey));
}
return FEDS_PUBKEYS_LIST;
}
};

/**
* Calls `Bridge::voteFeePerKbChange` to set a new fee per kb.
* @param {RskTransactionHelper} rskTxHelper
* @param {number} feePerKbInSatoshis the value to be set as the new fee per kb
*/
const setFeePerKb = async (rskTxHelper, feePerKbInSatoshis) => {

await rskTxHelper.getClient().eth.personal.importRawKey(FEE_PER_KB_CHANGER_PRIVATE_KEY, '');
await rskTxHelper.getClient().eth.personal.unlockAccount(FEE_PER_KB_CHANGER_ADDRESS, '');
const bridge = getBridge(rskTxHelper.getClient());

await sendTxWithCheck(rskTxHelper, bridge.methods.voteFeePerKbChange(feePerKbInSatoshis), FEE_PER_KB_CHANGER_ADDRESS, (result) => {
expect(Number(result)).to.equal(FEE_PER_KB_RESPONSE_CODES.SUCCESSFUL_VOTE);
});

const finalFeePerKb = await bridge.methods.getFeePerKb().call();
expect(Number(finalFeePerKb)).to.equal(Number(feePerKbInSatoshis));

};

module.exports = {
mineAndSync,
Expand All @@ -522,4 +547,5 @@ module.exports = {
waitAndUpdateBridge,
sendTransaction,
getPegoutEventsInBlockRange,
setFeePerKb,
};
48 changes: 46 additions & 2 deletions lib/tests/2wp.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const { getBridge } = require('../precompiled-abi-forks-util');
const { getBtcClient } = require('../btc-client-provider');
const { getRskTransactionHelper, getRskTransactionHelpers } = require('../rsk-tx-helper-provider');
const { satoshisToBtc, btcToSatoshis, satoshisToWeis } = require('@rsksmart/btc-eth-unit-converter');
const { findEventInBlock, triggerRelease, getPegoutEventsInBlockRange } = require('../rsk-utils');
const { findEventInBlock, triggerRelease, getPegoutEventsInBlockRange, setFeePerKb } = require('../rsk-utils');
const {
PEGIN_REJECTION_REASONS,
PEGIN_UNREFUNDABLE_REASONS,
Expand Down Expand Up @@ -774,6 +774,51 @@ const execute = (description, getRskHost) => {

});

it('should reject and refund a pegout when fee per kb is above value', async () => {

// Arrange

// Create a pegin for the sender to ensure there is enough funds to pegout and because this is the natural process
const senderRecipientInfo = await createSenderRecipientInfo(rskTxHelper, btcTxHelper);
await fundRskAccountThroughAPegin(rskTxHelper, btcTxHelper, senderRecipientInfo.btcSenderAddressInfo);

const initial2wpBalances = await get2wpBalances(rskTxHelper, btcTxHelper);
const initialBtcRecipientAddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo.btcSenderAddressInfo.address);
const initialRskSenderBalanceInWeisBN = await rskTxHelper.getBalance(senderRecipientInfo.rskRecipientRskAddressInfo.address);
const pegoutValueInSatoshis = MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS;

const initialFeePerKb = Number(await bridge.methods.getFeePerKb().call());
// We just need to have a feePerKB that will cause the pegout to rejected due to FEE_ABOVE_VALUE reason.
// This value is way bigger than what we need, but actual calculation is complex and and estimation so we cannot know for sure.
// That's we we just use a big enough value. The MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS is perfect for this in this case.
const newFeePerKbInSatoshis = MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS;
await setFeePerKb(rskTxHelper, newFeePerKbInSatoshis);

// Act

const pegoutTransaction = await sendTxToBridge(rskTxHelper, new BN(satoshisToWeis(pegoutValueInSatoshis)), senderRecipientInfo.rskRecipientRskAddressInfo.address);

// Assert

await assertExpectedReleaseRequestRejectedEventIsEmitted(senderRecipientInfo.rskRecipientRskAddressInfo.address, pegoutValueInSatoshis, PEGOUT_REJECTION_REASONS.FEE_ABOVE_VALUE);

await assert2wpBalanceIsUnchanged(initial2wpBalances);

// The rsk sender balance is the same as the initial balance minus the gas fee, because the pegout amount was refunded.
const finalRskSenderBalanceInWeisBN = await rskTxHelper.getBalance(senderRecipientInfo.rskRecipientRskAddressInfo.address);
const gasFee = pegoutTransaction.gasUsed * pegoutTransaction.effectiveGasPrice;
const expectedRskSenderBalanceInWeisBN = initialRskSenderBalanceInWeisBN.sub(new BN(`${gasFee}`));
expect(finalRskSenderBalanceInWeisBN.eq(expectedRskSenderBalanceInWeisBN)).to.be.true;

// The btc recipient address balance is the same as the initial balance, because the pegout didn't go though.
const finalBtcRecipientBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo.btcSenderAddressInfo.address);
expect(finalBtcRecipientBalanceInSatoshis).to.be.equal(initialBtcRecipientAddressBalanceInSatoshis);

// Setting fee per kb back to its original value
await setFeePerKb(rskTxHelper, initialFeePerKb);

});

});

};
Expand Down Expand Up @@ -940,4 +985,3 @@ const assertExpectedReleaseRequestRejectedEventIsEmitted = async (rskSenderAddre
module.exports = {
execute,
};

Loading

0 comments on commit 1aecc22

Please sign in to comment.