From 4835a42d77e96dbbe8106924ec25c1f36241f125 Mon Sep 17 00:00:00 2001 From: julia-zack Date: Tue, 17 Sep 2024 14:07:28 -0300 Subject: [PATCH] Move flyover methods from BridgeSupport to PegUtils Move new methods to PegUtils. Add tests Remove unused imports Use Address.fromBase58 instead of deprecated Address to fix sonar complain Fix call to FlyoverRedeemScriptBuilder --- .../main/java/co/rsk/peg/BridgeSupport.java | 14 ++----- .../src/main/java/co/rsk/peg/BridgeUtils.java | 5 +-- .../src/main/java/co/rsk/peg/PegUtils.java | 25 ++++++++++--- .../java/co/rsk/peg/BridgeSupportTest.java | 9 +---- .../test/java/co/rsk/peg/PegUtilsTest.java | 37 ++++++++++++++++++- 5 files changed, 60 insertions(+), 30 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java index db4398c1560..e1ce72eeb48 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -17,6 +17,7 @@ */ package co.rsk.peg; +import static co.rsk.peg.PegUtils.getFlyoverAddress; import static co.rsk.peg.BridgeUtils.getRegularPegoutTxSize; import static co.rsk.peg.ReleaseTransactionBuilder.BTC_TX_VERSION_2; import static co.rsk.peg.bitcoin.UtxoUtils.extractOutpointValues; @@ -996,7 +997,8 @@ private BtcTransaction createSvpFundTransaction(Federation proposedFederation, C // add outputs to proposed fed and proposed fed with flyover prefix svpFundTransaction.addOutput(spendableValueFromProposedFederation, proposedFederation.getAddress()); - Address proposedFederationWithFlyoverPrefixAddress = getProposedFederationWithFlyoverPrefixAddress(proposedFederation.getRedeemScript()); + Address proposedFederationWithFlyoverPrefixAddress = + getFlyoverAddress(networkParameters, bridgeConstants.getProposedFederationFlyoverPrefix(), proposedFederation.getRedeemScript()); svpFundTransaction.addOutput(spendableValueFromProposedFederation, proposedFederationWithFlyoverPrefixAddress); // complete tx with input and change output @@ -1006,16 +1008,6 @@ private BtcTransaction createSvpFundTransaction(Federation proposedFederation, C return svpFundTransaction; } - private Address getProposedFederationWithFlyoverPrefixAddress(Script federationRedeemScript) { - Script federationWithFlyoverPrefixRedeemScript = FlyoverRedeemScriptBuilderImpl.builder().of( - bridgeConstants.getProposedFederationFlyoverPrefix(), - federationRedeemScript - ); - Script federationWithFlyoverPrefixP2SHScript = ScriptBuilder.createP2SHOutputScript(federationWithFlyoverPrefixRedeemScript); - - return Address.fromP2SHScript(networkParameters, federationWithFlyoverPrefixP2SHScript); - } - private SendRequest createSvpFundTransactionSendRequest(BtcTransaction transaction) { SendRequest sendRequest = SendRequest.forTx(transaction); sendRequest.changeAddress = getActiveFederationAddress(); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java index 6e854f8c88a..39bddc7ac2d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java @@ -19,11 +19,8 @@ import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.crypto.TransactionSignature; -import co.rsk.bitcoinj.script.RedeemScriptParser; +import co.rsk.bitcoinj.script.*; import co.rsk.bitcoinj.script.RedeemScriptParser.MultiSigType; -import co.rsk.bitcoinj.script.RedeemScriptParserFactory; -import co.rsk.bitcoinj.script.Script; -import co.rsk.bitcoinj.script.ScriptChunk; import co.rsk.bitcoinj.wallet.Wallet; import co.rsk.peg.constants.BridgeConstants; import co.rsk.core.RskAddress; diff --git a/rskj-core/src/main/java/co/rsk/peg/PegUtils.java b/rskj-core/src/main/java/co/rsk/peg/PegUtils.java index f03ffc0b2af..74b04f90281 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PegUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/PegUtils.java @@ -5,14 +5,12 @@ import static co.rsk.peg.pegin.RejectedPeginReason.LEGACY_PEGIN_UNDETERMINED_SENDER; import static co.rsk.peg.pegin.RejectedPeginReason.PEGIN_V1_INVALID_PAYLOAD; -import co.rsk.bitcoinj.core.Address; -import co.rsk.bitcoinj.core.BtcTransaction; -import co.rsk.bitcoinj.core.Coin; -import co.rsk.bitcoinj.core.Context; -import co.rsk.bitcoinj.core.Sha256Hash; -import co.rsk.bitcoinj.core.TransactionOutput; +import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; +import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.wallet.Wallet; +import co.rsk.crypto.Keccak256; +import co.rsk.peg.bitcoin.FlyoverRedeemScriptBuilderImpl; import co.rsk.peg.constants.BridgeConstants; import co.rsk.peg.bitcoin.BitcoinUtils; import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType; @@ -198,4 +196,19 @@ private static PeginEvaluationResult evaluateLegacyPeginSender(TxSenderAddressTy return new PeginEvaluationResult(PeginProcessAction.CANNOT_BE_PROCESSED, LEGACY_PEGIN_UNDETERMINED_SENDER); } } + + public static Address getFlyoverAddress(NetworkParameters networkParameters, Keccak256 flyoverDerivationHash, Script redeemScript) { + Script flyoverScriptPubKey = getFlyoverScriptPubKey(flyoverDerivationHash, redeemScript); + + return Address.fromP2SHScript(networkParameters, flyoverScriptPubKey); + } + + public static Script getFlyoverScriptPubKey(Keccak256 flyoverDerivationHash, Script redeemScript) { + Script flyoverRedeemScript = FlyoverRedeemScriptBuilderImpl.builder().of( + flyoverDerivationHash, + redeemScript + ); + + return ScriptBuilder.createP2SHOutputScript(flyoverRedeemScript); + } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java index 131e7485a57..4ea6d74bc80 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -721,13 +721,8 @@ private void assertOneOutputIsToProposedFederationWithExpectedAmount(List svpFundTransactionUnsignedOutputs) { - Script redeemScriptWithFlyoverPrefix = FlyoverRedeemScriptBuilderImpl.builder().of( - bridgeMainNetConstants.getProposedFederationFlyoverPrefix(), - proposedFederation.getRedeemScript() - ); - Script proposedFederationWithFlyoverPrefixScriptPubKey = ScriptBuilder.createP2SHOutputScript( - redeemScriptWithFlyoverPrefix - ); + Script proposedFederationWithFlyoverPrefixScriptPubKey = + PegUtils.getFlyoverScriptPubKey(bridgeMainNetConstants.getProposedFederationFlyoverPrefix(), proposedFederation.getRedeemScript()); Optional outputToProposedFederationWithFlyoverPrefixOpt = searchForOutput( svpFundTransactionUnsignedOutputs, diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java index 4f11f52cda9..5b3e27e1513 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java @@ -18,16 +18,21 @@ import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import java.time.Instant; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.stream.Stream; import static co.rsk.peg.PegTestUtils.createFederation; +import static co.rsk.peg.PegUtils.getFlyoverAddress; +import static co.rsk.peg.PegUtils.getFlyoverScriptPubKey; import static co.rsk.peg.federation.FederationTestUtils.createP2shErpFederation; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -61,6 +66,34 @@ void init() { activeFederation = createP2shErpFederation(federationMainNetConstants, activeFedSigners); } + @ParameterizedTest + @MethodSource("derivationHashAndRedeemScriptArgs") + void getFlyoverScriptPubKey_fromRealValues_shouldReturnSameRealOutputScript(Keccak256 flyoverDerivationHash, Script redeemScript) { + Script scriptPubKey = getFlyoverScriptPubKey(flyoverDerivationHash, redeemScript); // OP_HASH160 outputScript OP_EQUAL + byte[] outputScript = Hex.decode("18fc3b52a5b7d5277f41b9765719b45bfa427730"); + + assertArrayEquals(outputScript, scriptPubKey.getPubKeyHash()); + } + + @ParameterizedTest + @MethodSource("derivationHashAndRedeemScriptArgs") + void getFlyoverAddress_fromRealValues_shouldReturnSameRealAddress(Keccak256 flyoverDerivationHash, Script redeemScript) { + Address flyoverAddress = Address.fromBase58(btcMainnetParams, "33y8JWrSe4byp3DKmy2Mkyykz2dzP8Lmvn"); + + assertEquals(flyoverAddress, getFlyoverAddress(btcMainnetParams, flyoverDerivationHash, redeemScript)); + } + + private static Stream derivationHashAndRedeemScriptArgs() { + // reference from https://mempool.space/tx/ffaebdabce5b1cc1b2ab95657cf087a67ade6a29ecc9ca7d4e2089e346a3e1b3 + + Keccak256 flyoverDerivationHash = new Keccak256("fc2bb93810d3d2332fed0b291c03822100a813eceaa0665896e0c82a8d500439"); + Script redeemScript = new Script(Hex.decode("645521020ace50bab1230f8002a0bfe619482af74b338cc9e4c956add228df47e6adae1c21025093f439fb8006fd29ab56605ffec9cdc840d16d2361004e1337a2f86d8bd2db210275d473555de2733c47125f9702b0f870df1d817379f5587f09b6c40ed2c6c9492102a95f095d0ce8cb3b9bf70cc837e3ebe1d107959b1fa3f9b2d8f33446f9c8cbdb2103250c11be0561b1d7ae168b1f59e39cbc1fd1ba3cf4d2140c1a365b2723a2bf9321034851379ec6b8a701bd3eef8a0e2b119abb4bdde7532a3d6bcbff291b0daf3f25210350179f143a632ce4e6ac9a755b82f7f4266cfebb116a42cadb104c2c2a3350f92103b04fbd87ef5e2c0946a684c8c93950301a45943bbe56d979602038698facf9032103b58a5da144f5abab2e03e414ad044b732300de52fa25c672a7f7b3588877190659ae670350cd00b275532102370a9838e4d15708ad14a104ee5606b36caaaaf739d833e67770ce9fd9b3ec80210257c293086c4d4fe8943deda5f890a37d11bebd140e220faa76258a41d077b4d42103c2660a46aa73078ee6016dee953488566426cf55fc8011edd0085634d75395f92103cd3e383ec6e12719a6c69515e5559bcbe037d0aa24c187e1e26ce932e22ad7b354ae68")); + + return Stream.of( + Arguments.of(flyoverDerivationHash, redeemScript) + ); + } + @Test void test_getTransactionType_before_tbd_600() { // Arrange