Skip to content

Commit

Permalink
Adds SVP fund tx release and SVP spend tx created test.
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremy-then committed Jan 21, 2025
1 parent 9997ec4 commit 08b6ce6
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 19 deletions.
2 changes: 1 addition & 1 deletion lib/2wp-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ const peginVerifier = require('pegin-address-verificator');
const { getRskTransactionHelpers } = require('../lib/rsk-tx-helper-provider');
const { WHITELIST_CHANGE_PK, WHITELIST_CHANGE_ADDR} = require('../lib/assertions/whitelisting');
const { getLogger } = require('../logger');
const { BRIDGE_ADDRESS } = require('./bridge-constants');

const BTC_TO_RSK_MINIMUM_CONFIRMATIONS = 3;
const TO_BRIDGE_GAS_PRICE = 2;
const BRIDGE_ADDRESS = '0x0000000000000000000000000000000001000006';
const MIN_PEGOUT_VALUE_IN_RBTC = 0.0025;

const logger = getLogger();
Expand Down
3 changes: 1 addition & 2 deletions lib/assertions/fed.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ const rskUtilsLegacy = require('../rsk-utils-legacy');
const { getBridge } = require('../bridge-provider');
const rskUtils = require('../rsk-utils');
const { getRskTransactionHelpers } = require('../rsk-tx-helper-provider');

const BRIDGE_ADDRESS = "0x0000000000000000000000000000000001000006";
const { BRIDGE_ADDRESS } = require('../bridge-constants');

var assertKeyControl = (federates) => (begin, end, amountToTransferInWeis) => {
var rskClients = federates
Expand Down
6 changes: 6 additions & 0 deletions lib/bridge-constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
const BRIDGE_ADDRESS = '0x0000000000000000000000000000000001000006';

module.exports = {
BRIDGE_ADDRESS
};

2 changes: 1 addition & 1 deletion lib/liquidity-bridge-contract.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ const { getRskTransactionHelper } = require('../lib/rsk-tx-helper-provider');
const { compileAndDeploy } = require('./sol-utils');
const { sendFromCow } = require('./rsk-utils');
const { btcToWeis } = require('@rsksmart/btc-eth-unit-converter');
const { BRIDGE_ADDRESS } = require('./bridge-constants');

const INITIAL_RSK_BALANCE_IN_BTC = 1;
const BRIDGE_ADDRESS = '0x0000000000000000000000000000000001000006';
const LIQUIDITY_BRIDGE_CONTRACT_FILE = './contracts/LBC.sol'; // Relative to tests root
const LIQUIDITY_BRIDGE_CONTRACT_NAME = 'LiquidityBridgeContractImpl';
const SOLIDITY_COMPILER_VERSION = 'v0.7.4+commit.3f05b770';
Expand Down
24 changes: 13 additions & 11 deletions lib/rsk-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { getLogger } = require('../logger');
const { PEGOUT_EVENTS } = require('./constants/pegout-constants');
const { FEE_PER_KB_CHANGER_PRIVATE_KEY, FEE_PER_KB_CHANGER_ADDRESS, FEE_PER_KB_RESPONSE_CODES } = require('./constants/fee-per-kb-constants');
const { DEFAULT_RSK_ADDRESS_FUNDING_IN_BTC } = require('./constants/pegin-constants');
const { BRIDGE_ADDRESS } = require('./bridge-constants');

const BtcTransactionHelper = require('btc-transaction-helper/btc-transaction-helper');
const { ethToWeis } = require('@rsksmart/btc-eth-unit-converter');
Expand Down Expand Up @@ -169,9 +170,10 @@ const waitAndUpdateBridge = async (rskTxHelper, timeInMilliseconds = 1000) => {
* @param {RskTransactionHelper} rskTxHelper
* @returns {Promise<string[]>} array of tx hashes in the mempool
*/
const getRskMempoolTransactionHashes = async (rskTxHelper) => {
const getRskMempoolTransactionsToTheBridge = async (rskTxHelper) => {
const mempoolBlock = await rskTxHelper.getClient().eth.getBlock('pending');
return mempoolBlock.transactions;
const transactionsToTheBridge = mempoolBlock.transactions.filter((tx) => tx.to === BRIDGE_ADDRESS);
return transactionsToTheBridge;
};

/**
Expand Down Expand Up @@ -230,15 +232,15 @@ const waitForRskTxToBeInTheMempool = async (rskTxHelper, txHash, maxAttempts = 3
*/
const waitForRskMempoolToGetNewTxs = async (rskTxHelper, maxAttempts = 3, checkEveryMilliseconds = 500) => {

const initialRskMempoolTxHashes = await getRskMempoolTransactionHashes(rskTxHelper);
const initialRskMempoolTxs = await getRskMempoolTransactionsToTheBridge(rskTxHelper);

logger.debug(`[${waitForRskMempoolToGetNewTxs.name}] initial rsk mempool size: ${initialRskMempoolTxHashes.length}`);
logger.debug(`[${waitForRskMempoolToGetNewTxs.name}] initial rsk mempool size: ${initialRskMempoolTxs.length}`);
logger.debug(`[${waitForRskMempoolToGetNewTxs.name}] Will wait and attempt to check if the rsk mempool has received any new transactions ${maxAttempts} times.`);

const areThereNewTxsInTheMempool = async () => {
const mempoolTxHashes = await getRskMempoolTransactionHashes(rskTxHelper);
if(mempoolTxHashes.length > initialRskMempoolTxHashes.length) {
logger.debug(`[${waitForRskMempoolToGetNewTxs.name}] The mempool got ${mempoolTxHashes.length - initialRskMempoolTxHashes.length} new transactions`);
const mempoolTxHashes = await getRskMempoolTransactionsToTheBridge(rskTxHelper);
if(mempoolTxHashes.length > initialRskMempoolTxs.length) {
logger.debug(`[${waitForRskMempoolToGetNewTxs.name}] The mempool got ${mempoolTxHashes.length - initialRskMempoolTxs.length} new transactions`);
return true;
}
return false;
Expand All @@ -250,9 +252,9 @@ const waitForRskMempoolToGetNewTxs = async (rskTxHelper, maxAttempts = 3, checkE

const { result: newTxsWhereFoundInTheRskMempool, attempts } = await retryWithCheck(areThereNewTxsInTheMempool, check, maxAttempts, checkEveryMilliseconds);

const finalRskMempoolTxHashes = await getRskMempoolTransactionHashes(rskTxHelper);
const finalRskMempoolTxHashes = await getRskMempoolTransactionsToTheBridge(rskTxHelper);

logger.debug(`[${waitForRskMempoolToGetNewTxs.name}] final rsk mempool size: ${finalRskMempoolTxHashes.length}, after ${attempts} attempts. Difference with initial mempool size: ${finalRskMempoolTxHashes.length - initialRskMempoolTxHashes.length}`);
logger.debug(`[${waitForRskMempoolToGetNewTxs.name}] final rsk mempool size: ${finalRskMempoolTxHashes.length}, after ${attempts} attempts. Difference with initial mempool size: ${finalRskMempoolTxHashes.length - initialRskMempoolTxs.length}`);

return newTxsWhereFoundInTheRskMempool;

Expand Down Expand Up @@ -550,7 +552,7 @@ const getNewFundedRskAddress = async (rskTxHelper, fundingAmountInRbtc = DEFAULT
const waitForRskMempoolToGetAtLeastThisManyTxs = async (rskTxHelper, atLeastExpectedCount, waitTimeInMilliseconds = 500, maxAttempts = 20) => {
let attempts = 1;
while(attempts <= maxAttempts) {
const rskMempoolTxs = await getRskMempoolTransactionHashes(rskTxHelper);
const rskMempoolTxs = await getRskMempoolTransactionsToTheBridge(rskTxHelper);
logger.debug(`[${waitForRskMempoolToGetAtLeastThisManyTxs.name}] rsk mempool txs: ${rskMempoolTxs.length}`);
if(rskMempoolTxs.length >= atLeastExpectedCount) {
logger.debug(`[${waitForRskMempoolToGetAtLeastThisManyTxs.name}] rsk mempool has ${rskMempoolTxs.length} (at least expected was ${atLeastExpectedCount}) txs after ${attempts} attempts`);
Expand All @@ -574,7 +576,7 @@ module.exports = {
findEventInBlock,
getUnlockedAddress,
getFedsPubKeys,
getRskMempoolTransactionHashes,
getRskMempoolTransactionsToTheBridge,
waitForRskTxToBeInTheMempool,
waitForRskMempoolToGetNewTxs,
waitAndUpdateBridge,
Expand Down
4 changes: 2 additions & 2 deletions lib/tests/2wp.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const {
getPegoutEventsInBlockRange,
setFeePerKb,
sendTransaction,
getRskMempoolTransactionHashes,
getRskMempoolTransactionsToTheBridge,
getNewFundedRskAddress,
waitForRskMempoolToGetAtLeastThisManyTxs,
} = require('../rsk-utils');
Expand Down Expand Up @@ -938,7 +938,7 @@ const execute = (description, getRskHost) => {
const pegout3ValueInSatoshis = MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS + 150_000;
const totalPegoutValueInSatoshis = pegout1ValueInSatoshis + pegout2ValueInSatoshis + pegout3ValueInSatoshis;

const rskMemPoolTxHashes = await getRskMempoolTransactionHashes(rskTxHelper);
const rskMemPoolTxHashes = await getRskMempoolTransactionsToTheBridge(rskTxHelper);
const initialRskMempoolTxHashesSize = rskMemPoolTxHashes.length;

// Act
Expand Down
2 changes: 1 addition & 1 deletion lib/tests/bridge-calls.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ const solUtils = require('../sol-utils');
const btcEthUnitConverter = require('@rsksmart/btc-eth-unit-converter');
const { getRskTransactionHelper } = require('../rsk-tx-helper-provider');
const { getBridge } = require('../bridge-provider');
const { BRIDGE_ADDRESS } = require('../bridge-constants');

const INITIAL_RSK_BALANCE_IN_BTC = 1;
const BRIDGE_ADDRESS = '0x0000000000000000000000000000000001000006';
const BRIDGE_TESTER_FILE = './contracts/contract-calls-tester.sol'; // Relative to tests root
const BRIDGE_TESTER_CONTRACT_NAME = 'ContractCallsTester';
const SOLIDITY_COMPILER_VERSION = 'v0.4.16+commit.d7661dd9';
Expand Down
51 changes: 50 additions & 1 deletion tests/00_00_04-change-federation.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { expect } = require('chai');
const bitcoinJsLib = require('bitcoinjs-lib');
const { getBridgeState } = require('@rsksmart/bridge-state-data-parser');
const { parseRLPToPegoutWaitingSignatures } = require('@rsksmart/bridge-state-data-parser/pegout-waiting-signature');
const { btcToWeis, satoshisToBtc } = require('@rsksmart/btc-eth-unit-converter');
const BridgeTransactionParser = require('@rsksmart/bridge-transaction-parser');
const redeemScriptParser = require('@rsksmart/powpeg-redeemscript-parser');
Expand All @@ -12,6 +13,7 @@ const {
ensure0x,
splitStringIntoChunks,
getBridgeStorageValueDecodedHexString,
decodeRlp,
} = require('../lib/utils');
const {
KEY_TYPE_BTC,
Expand All @@ -28,11 +30,11 @@ const {
svpSpendTxWaitingForSignaturesStorageIndex,
} = require('../lib/constants/federation-constants');
const {
BRIDGE_ADDRESS,
createSenderRecipientInfo,
sendPegin,
ensurePeginIsRegistered
} = require('../lib/2wp-utils');
const { BRIDGE_ADDRESS } = require('../lib/bridge-constants');
const { getBtcClient } = require('../lib/btc-client-provider');
const { MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS, PEGOUT_EVENTS } = require('../lib/constants/pegout-constants');
const {
Expand Down Expand Up @@ -356,6 +358,32 @@ describe('Change federation', async function() {

});

it('should release and register the svp fund transaction and create the svp spend transaction', async () => {

// Mining to have enough confirmations for the SVP fund transaction and updating the bridge.
await rskTxHelper.mine(3);
await rskUtils.waitAndUpdateBridge(rskTxHelper);

const initialBridgeState = await getBridgeState(rskTxHelper.getClient());
expect(initialBridgeState.pegoutsWaitingForSignatures.length).to.be.equal(1, 'The svp fund transaction should be waiting for signatures.');

const blockNumberBeforeRelease = await rskTxHelper.getBlockNumber();
await rskUtils.triggerRelease(rskTxHelpers, btcTxHelper);
const blockNumberAfterRelease = await rskTxHelper.getBlockNumber();
const releaseBtcEvent = await rskUtils.findEventInBlock(rskTxHelper, PEGOUT_EVENTS.RELEASE_BTC.name, blockNumberBeforeRelease, blockNumberAfterRelease);

const releaseBtcTransaction = bitcoinJsLib.Transaction.fromHex(removePrefix0x(releaseBtcEvent.arguments.btcRawTransaction));
const finalBridgeState = await getBridgeState(rskTxHelper.getClient());
const registeredSvpFundTxUtxo = finalBridgeState.activeFederationUtxos.find(utxo => utxo.btcTxHash === releaseBtcTransaction.getId());
expect(registeredSvpFundTxUtxo, 'The SVP fund tx should be registered in the Bridge by now.').to.not.be.undefined;

const utxoToActiveFederation = releaseBtcTransaction.outs[2];
expect(registeredSvpFundTxUtxo.valueInSatoshis).to.be.equal(utxoToActiveFederation.value, 'The SVP fund tx registered utxo value should be the same as the utxo to the active federation.');

await assertOnlySvpSpendTxValuesAreInStorage(rskTxHelper);

});

it('should activate federation', async () => {

const federationActivationBlockNumber = commitFederationCreationBlockNumber + FEDERATION_ACTIVATION_AGE;
Expand Down Expand Up @@ -438,6 +466,27 @@ const assertOnlySvpFundTxHashUnsignedIsInStorage = async (rskTxHelper, pegoutBtc

};

const assertOnlySvpSpendTxValuesAreInStorage = async (rskTxHelper) => {

const svpFundTxHashUnsignedRlpEncoded = await rskTxHelper.getClient().rsk.getStorageBytesAt(BRIDGE_ADDRESS, svpFundTxHashUnsignedStorageIndex);
expect(svpFundTxHashUnsignedRlpEncoded).to.be.equal('0x0', 'The SVP fund tx hash unsigned storage value should be empty.');

const svpFundTxSigned = await rskTxHelper.getClient().rsk.getStorageBytesAt(BRIDGE_ADDRESS, svpFundTxSignedStorageIndex);
expect(svpFundTxSigned).to.be.equal('0x0', 'The SVP fund tx signed storage value should be empty.');

const svpSpendTxHashUnsigned = await rskTxHelper.getClient().rsk.getStorageBytesAt(BRIDGE_ADDRESS, svpSpendTxHashUnsignedStorageIndex);
expect(svpSpendTxHashUnsigned).to.not.be.equal('0x0', 'The SVP spend tx hash unsigned storage value should not be empty.');
const svpSpendTxHashUnsignedDecoded = decodeRlp(svpSpendTxHashUnsigned).toString('hex');

const svpSpendTxWaitingForSignatures = await rskTxHelper.getClient().rsk.getStorageBytesAt(BRIDGE_ADDRESS, svpSpendTxWaitingForSignaturesStorageIndex);
expect(svpSpendTxWaitingForSignatures).to.not.be.equal('0x0', 'The SVP spend tx waiting for signatures storage value should not be empty.');

const decodedSvpSpendTxWaitingForSignature = parseRLPToPegoutWaitingSignatures(svpSpendTxWaitingForSignatures)[0];
const svpSpendBtcTx = bitcoinJsLib.Transaction.fromHex(removePrefix0x(decodedSvpSpendTxWaitingForSignature.btcRawTx));
expect(svpSpendTxHashUnsignedDecoded).to.be.equal(svpSpendBtcTx.getId(), 'The SVP spend tx hash unsigned storage value should be the tx id of the SVP spend tx.');

};

const assertPegoutTrasactionCreatedOutpointValues = async (initialBridgeState, finalBridgeState, svpBtcTransaction, pegoutTransactionCreatedEvent) => {

const svpFundTxInput = svpBtcTransaction.ins[0];
Expand Down

0 comments on commit 08b6ce6

Please sign in to comment.