-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds 'should create multiple pegouts with mixed values same and above… #163
base: rits-refactors-9-2024-integration
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,16 @@ 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, setFeePerKb, sendTransaction, getNewFundedRskAddress } = require('../rsk-utils'); | ||
const { | ||
findEventInBlock, | ||
triggerRelease, | ||
getPegoutEventsInBlockRange, | ||
setFeePerKb, | ||
sendTransaction, | ||
getRskMempoolTransactionHashes, | ||
getNewFundedRskAddress, | ||
waitForRskMempoolToGetAtLeastThisManyTxs, | ||
} = require('../rsk-utils'); | ||
const BridgeTransactionParser = require('@rsksmart/bridge-transaction-parser'); | ||
const { | ||
PEGIN_REJECTION_REASONS, | ||
|
@@ -905,6 +914,130 @@ const execute = (description, getRskHost) => { | |
|
||
}); | ||
|
||
it('should create multiple pegouts with mixed values same and above minimum', async () => { | ||
|
||
// Arrange | ||
|
||
const senderRecipientInfo1 = await createSenderRecipientInfo(rskTxHelper, btcTxHelper); | ||
await fundRskAccountThroughAPegin(rskTxHelper, btcTxHelper, senderRecipientInfo1.btcSenderAddressInfo); | ||
|
||
const senderRecipientInfo2 = await createSenderRecipientInfo(rskTxHelper, btcTxHelper); | ||
await fundRskAccountThroughAPegin(rskTxHelper, btcTxHelper, senderRecipientInfo2.btcSenderAddressInfo); | ||
|
||
const senderRecipientInfo3 = await createSenderRecipientInfo(rskTxHelper, btcTxHelper); | ||
await fundRskAccountThroughAPegin(rskTxHelper, btcTxHelper, senderRecipientInfo3.btcSenderAddressInfo); | ||
nathanieliov marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
const initial2wpBalances = await get2wpBalances(rskTxHelper, btcTxHelper); | ||
|
||
const initialSender1AddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo1.btcSenderAddressInfo.address); | ||
const initialSender2AddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo2.btcSenderAddressInfo.address); | ||
const initialSender3AddressBalanceInSatoshis = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo3.btcSenderAddressInfo.address); | ||
|
||
const pegout1ValueInSatoshis = MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS; | ||
const pegout2ValueInSatoshis = MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS + 100_000; | ||
const pegout3ValueInSatoshis = MINIMUM_PEGOUT_AMOUNT_IN_SATOSHIS + 150_000; | ||
const totalPegoutValueInSatoshis = pegout1ValueInSatoshis + pegout2ValueInSatoshis + pegout3ValueInSatoshis; | ||
|
||
const rskMemPoolTxHashes = await getRskMempoolTransactionHashes(rskTxHelper); | ||
const initialRskMempoolTxHashesSize = rskMemPoolTxHashes.length; | ||
|
||
// Act | ||
|
||
const shouldMine = false; | ||
const pegoutTransaction1Promise = sendTxToBridge(rskTxHelper, new BN(satoshisToWeis(pegout1ValueInSatoshis)), senderRecipientInfo1.rskRecipientRskAddressInfo.address, shouldMine); | ||
const pegoutTransaction2Promise = sendTxToBridge(rskTxHelper, new BN(satoshisToWeis(pegout2ValueInSatoshis)), senderRecipientInfo2.rskRecipientRskAddressInfo.address, shouldMine); | ||
const pegoutTransaction3Promise = sendTxToBridge(rskTxHelper, new BN(satoshisToWeis(pegout3ValueInSatoshis)), senderRecipientInfo3.rskRecipientRskAddressInfo.address, shouldMine); | ||
|
||
// Waiting for our 3 txs to reach the mempool before trying to mine them. + 3 because we are sending 3 pegouts. | ||
const atLeastExpectedCount = initialRskMempoolTxHashesSize + 3; | ||
await waitForRskMempoolToGetAtLeastThisManyTxs(rskTxHelper, atLeastExpectedCount); | ||
|
||
// Now our 3 pegout transaction requests will get mined together. | ||
await rskTxHelper.mine(); | ||
|
||
// After mining, we can get the transaction receipts. | ||
const pegoutTransaction1 = await pegoutTransaction1Promise; | ||
const pegoutTransaction2 = await pegoutTransaction2Promise; | ||
const pegoutTransaction3 = await pegoutTransaction3Promise; | ||
|
||
// Assert | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we check the Bridge state at this point? To assert there are 3 pegout requests created |
||
|
||
let bridgeStateAfterPegoutCreation; | ||
|
||
// Callback to get the bridge state after the pegout is created | ||
const pegoutCreatedCallback = async () => { | ||
bridgeStateAfterPegoutCreation = await getBridgeState(rskTxHelper.getClient()); | ||
}; | ||
Comment on lines
+968
to
+970
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I might be missing something, what's the value of this callback? It will simply get the Bridge state and do nothing with it |
||
|
||
const callbacks = { | ||
pegoutCreatedCallback | ||
}; | ||
|
||
await triggerRelease(rskTxHelpers, btcTxHelper, callbacks); | ||
|
||
// Checking all the pegout events are emitted and in order | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems they all get mined in the same block. How are we verifying the order? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They all get mined in the same block, otherwise, the test would fail. |
||
const blockNumberAfterPegoutRelease = await rskTxHelper.getBlockNumber(); | ||
const pegoutsEvents = await getPegoutEventsInBlockRange(rskTxHelper, pegoutTransaction1.blockNumber, blockNumberAfterPegoutRelease); | ||
|
||
// The release_request_received event of the first pegout request | ||
const rskSender1Address = rskTxHelper.getClient().utils.toChecksumAddress(ensure0x(senderRecipientInfo1.rskRecipientRskAddressInfo.address)); | ||
const releaseRequestReceivedEvent1 = pegoutsEvents.find(event => event.arguments.sender === rskSender1Address); | ||
assertReleaseRequestReceivedEvent(releaseRequestReceivedEvent1, rskSender1Address, senderRecipientInfo1.btcSenderAddressInfo.address, pegout1ValueInSatoshis); | ||
|
||
// The release_request_received event of the second pegout request | ||
const rskSender2Address = rskTxHelper.getClient().utils.toChecksumAddress(ensure0x(senderRecipientInfo2.rskRecipientRskAddressInfo.address)); | ||
const releaseRequestReceivedEvent2 = pegoutsEvents.find(event => event.arguments.sender === rskSender2Address); | ||
assertReleaseRequestReceivedEvent(releaseRequestReceivedEvent2, rskSender2Address, senderRecipientInfo2.btcSenderAddressInfo.address, pegout2ValueInSatoshis); | ||
|
||
// The release_request_received event of the third pegout request | ||
const rskSender3Address = rskTxHelper.getClient().utils.toChecksumAddress(ensure0x(senderRecipientInfo3.rskRecipientRskAddressInfo.address)); | ||
const releaseRequestReceivedEvent3 = pegoutsEvents.find(event => event.arguments.sender === rskSender3Address); | ||
assertReleaseRequestReceivedEvent(releaseRequestReceivedEvent3, rskSender3Address, senderRecipientInfo3.btcSenderAddressInfo.address, pegout3ValueInSatoshis); | ||
|
||
const pegoutWaitingForConfirmationWhenPegoutWasCreated = bridgeStateAfterPegoutCreation.pegoutsWaitingForConfirmations[0]; | ||
const btcTransaction = bitcoinJsLib.Transaction.fromHex(pegoutWaitingForConfirmationWhenPegoutWasCreated.btcRawTx); | ||
const pegoutCreationRskTransactionHash = ensure0x(pegoutWaitingForConfirmationWhenPegoutWasCreated.rskTxHash.padStart(64, '0')); | ||
|
||
// Release requested events | ||
const releaseRequestedEvent = pegoutsEvents[3]; | ||
assertReleaseRequestedEvent(releaseRequestedEvent, pegoutCreationRskTransactionHash, btcTransaction.getId(), totalPegoutValueInSatoshis); | ||
|
||
const batchPegoutCreatedEvent = pegoutsEvents[4]; | ||
assertBatchPegoutCreatedEvent(batchPegoutCreatedEvent, btcTransaction.getId(), [pegoutTransaction1.transactionHash, pegoutTransaction2.transactionHash, pegoutTransaction3.transactionHash]); | ||
|
||
// pegout_confirmed event | ||
const pegoutConfirmedEvent = pegoutsEvents[5]; | ||
assertPegoutConfirmedEvent(pegoutConfirmedEvent, btcTransaction.getId(), pegoutWaitingForConfirmationWhenPegoutWasCreated.pegoutCreationBlockNumber); | ||
|
||
// add_signature events | ||
const addSignatureEvents = pegoutsEvents.slice(6, pegoutsEvents.length - 1); | ||
assertAddSignatureEvents(addSignatureEvents, releaseRequestedEvent); | ||
|
||
// release_btc event | ||
const releaseBtcEvent = pegoutsEvents[pegoutsEvents.length - 1]; | ||
assertReleaseBtcEvent(releaseBtcEvent, releaseRequestedEvent); | ||
|
||
await assert2wpBalanceAfterSuccessfulPegout(initial2wpBalances, totalPegoutValueInSatoshis); | ||
|
||
const releaseBtcTransaction = bitcoinJsLib.Transaction.fromHex(removePrefix0x(releaseBtcEvent.arguments.btcRawTransaction)); | ||
|
||
// Asserting actual value received for sender 1 | ||
const finalSenderAddressBalanceInSatoshis1 = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo1.btcSenderAddressInfo.address); | ||
const sender1Utxo = getAddressUtxo(releaseBtcTransaction.outs, senderRecipientInfo1.btcSenderAddressInfo.address); | ||
expect(finalSenderAddressBalanceInSatoshis1).to.be.equal(initialSender1AddressBalanceInSatoshis + sender1Utxo.value); | ||
|
||
// Asserting actual value received for sender 2 | ||
const finalSenderAddressBalanceInSatoshis2 = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo2.btcSenderAddressInfo.address); | ||
const serder2Utxo = getAddressUtxo(releaseBtcTransaction.outs, senderRecipientInfo2.btcSenderAddressInfo.address); | ||
expect(finalSenderAddressBalanceInSatoshis2).to.be.equal(initialSender2AddressBalanceInSatoshis + serder2Utxo.value); | ||
|
||
// Asserting actual value received for sender 3 | ||
const finalSenderAddressBalanceInSatoshis3 = await getBtcAddressBalanceInSatoshis(btcTxHelper, senderRecipientInfo3.btcSenderAddressInfo.address); | ||
const serder3Utxo = getAddressUtxo(releaseBtcTransaction.outs, senderRecipientInfo3.btcSenderAddressInfo.address); | ||
expect(finalSenderAddressBalanceInSatoshis3).to.be.equal(initialSender3AddressBalanceInSatoshis + serder3Utxo.value); | ||
|
||
}); | ||
|
||
}); | ||
|
||
}; | ||
|
@@ -1011,6 +1144,44 @@ const assertBtcPeginTxHashProcessed = async (btcPeginTxHash) => { | |
expect(isBtcTxHashAlreadyProcessed).to.be.true; | ||
}; | ||
|
||
const assertReleaseRequestReceivedEvent = (releaseRequestReceivedEvent, rskSenderAddress, btcRecipientAddress, pegoutValueInSatoshis) => { | ||
expect(releaseRequestReceivedEvent.arguments.sender).to.be.equal(rskSenderAddress); | ||
expect(Number(releaseRequestReceivedEvent.arguments.amount)).to.be.equal(pegoutValueInSatoshis); | ||
expect(releaseRequestReceivedEvent.arguments.btcDestinationAddress).to.be.equal(btcRecipientAddress); | ||
}; | ||
|
||
const assertReleaseRequestedEvent = (releaseRequestedEvent, pegoutCreationRskTransactionHash, btcTxHash, pegoutValueInSatoshis) => { | ||
expect(releaseRequestedEvent.arguments.rskTxHash).to.be.equal(pegoutCreationRskTransactionHash); | ||
expect(removePrefix0x(releaseRequestedEvent.arguments.btcTxHash)).to.be.equal(btcTxHash); | ||
expect(Number(releaseRequestedEvent.arguments.amount)).to.be.equal(pegoutValueInSatoshis); | ||
}; | ||
|
||
const assertBatchPegoutCreatedEvent = (batchPegoutCreatedEvent, btcTxHash, pegoutRequestReceivedTransactionHashes) => { | ||
expect(removePrefix0x(batchPegoutCreatedEvent.arguments.btcTxHash)).to.be.equal(btcTxHash); | ||
const releaseRskTxHashes = batchPegoutCreatedEvent.arguments.releaseRskTxHashes; | ||
const allPegoutRequestReceivedTxHashesAreInBatch = pegoutRequestReceivedTransactionHashes.every(hash => releaseRskTxHashes.includes(removePrefix0x(hash))); | ||
expect(allPegoutRequestReceivedTxHashesAreInBatch).to.be.true; | ||
}; | ||
|
||
const assertPegoutConfirmedEvent = (pegoutConfirmedEvent, btcTxHash, pegoutCreationBlockNumber) => { | ||
expect(removePrefix0x(pegoutConfirmedEvent.arguments.btcTxHash)).to.be.equal(btcTxHash); | ||
expect(pegoutConfirmedEvent.arguments.pegoutCreationRskBlockNumber).to.be.equal(pegoutCreationBlockNumber); | ||
}; | ||
|
||
const assertAddSignatureEvent = (addSignatureEvent, releaseRequestedEvent) => { | ||
expect(addSignatureEvent.arguments.releaseRskTxHash).to.be.equal(releaseRequestedEvent.arguments.rskTxHash); | ||
}; | ||
|
||
const assertAddSignatureEvents = (addSignatureEvents, releaseRequestedEvent) => { | ||
addSignatureEvents.forEach(addSignatureEvent => { | ||
assertAddSignatureEvent(addSignatureEvent, releaseRequestedEvent); | ||
}); | ||
}; | ||
|
||
const assertReleaseBtcEvent = (releaseBtcEvent, releaseRequestedEvent) => { | ||
expect(releaseBtcEvent.arguments.releaseRskTxHash).to.be.equal(releaseRequestedEvent.arguments.rskTxHash); | ||
}; | ||
|
||
const assertSuccessfulPegoutEventsAreEmitted = async (pegoutsEvents, pegoutRequestReceivedTransactionHash, senderRecipientInfo, pegoutValueInSatoshis, bridgeStateAfterPegoutCreation) => { | ||
|
||
const pegoutWaitingForConfirmationWhenPegoutWasCreated = bridgeStateAfterPegoutCreation.pegoutsWaitingForConfirmations[0]; | ||
|
@@ -1019,40 +1190,27 @@ const assertSuccessfulPegoutEventsAreEmitted = async (pegoutsEvents, pegoutReque | |
|
||
// release_request_received event | ||
const releaseRequestReceivedEvent = pegoutsEvents[0]; | ||
expect(releaseRequestReceivedEvent.arguments.sender).to.be.equal(rskSenderAddress); | ||
expect(Number(releaseRequestReceivedEvent.arguments.amount)).to.be.equal(pegoutValueInSatoshis); | ||
expect(releaseRequestReceivedEvent.arguments.btcDestinationAddress).to.be.equal(senderRecipientInfo.btcSenderAddressInfo.address); | ||
assertReleaseRequestReceivedEvent(releaseRequestReceivedEvent, rskSenderAddress, senderRecipientInfo.btcSenderAddressInfo.address, pegoutValueInSatoshis); | ||
|
||
// release_requested event | ||
const pegoutCreationRskTransactionHash = ensure0x(pegoutWaitingForConfirmationWhenPegoutWasCreated.rskTxHash.padStart(64, '0')); | ||
const releaseRequestedEvent = pegoutsEvents[1]; | ||
expect(releaseRequestedEvent.arguments.rskTxHash).to.be.equal(pegoutCreationRskTransactionHash); | ||
expect(removePrefix0x(releaseRequestedEvent.arguments.btcTxHash)).to.be.equal(btcTransaction.getId()); | ||
expect(Number(releaseRequestReceivedEvent.arguments.amount)).to.be.equal(pegoutValueInSatoshis); | ||
assertReleaseRequestedEvent(releaseRequestedEvent, pegoutCreationRskTransactionHash, btcTransaction.getId(), pegoutValueInSatoshis); | ||
|
||
// batch_pegout_created event | ||
const batchPegoutCreatedEvent = pegoutsEvents[2]; | ||
expect(removePrefix0x(batchPegoutCreatedEvent.arguments.btcTxHash)).to.be.equal(btcTransaction.getId()); | ||
expect(batchPegoutCreatedEvent.arguments.releaseRskTxHashes.includes(removePrefix0x(pegoutRequestReceivedTransactionHash))).to.be.true; | ||
|
||
assertBatchPegoutCreatedEvent(batchPegoutCreatedEvent, btcTransaction.getId(), [pegoutRequestReceivedTransactionHash]); | ||
|
||
// pegout_confirmed event | ||
const pegoutConfirmedEvent = pegoutsEvents[3]; | ||
expect(removePrefix0x(pegoutConfirmedEvent.arguments.btcTxHash)).to.be.equal(btcTransaction.getId()); | ||
expect(pegoutConfirmedEvent.arguments.pegoutCreationRskBlockNumber).to.be.equal(pegoutWaitingForConfirmationWhenPegoutWasCreated.pegoutCreationBlockNumber); | ||
assertPegoutConfirmedEvent(pegoutConfirmedEvent, btcTransaction.getId(), pegoutWaitingForConfirmationWhenPegoutWasCreated.pegoutCreationBlockNumber); | ||
|
||
// add_signature events | ||
const addSignatureEvent1 = pegoutsEvents[4]; | ||
const addSignatureEvent2 = pegoutsEvents[5]; | ||
const addSignatureEvent3 = pegoutsEvents[6]; | ||
|
||
expect(addSignatureEvent1.arguments.releaseRskTxHash).to.be.equal(releaseRequestedEvent.arguments.rskTxHash); | ||
expect(addSignatureEvent2.arguments.releaseRskTxHash).to.be.equal(releaseRequestedEvent.arguments.rskTxHash); | ||
expect(addSignatureEvent3.arguments.releaseRskTxHash).to.be.equal(releaseRequestedEvent.arguments.rskTxHash); | ||
const addSignatureEvents = pegoutsEvents.slice(4, pegoutsEvents.length - 1); | ||
assertAddSignatureEvents(addSignatureEvents, releaseRequestedEvent); | ||
|
||
// Final event, release_btc | ||
const releaseBtcEvent = pegoutsEvents[7]; | ||
expect(releaseBtcEvent.arguments.releaseRskTxHash).to.be.equal(releaseRequestedEvent.arguments.rskTxHash); | ||
const releaseBtcEvent = pegoutsEvents[pegoutsEvents.length - 1]; | ||
assertReleaseBtcEvent(releaseBtcEvent, releaseRequestedEvent); | ||
|
||
}; | ||
|
||
|
@@ -1113,6 +1271,13 @@ const getReleaseRequestRejectedEventFromContractCallTxReceipt = (contractCallTxR | |
return releaseRequestRejectedEvent; | ||
}; | ||
|
||
const getAddressUtxo = (outputs, address) => { | ||
return outputs.find(output => { | ||
const outputAddress = bitcoinJsLib.address.fromOutputScript(output.script, btcTxHelper.btcConfig.network); | ||
return outputAddress === address; | ||
}); | ||
}; | ||
|
||
module.exports = { | ||
execute, | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed there is a mixed of
if (
anif(
in the test. I always preferif(
. But what should we always use? @nathanieliov , @marcos-iov , @julia-zack .There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@apancorb 's suggestion, as it seems to be the rule of our formatting settings. I formatted it in my local and the result was @apancorb suggestion.