From 651a9453298bab02810c6a97861d2f1a3ff00af9 Mon Sep 17 00:00:00 2001 From: Volodymyr Kravets Date: Tue, 16 Jan 2024 15:20:53 +0200 Subject: [PATCH 001/137] Made bucketSize value configurable --- rskj-core/src/main/java/co/rsk/RskContext.java | 3 ++- .../src/main/java/co/rsk/config/RskSystemProperties.java | 6 ++++++ rskj-core/src/main/resources/expected.conf | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/java/co/rsk/RskContext.java b/rskj-core/src/main/java/co/rsk/RskContext.java index 2d6f24fa06c..a73129564ce 100644 --- a/rskj-core/src/main/java/co/rsk/RskContext.java +++ b/rskj-core/src/main/java/co/rsk/RskContext.java @@ -1588,10 +1588,11 @@ protected PeerExplorer getPeerExplorer() { initialBootNodes.add(address.getHostName() + ":" + address.getPort()); } } + int bucketSize = rskSystemProperties.discoveryBucketSize(); peerExplorer = new PeerExplorer( initialBootNodes, localNode, - new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, localNode), + new NodeDistanceTable(KademliaOptions.BINS, bucketSize, localNode), key, rskSystemProperties.peerDiscoveryMessageTimeOut(), rskSystemProperties.peerDiscoveryRefreshPeriod(), diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index ad411a32043..aba915edfcd 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -19,6 +19,7 @@ package co.rsk.config; import co.rsk.core.RskAddress; +import co.rsk.net.discovery.table.KademliaOptions; import co.rsk.rpc.ModuleDescription; import com.typesafe.config.Config; import com.typesafe.config.ConfigObject; @@ -54,6 +55,7 @@ public class RskSystemProperties extends SystemProperties { private static final String RPC_MODULES_PATH = "rpc.modules"; private static final String RPC_ETH_GET_LOGS_MAX_BLOCKS_TO_QUERY = "rpc.logs.maxBlocksToQuery"; private static final String RPC_ETH_GET_LOGS_MAX_LOGS_TO_RETURN = "rpc.logs.maxLogsToReturn"; + private static final String DISCOVERY_BUCKET_SIZE = "peer.discovery.bucketSize"; private static final int CHUNK_SIZE = 192; @@ -249,6 +251,10 @@ public boolean allowMultipleConnectionsPerHostPort() { return getBoolean("peer.discovery.allowMultipleConnectionsPerHostPort", true); } + public int discoveryBucketSize() { + return getInt(DISCOVERY_BUCKET_SIZE, KademliaOptions.BUCKET_SIZE); + } + public List getRpcModules() { if (this.moduleDescriptions != null) { return this.moduleDescriptions; diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index dec928794e5..9714c4b5421 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -135,6 +135,7 @@ peer = { msg.timeout = refresh.period = allowMultipleConnectionsPerHostPort = + bucketSize = } port = networkId = From 54eea818c51d5f80b5aa44466dbda8bc862042ec Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Wed, 17 Jan 2024 19:07:12 -0300 Subject: [PATCH 002/137] fix eth_getStorage non existing key response --- .../co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java | 2 ++ .../src/main/java/org/ethereum/rpc/Web3Impl.java | 3 ++- .../test/java/org/ethereum/rpc/Web3ImplTest.java | 14 +++++++------- .../java/org/ethereum/rpc/Web3ImplUnitTest.java | 3 +-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java index dbb8029ed5e..d15decdc701 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java @@ -107,6 +107,8 @@ protected void channelRead0(ChannelHandlerContext ctx, ByteBufHolder request) th int errorCode = ErrorResolver.JsonError.CUSTOM_SERVER_ERROR_LOWER; responseContent = buildErrorContent(errorCode, unexpectedErrorMsg); responseCode = errorCode; + } finally { + ReflectionUtil.clearCache(); } ctx.fireChannelRead(new Web3Result( diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index 1c224f659d3..f9057787f13 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -86,6 +86,7 @@ public class Web3Impl implements Web3 { private static final Logger logger = LoggerFactory.getLogger("web3"); private static final String CLIENT_VERSION_PREFIX = "RskJ"; + private static final String NON_EXISTING_KEY_RESPONSE = "0x0000000000000000000000000000000000000000000000000000000000000000"; private final MinerClient minerClient; private final MinerServer minerServer; @@ -487,7 +488,7 @@ private String eth_getStorageAt(HexAddressParam address, HexNumberParam storageI .getStorageValue(addr, DataWord.valueOf(HexUtils.strHexOrStrNumberToByteArray(storageIdx.getHexNumber()))); if (sv == null) { - s = "0x0"; + s = NON_EXISTING_KEY_RESPONSE; } else { s = HexUtils.toUnformattedJsonHex(sv.getData()); } diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index f8ac098dfff..1ac91726598 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -107,9 +107,9 @@ * Created by Ruben Altman on 09/06/2016. */ class Web3ImplTest { - private static final String BALANCE_10K_HEX = "0x2710"; //10.000 private static final String CALL_RESPOND = "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"; + private static final String NON_EXISTING_KEY_RESPONSE = "0x0000000000000000000000000000000000000000000000000000000000000000"; private final TestSystemProperties config = new TestSystemProperties(); private final BlockFactory blockFactory = new BlockFactory(config.getActivationConfig()); @@ -367,7 +367,7 @@ void getBalanceWithAccountAndBlockWithTransaction() { //[ "0x
", { "blockNumber": "0x0" } -> return storage at given address in genesis block void getStorageAtAccountAndBlockNumber() { final ChainParams chain = chainWithAccount10kBalance(false); - assertByBlockNumber("0x0", blockRef -> chain.web3.eth_getStorageAt( + assertByBlockNumber(NON_EXISTING_KEY_RESPONSE, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -377,7 +377,7 @@ void getStorageAtAccountAndBlockNumber() { //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" } -> return storage at given address in genesis block void getStorageAtAccountAndBlockHash() { final ChainParams chain = chainWithAccount10kBalance(false); - assertByBlockHash("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertByBlockHash(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -428,7 +428,7 @@ void getStorageAtAccountAndNonCanonicalBlockHashWhenCanonicalIsRequired() { //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": true } -> return storage at given address in genesis block void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertCanonicalBlockHashWhenCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertCanonicalBlockHashWhenCanonical(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -438,7 +438,7 @@ void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsRequired() { //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": false } -> return storage at given address in genesis block void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertCanonicalBlockHashWhenNotCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertCanonicalBlockHashWhenNotCanonical(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -448,7 +448,7 @@ void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsNotRequired() { // [ "0x
", { "blockHash": "0x", "requireCanonical": false } -> return storage at given address in specified block void getStorageAtAccountAndNonCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHashWhenNotCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertNonCanonicalBlockHashWhenNotCanonical(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -458,7 +458,7 @@ void getStorageAtAccountAndNonCanonicalBlockHashWhenCanonicalIsNotRequired() { // [ "0x
", { "blockHash": "0x" } -> return storage at given address in specified bloc void getStorageAtAccountAndNonCanonicalBlockHash() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHash("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertNonCanonicalBlockHash(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java index 6dfe17b61fd..5c1d7db144c 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java @@ -222,8 +222,7 @@ void eth_getStorageAtEmptyCell() { .thenReturn(null); String result = target.eth_getStorageAt(hexAddressParam, hexNumberParam, blockRefParam); - assertEquals("0x0", - result); + assertEquals("0x0000000000000000000000000000000000000000000000000000000000000000", result); } @Test From 34938e181025cc580f547268d2cc451e98be3e61 Mon Sep 17 00:00:00 2001 From: Volodymyr Kravets Date: Thu, 25 Jan 2024 14:00:49 +0200 Subject: [PATCH 003/137] Changed version to v5.4.0 --- rskj-core/src/main/resources/version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rskj-core/src/main/resources/version.properties b/rskj-core/src/main/resources/version.properties index f093fc930f4..08b5b7f5e05 100644 --- a/rskj-core/src/main/resources/version.properties +++ b/rskj-core/src/main/resources/version.properties @@ -1,2 +1,2 @@ -versionNumber='6.0.0' +versionNumber='5.4.0' modifier="RC" From 37c8b14bd5b43604dce95ebe27f8d55df26d9a1a Mon Sep 17 00:00:00 2001 From: Volodymyr Kravets Date: Thu, 25 Jan 2024 14:58:16 +0200 Subject: [PATCH 004/137] Changed modifier to FINGERROOT for v5.4.0 --- rskj-core/src/main/resources/version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rskj-core/src/main/resources/version.properties b/rskj-core/src/main/resources/version.properties index 08b5b7f5e05..fc17b52d272 100644 --- a/rskj-core/src/main/resources/version.properties +++ b/rskj-core/src/main/resources/version.properties @@ -1,2 +1,2 @@ versionNumber='5.4.0' -modifier="RC" +modifier="FINGERROOT" From 77b31222eb852bac41cf03d837d80d178df8b62d Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Wed, 3 Jan 2024 10:32:56 -0400 Subject: [PATCH 005/137] Add user defined gas price buffer --- .../org/ethereum/facade/EthereumImpl.java | 10 ++++++ .../main/java/org/ethereum/util/Utils.java | 24 ++++++++++++++ rskj-core/src/main/resources/gas-price.conf | 1 + .../org/ethereum/facade/EthereumImplTest.java | 33 +++++++++++++++++++ .../java/org/ethereum/util/UtilsTest.java | 19 +++++++++++ rskj-core/src/test/resources/gas-price.conf | 1 + .../loadProperties/test-props-1.conf | 2 ++ .../loadProperties/test-props-empty.conf | 1 + 8 files changed, 91 insertions(+) create mode 100644 rskj-core/src/main/resources/gas-price.conf create mode 100644 rskj-core/src/test/resources/gas-price.conf create mode 100644 rskj-core/src/test/resources/loadProperties/test-props-1.conf create mode 100644 rskj-core/src/test/resources/loadProperties/test-props-empty.conf diff --git a/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index 8b3cec0a317..eab5fe94368 100644 --- a/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -26,9 +26,11 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.listener.GasPriceTracker; import org.ethereum.net.server.ChannelManager; +import org.ethereum.util.Utils; import javax.annotation.Nonnull; import java.math.BigDecimal; +import java.util.Properties; public class EthereumImpl implements Ethereum { @@ -84,6 +86,14 @@ public TransactionPoolAddResult submitTransaction(Transaction transaction) { @Override public Coin getGasPrice() { + Properties props = Utils.getPropertiesFromFile("gas-price"); + String gasPrice = props.getProperty("gasPrice"); + + if(gasPrice != null && !gasPrice.isEmpty()) { + long gasPriceLong = Long.parseLong(gasPrice); + return Coin.valueOf(gasPriceLong); + } + if (gasPriceTracker.isFeeMarketWorking()) { return gasPriceTracker.getGasPrice(); } diff --git a/rskj-core/src/main/java/org/ethereum/util/Utils.java b/rskj-core/src/main/java/org/ethereum/util/Utils.java index a703c2d131c..3fba0c5a39b 100644 --- a/rskj-core/src/main/java/org/ethereum/util/Utils.java +++ b/rskj-core/src/main/java/org/ethereum/util/Utils.java @@ -21,7 +21,10 @@ import org.bouncycastle.util.encoders.DecoderException; import org.bouncycastle.util.encoders.Hex; +import org.ethereum.facade.EthereumImpl; +import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Array; import java.math.BigInteger; import java.nio.charset.StandardCharsets; @@ -30,6 +33,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.Properties; import java.util.regex.Pattern; @@ -255,4 +259,24 @@ public static int significantBitCount(int number) { } return result; } + + /** + * Return the properties contained in the specified configuration file + * + * @param String the file name, and path if it is inside a sub-folder + * @return Properties the properties found in the file + */ + public static Properties getPropertiesFromFile(String name) { + try (InputStream inputStream = EthereumImpl.class.getClassLoader().getResourceAsStream(name + ".conf")) { + if (inputStream == null) { + throw new IllegalStateException("Configuration file not found for name: " + name); + } + + Properties props = new Properties(); + props.load(inputStream); + return props; + } catch (IOException e) { // NOSONAR + throw new IllegalStateException("Could not get properties from: " + name); + } + } } diff --git a/rskj-core/src/main/resources/gas-price.conf b/rskj-core/src/main/resources/gas-price.conf new file mode 100644 index 00000000000..9b2158af865 --- /dev/null +++ b/rskj-core/src/main/resources/gas-price.conf @@ -0,0 +1 @@ +gasPrice = \ No newline at end of file diff --git a/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java b/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java index 1502e7069cc..9cf6b2f1587 100644 --- a/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java @@ -22,7 +22,13 @@ import org.ethereum.core.Blockchain; import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.GasPriceTracker; +import org.ethereum.util.Utils; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import org.mockito.MockedStatic; +import org.mockito.Mockito; + +import java.util.Properties; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; @@ -30,6 +36,10 @@ class EthereumImplTest { + @AfterEach + void resetMocks() { + Mockito.reset(); + } @Test void getGasPrice_returns_GasPriceTrackerValue_when_feeMarketWorking_is_true() { @@ -60,4 +70,27 @@ void getGasPrice_returns_correctedBestBlockValue_when_feeMarketWorking_is_false( assertEquals(12, price.asBigInteger().intValue()); } + + @Test + void getGasPrice_returns_user_defined_value_when_property_is_set() { + GasPriceTracker gasPriceTracker = mock(GasPriceTracker.class); + Blockchain blockchain = mock(Blockchain.class); + MockedStatic utils = Mockito.mockStatic(Utils.class); + double minGasPriceMultiplier = 1.2; + Properties testProperties = new Properties(); + testProperties.setProperty("gasPrice", "15"); + + + utils.when(() -> Utils.getPropertiesFromFile("gas-price")) + .thenReturn(testProperties); + + Ethereum ethereum = new EthereumImpl(null, null, new CompositeEthereumListener(), blockchain, gasPriceTracker, minGasPriceMultiplier); + Coin price = ethereum.getGasPrice(); + + assertEquals(15, price.asBigInteger().intValue()); + + if(!utils.isClosed()) { + utils.close(); + } + } } \ No newline at end of file diff --git a/rskj-core/src/test/java/org/ethereum/util/UtilsTest.java b/rskj-core/src/test/java/org/ethereum/util/UtilsTest.java index a42711cb4ec..8163031e11d 100644 --- a/rskj-core/src/test/java/org/ethereum/util/UtilsTest.java +++ b/rskj-core/src/test/java/org/ethereum/util/UtilsTest.java @@ -27,6 +27,7 @@ import org.bouncycastle.util.encoders.Hex; import java.math.BigInteger; +import java.util.Properties; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; @@ -297,4 +298,22 @@ void significantBitCount() { Assertions.assertEquals(13, Utils.significantBitCount(0b1000111000101)); Assertions.assertEquals(9, Utils.significantBitCount(0b000111000101)); } + + @Test + void getPropertiesFromFile() { + Properties properties = Utils.getPropertiesFromFile("loadProperties/test-props-1"); + + Assertions.assertEquals(2, properties.size()); + Assertions.assertEquals("1000", properties.getProperty("testGasPrice")); + Assertions.assertEquals("testName", properties.getProperty("testName")); + } + + @Test + void getPropertiesFromFile_empty_properties() { + Properties properties = Utils.getPropertiesFromFile("loadProperties/test-props-empty"); + + Assertions.assertEquals(1, properties.size()); + Assertions.assertEquals("", properties.getProperty("testGasPrice")); + Assertions.assertNull(properties.getProperty("testName")); + } } diff --git a/rskj-core/src/test/resources/gas-price.conf b/rskj-core/src/test/resources/gas-price.conf new file mode 100644 index 00000000000..9b2158af865 --- /dev/null +++ b/rskj-core/src/test/resources/gas-price.conf @@ -0,0 +1 @@ +gasPrice = \ No newline at end of file diff --git a/rskj-core/src/test/resources/loadProperties/test-props-1.conf b/rskj-core/src/test/resources/loadProperties/test-props-1.conf new file mode 100644 index 00000000000..d35df3d54e6 --- /dev/null +++ b/rskj-core/src/test/resources/loadProperties/test-props-1.conf @@ -0,0 +1,2 @@ +testGasPrice = 1000 +testName = testName \ No newline at end of file diff --git a/rskj-core/src/test/resources/loadProperties/test-props-empty.conf b/rskj-core/src/test/resources/loadProperties/test-props-empty.conf new file mode 100644 index 00000000000..b512c980f18 --- /dev/null +++ b/rskj-core/src/test/resources/loadProperties/test-props-empty.conf @@ -0,0 +1 @@ +testGasPrice = \ No newline at end of file From 0ff7f5dd2b09a127b79d3d611c9699f24eba2e0d Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Wed, 3 Jan 2024 11:45:02 -0400 Subject: [PATCH 006/137] Add check to handle cases when the config file is not found --- .../org/ethereum/facade/EthereumImpl.java | 24 +++++++++++++++---- .../main/java/org/ethereum/util/Utils.java | 6 ++--- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index eab5fe94368..cb9d9fa7bec 100644 --- a/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -86,12 +86,10 @@ public TransactionPoolAddResult submitTransaction(Transaction transaction) { @Override public Coin getGasPrice() { - Properties props = Utils.getPropertiesFromFile("gas-price"); - String gasPrice = props.getProperty("gasPrice"); + Long gasPrice = getGasPriceFromConfig(); - if(gasPrice != null && !gasPrice.isEmpty()) { - long gasPriceLong = Long.parseLong(gasPrice); - return Coin.valueOf(gasPriceLong); + if(gasPrice != null) { + return Coin.valueOf(gasPrice); } if (gasPriceTracker.isFeeMarketWorking()) { @@ -100,4 +98,20 @@ public Coin getGasPrice() { double estimatedGasPrice = blockchain.getBestBlock().getMinimumGasPrice().asBigInteger().doubleValue() * minGasPriceMultiplier; return new Coin(BigDecimal.valueOf(estimatedGasPrice).toBigInteger()); } + + private Long getGasPriceFromConfig() { + Properties properties = Utils.getPropertiesFromFile("gas-price"); + + if(properties == null) { + return null; + } + + String gasPrice = properties.getProperty("gasPrice"); + + if(gasPrice != null && !gasPrice.isEmpty()) { + return Long.parseLong(gasPrice); + } + + return null; + } } diff --git a/rskj-core/src/main/java/org/ethereum/util/Utils.java b/rskj-core/src/main/java/org/ethereum/util/Utils.java index 3fba0c5a39b..55b42f6a60c 100644 --- a/rskj-core/src/main/java/org/ethereum/util/Utils.java +++ b/rskj-core/src/main/java/org/ethereum/util/Utils.java @@ -263,13 +263,13 @@ public static int significantBitCount(int number) { /** * Return the properties contained in the specified configuration file * - * @param String the file name, and path if it is inside a sub-folder - * @return Properties the properties found in the file + * @param name String the file name, and path if it is inside a sub-folder + * @return Properties the properties found in the file or null if no file was found */ public static Properties getPropertiesFromFile(String name) { try (InputStream inputStream = EthereumImpl.class.getClassLoader().getResourceAsStream(name + ".conf")) { if (inputStream == null) { - throw new IllegalStateException("Configuration file not found for name: " + name); + return null; } Properties props = new Properties(); From 3eb849445e716bf67038f58ed34b780a42db1963 Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Wed, 3 Jan 2024 11:49:19 -0400 Subject: [PATCH 007/137] Add EOF lines --- rskj-core/src/main/resources/gas-price.conf | 2 +- .../src/test/java/org/ethereum/facade/EthereumImplTest.java | 2 +- rskj-core/src/test/resources/gas-price.conf | 2 +- rskj-core/src/test/resources/loadProperties/test-props-1.conf | 2 +- .../src/test/resources/loadProperties/test-props-empty.conf | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rskj-core/src/main/resources/gas-price.conf b/rskj-core/src/main/resources/gas-price.conf index 9b2158af865..f7e6ca3eb46 100644 --- a/rskj-core/src/main/resources/gas-price.conf +++ b/rskj-core/src/main/resources/gas-price.conf @@ -1 +1 @@ -gasPrice = \ No newline at end of file +gasPrice = diff --git a/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java b/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java index 9cf6b2f1587..d53a1c268ec 100644 --- a/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java @@ -93,4 +93,4 @@ void getGasPrice_returns_user_defined_value_when_property_is_set() { utils.close(); } } -} \ No newline at end of file +} diff --git a/rskj-core/src/test/resources/gas-price.conf b/rskj-core/src/test/resources/gas-price.conf index 9b2158af865..f7e6ca3eb46 100644 --- a/rskj-core/src/test/resources/gas-price.conf +++ b/rskj-core/src/test/resources/gas-price.conf @@ -1 +1 @@ -gasPrice = \ No newline at end of file +gasPrice = diff --git a/rskj-core/src/test/resources/loadProperties/test-props-1.conf b/rskj-core/src/test/resources/loadProperties/test-props-1.conf index d35df3d54e6..1c34ee1379d 100644 --- a/rskj-core/src/test/resources/loadProperties/test-props-1.conf +++ b/rskj-core/src/test/resources/loadProperties/test-props-1.conf @@ -1,2 +1,2 @@ testGasPrice = 1000 -testName = testName \ No newline at end of file +testName = testName diff --git a/rskj-core/src/test/resources/loadProperties/test-props-empty.conf b/rskj-core/src/test/resources/loadProperties/test-props-empty.conf index b512c980f18..955b5203d14 100644 --- a/rskj-core/src/test/resources/loadProperties/test-props-empty.conf +++ b/rskj-core/src/test/resources/loadProperties/test-props-empty.conf @@ -1 +1 @@ -testGasPrice = \ No newline at end of file +testGasPrice = From 9ad05536e630f0fa9fbfba876918f9834c4e3ccc Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Fri, 5 Jan 2024 10:54:28 -0400 Subject: [PATCH 008/137] Remove previous changes and add new approach --- .../src/main/java/co/rsk/RskContext.java | 5 +++- .../co/rsk/config/RskSystemProperties.java | 15 +++++++++++ .../org/ethereum/facade/EthereumImpl.java | 24 ----------------- .../ethereum/listener/GasPriceTracker.java | 13 ++++++--- .../main/java/org/ethereum/util/Utils.java | 25 ----------------- rskj-core/src/main/resources/expected.conf | 1 + rskj-core/src/main/resources/gas-price.conf | 1 - rskj-core/src/main/resources/reference.conf | 4 +++ .../rsk/config/RskSystemPropertiesTest.java | 27 +++++++++++++++++++ .../org/ethereum/facade/EthereumImplTest.java | 27 ------------------- .../listener/GasPriceTrackerTest.java | 15 +++++++++++ .../java/org/ethereum/util/UtilsTest.java | 19 ------------- rskj-core/src/test/resources/gas-price.conf | 1 - .../loadProperties/test-props-1.conf | 2 -- .../loadProperties/test-props-empty.conf | 1 - rskj-core/src/test/resources/test-rskj.conf | 1 + 16 files changed, 77 insertions(+), 104 deletions(-) delete mode 100644 rskj-core/src/main/resources/gas-price.conf delete mode 100644 rskj-core/src/test/resources/gas-price.conf delete mode 100644 rskj-core/src/test/resources/loadProperties/test-props-1.conf delete mode 100644 rskj-core/src/test/resources/loadProperties/test-props-empty.conf diff --git a/rskj-core/src/main/java/co/rsk/RskContext.java b/rskj-core/src/main/java/co/rsk/RskContext.java index 2d6f24fa06c..14e172c5ca0 100644 --- a/rskj-core/src/main/java/co/rsk/RskContext.java +++ b/rskj-core/src/main/java/co/rsk/RskContext.java @@ -131,6 +131,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.*; +import java.math.BigInteger; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -555,8 +556,10 @@ public synchronized Ethereum getRsk() { public GasPriceTracker getGasPriceTracker() { checkIfNotClosed(); + BigInteger gasPriceBuffer = getRskSystemProperties().gasPriceBuffer(); + if (this.gasPriceTracker == null) { - this.gasPriceTracker = GasPriceTracker.create(getBlockStore()); + this.gasPriceTracker = GasPriceTracker.create(getBlockStore(), gasPriceBuffer); } return this.gasPriceTracker; } diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index ad411a32043..f69577f2573 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -31,6 +31,7 @@ import org.ethereum.crypto.HashUtil; import javax.annotation.Nullable; +import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.*; @@ -185,6 +186,20 @@ public boolean isWalletEnabled() { return getBoolean("wallet.enabled", false); } + public BigInteger gasPriceBuffer() { + String gasPriceBuffer = getString("miner.gasPriceBuffer", ""); + + if(!gasPriceBuffer.isEmpty()) { + try { + return new BigInteger(gasPriceBuffer); + } catch (NumberFormatException e) { + throw new NumberFormatException("Invalid gasPriceBuffer value in config file"); + } + } + + return null; + } + public List walletAccounts() { if (!configFromFiles.hasPath("wallet.accounts")) { return Collections.emptyList(); diff --git a/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java b/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java index cb9d9fa7bec..8b3cec0a317 100644 --- a/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java +++ b/rskj-core/src/main/java/org/ethereum/facade/EthereumImpl.java @@ -26,11 +26,9 @@ import org.ethereum.listener.EthereumListener; import org.ethereum.listener.GasPriceTracker; import org.ethereum.net.server.ChannelManager; -import org.ethereum.util.Utils; import javax.annotation.Nonnull; import java.math.BigDecimal; -import java.util.Properties; public class EthereumImpl implements Ethereum { @@ -86,32 +84,10 @@ public TransactionPoolAddResult submitTransaction(Transaction transaction) { @Override public Coin getGasPrice() { - Long gasPrice = getGasPriceFromConfig(); - - if(gasPrice != null) { - return Coin.valueOf(gasPrice); - } - if (gasPriceTracker.isFeeMarketWorking()) { return gasPriceTracker.getGasPrice(); } double estimatedGasPrice = blockchain.getBestBlock().getMinimumGasPrice().asBigInteger().doubleValue() * minGasPriceMultiplier; return new Coin(BigDecimal.valueOf(estimatedGasPrice).toBigInteger()); } - - private Long getGasPriceFromConfig() { - Properties properties = Utils.getPropertiesFromFile("gas-price"); - - if(properties == null) { - return null; - } - - String gasPrice = properties.getProperty("gasPrice"); - - if(gasPrice != null && !gasPrice.isEmpty()) { - return Long.parseLong(gasPrice); - } - - return null; - } } diff --git a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java index 964a6f30015..a2a3db711ea 100644 --- a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java +++ b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java @@ -60,6 +60,7 @@ public class GasPriceTracker extends EthereumListenerAdapter { private final AtomicReference bestBlockPriceRef = new AtomicReference<>(); private final BlockStore blockStore; + private final BigInteger configBuffer; private Coin defaultPrice = Coin.valueOf(20_000_000_000L); private int txIdx = TX_WINDOW_SIZE - 1; @@ -68,12 +69,17 @@ public class GasPriceTracker extends EthereumListenerAdapter { private Coin lastVal; - private GasPriceTracker(BlockStore blockStore) { + private GasPriceTracker(BlockStore blockStore, BigInteger configBuffer) { this.blockStore = blockStore; + this.configBuffer = configBuffer; } public static GasPriceTracker create(BlockStore blockStore) { - GasPriceTracker gasPriceTracker = new GasPriceTracker(blockStore); + return create(blockStore, null); + } + + public static GasPriceTracker create(BlockStore blockStore, BigInteger configBuffer) { + GasPriceTracker gasPriceTracker = new GasPriceTracker(blockStore, configBuffer); gasPriceTracker.initializeWindowsFromDB(); return gasPriceTracker; } @@ -122,7 +128,8 @@ public synchronized Coin getGasPrice() { return lastVal; } - return Coin.max(lastVal, bestBlockPrice.multiply(BI_11).divide(BI_10)); + return Coin.max(lastVal, bestBlockPrice.multiply(BI_11) + .divide(configBuffer == null ? BI_10 : configBuffer)); } public synchronized boolean isFeeMarketWorking() { diff --git a/rskj-core/src/main/java/org/ethereum/util/Utils.java b/rskj-core/src/main/java/org/ethereum/util/Utils.java index 55b42f6a60c..a2d23853a51 100644 --- a/rskj-core/src/main/java/org/ethereum/util/Utils.java +++ b/rskj-core/src/main/java/org/ethereum/util/Utils.java @@ -21,10 +21,6 @@ import org.bouncycastle.util.encoders.DecoderException; import org.bouncycastle.util.encoders.Hex; -import org.ethereum.facade.EthereumImpl; - -import java.io.IOException; -import java.io.InputStream; import java.lang.reflect.Array; import java.math.BigInteger; import java.nio.charset.StandardCharsets; @@ -33,7 +29,6 @@ import java.util.Arrays; import java.util.Date; import java.util.List; -import java.util.Properties; import java.util.regex.Pattern; @@ -259,24 +254,4 @@ public static int significantBitCount(int number) { } return result; } - - /** - * Return the properties contained in the specified configuration file - * - * @param name String the file name, and path if it is inside a sub-folder - * @return Properties the properties found in the file or null if no file was found - */ - public static Properties getPropertiesFromFile(String name) { - try (InputStream inputStream = EthereumImpl.class.getClassLoader().getResourceAsStream(name + ".conf")) { - if (inputStream == null) { - return null; - } - - Properties props = new Properties(); - props.load(inputStream); - return props; - } catch (IOException e) { // NOSONAR - throw new IllegalStateException("Could not get properties from: " + name); - } - } } diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index dec928794e5..c4d58a2999a 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -168,6 +168,7 @@ wallet = { miner = { gasUnitInDollars = minGasPrice = + gasPriceBuffer = server = { enabled = isFixedClock = diff --git a/rskj-core/src/main/resources/gas-price.conf b/rskj-core/src/main/resources/gas-price.conf deleted file mode 100644 index f7e6ca3eb46..00000000000 --- a/rskj-core/src/main/resources/gas-price.conf +++ /dev/null @@ -1 +0,0 @@ -gasPrice = diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 39823139df6..d10f8ba6caf 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -166,6 +166,10 @@ miner { # The default gas price minGasPrice = 0 + # This property can be set to a numeric value by the node operator to over write the gas price buffer + # used to calculate the gas price returned by eth_gasPrice + gasPriceBuffer = null + server { enabled = false isFixedClock = false diff --git a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java index 93ad1a41983..56006cc86e9 100644 --- a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java +++ b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java @@ -23,10 +23,12 @@ import co.rsk.rpc.ModuleDescription; import com.typesafe.config.Config; import com.typesafe.config.ConfigFactory; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; +import java.math.BigInteger; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -223,4 +225,29 @@ void testGetRpcModulesWithObject() { assertEquals(9000, netModule.getTimeout()); assertEquals(30000, netModule.getMethodTimeout("eth_getBlockByHash")); } + + @Test + void testGasPriceBuffer() { + assertEquals(BigInteger.valueOf(5), config.gasPriceBuffer()); + } + + @Test + void testGasPriceBufferWithNull() { + TestSystemProperties testSystemProperties = new TestSystemProperties(rawConfig -> + ConfigFactory.parseString("{" + + "miner.gasPriceBuffer = null" + + " }").withFallback(rawConfig)); + + assertNull(testSystemProperties.gasPriceBuffer()); + } + + @Test + void testGasPriceBufferThrowsError() { + TestSystemProperties testSystemProperties = new TestSystemProperties(rawConfig -> + ConfigFactory.parseString("{" + + "miner.gasPriceBuffer = invalid" + + " }").withFallback(rawConfig)); + + Assertions.assertThrows(NumberFormatException.class, testSystemProperties::gasPriceBuffer); + } } diff --git a/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java b/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java index d53a1c268ec..afd468a1352 100644 --- a/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java @@ -22,14 +22,10 @@ import org.ethereum.core.Blockchain; import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.GasPriceTracker; -import org.ethereum.util.Utils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; import org.mockito.Mockito; -import java.util.Properties; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -70,27 +66,4 @@ void getGasPrice_returns_correctedBestBlockValue_when_feeMarketWorking_is_false( assertEquals(12, price.asBigInteger().intValue()); } - - @Test - void getGasPrice_returns_user_defined_value_when_property_is_set() { - GasPriceTracker gasPriceTracker = mock(GasPriceTracker.class); - Blockchain blockchain = mock(Blockchain.class); - MockedStatic utils = Mockito.mockStatic(Utils.class); - double minGasPriceMultiplier = 1.2; - Properties testProperties = new Properties(); - testProperties.setProperty("gasPrice", "15"); - - - utils.when(() -> Utils.getPropertiesFromFile("gas-price")) - .thenReturn(testProperties); - - Ethereum ethereum = new EthereumImpl(null, null, new CompositeEthereumListener(), blockchain, gasPriceTracker, minGasPriceMultiplier); - Coin price = ethereum.getGasPrice(); - - assertEquals(15, price.asBigInteger().intValue()); - - if(!utils.isClosed()) { - utils.close(); - } - } } diff --git a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java index 35e9134cd6d..d8dec3b75f4 100644 --- a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java +++ b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java @@ -150,6 +150,21 @@ void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_ReturnsBest assertEquals(Coin.valueOf(55_000_000_000L), actualResult); } + @Test + void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_GasPriceBufferOverWritten_ReturnsBestBlockAdjustedPriceWithNewBuffer() { + GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, BigInteger.valueOf(5)); + + Block bestBlock = makeBlock(Coin.valueOf(50_000_000_000L), 0, i -> null); + Block block = makeBlock(Coin.valueOf(30_000_000_000L), TOTAL_SLOTS, i -> makeTx(Coin.valueOf(40_000_000_000L))); + + gasPriceTracker.onBestBlock(bestBlock, Collections.emptyList()); + gasPriceTracker.onBlock(block, Collections.emptyList()); + + Coin actualResult = gasPriceTracker.getGasPrice(); + + assertEquals(Coin.valueOf(110_000_000_000L), actualResult); + } + @Test void isFeeMarketWorking_falseWhenNotEnoughBlocks() { GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore); diff --git a/rskj-core/src/test/java/org/ethereum/util/UtilsTest.java b/rskj-core/src/test/java/org/ethereum/util/UtilsTest.java index 8163031e11d..a42711cb4ec 100644 --- a/rskj-core/src/test/java/org/ethereum/util/UtilsTest.java +++ b/rskj-core/src/test/java/org/ethereum/util/UtilsTest.java @@ -27,7 +27,6 @@ import org.bouncycastle.util.encoders.Hex; import java.math.BigInteger; -import java.util.Properties; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; @@ -298,22 +297,4 @@ void significantBitCount() { Assertions.assertEquals(13, Utils.significantBitCount(0b1000111000101)); Assertions.assertEquals(9, Utils.significantBitCount(0b000111000101)); } - - @Test - void getPropertiesFromFile() { - Properties properties = Utils.getPropertiesFromFile("loadProperties/test-props-1"); - - Assertions.assertEquals(2, properties.size()); - Assertions.assertEquals("1000", properties.getProperty("testGasPrice")); - Assertions.assertEquals("testName", properties.getProperty("testName")); - } - - @Test - void getPropertiesFromFile_empty_properties() { - Properties properties = Utils.getPropertiesFromFile("loadProperties/test-props-empty"); - - Assertions.assertEquals(1, properties.size()); - Assertions.assertEquals("", properties.getProperty("testGasPrice")); - Assertions.assertNull(properties.getProperty("testName")); - } } diff --git a/rskj-core/src/test/resources/gas-price.conf b/rskj-core/src/test/resources/gas-price.conf deleted file mode 100644 index f7e6ca3eb46..00000000000 --- a/rskj-core/src/test/resources/gas-price.conf +++ /dev/null @@ -1 +0,0 @@ -gasPrice = diff --git a/rskj-core/src/test/resources/loadProperties/test-props-1.conf b/rskj-core/src/test/resources/loadProperties/test-props-1.conf deleted file mode 100644 index 1c34ee1379d..00000000000 --- a/rskj-core/src/test/resources/loadProperties/test-props-1.conf +++ /dev/null @@ -1,2 +0,0 @@ -testGasPrice = 1000 -testName = testName diff --git a/rskj-core/src/test/resources/loadProperties/test-props-empty.conf b/rskj-core/src/test/resources/loadProperties/test-props-empty.conf deleted file mode 100644 index 955b5203d14..00000000000 --- a/rskj-core/src/test/resources/loadProperties/test-props-empty.conf +++ /dev/null @@ -1 +0,0 @@ -testGasPrice = diff --git a/rskj-core/src/test/resources/test-rskj.conf b/rskj-core/src/test/resources/test-rskj.conf index 1942a23e680..b616f23bea7 100644 --- a/rskj-core/src/test/resources/test-rskj.conf +++ b/rskj-core/src/test/resources/test-rskj.conf @@ -161,6 +161,7 @@ vm.structured.storage.dictionary.enabled = false miner.client.enabled = false miner.server.enabled = false +miner.gasPriceBuffer = 5 # eth sync process sync { From 7b0652ea082b48a992d12021642765db595574de Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Fri, 5 Jan 2024 13:08:57 -0400 Subject: [PATCH 009/137] Update gas price buffer calculation values --- .../java/co/rsk/config/RskSystemProperties.java | 15 ++++++--------- .../org/ethereum/listener/GasPriceTracker.java | 14 +++++++------- rskj-core/src/main/resources/reference.conf | 2 +- .../co/rsk/config/RskSystemPropertiesTest.java | 8 +++++--- .../ethereum/listener/GasPriceTrackerTest.java | 4 ++-- rskj-core/src/test/resources/test-rskj.conf | 2 +- 6 files changed, 22 insertions(+), 23 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index f69577f2573..7e88a569bd9 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -52,6 +52,7 @@ public class RskSystemProperties extends SystemProperties { private static final String MINER_REWARD_ADDRESS_CONFIG = "miner.reward.address"; private static final String MINER_COINBASE_SECRET_CONFIG = "miner.coinbase.secret"; + private static final String MINER_GAS_PRICE_BUFFER_CONFIG = "miner.gasPriceBuffer"; private static final String RPC_MODULES_PATH = "rpc.modules"; private static final String RPC_ETH_GET_LOGS_MAX_BLOCKS_TO_QUERY = "rpc.logs.maxBlocksToQuery"; private static final String RPC_ETH_GET_LOGS_MAX_LOGS_TO_RETURN = "rpc.logs.maxLogsToReturn"; @@ -187,17 +188,13 @@ public boolean isWalletEnabled() { } public BigInteger gasPriceBuffer() { - String gasPriceBuffer = getString("miner.gasPriceBuffer", ""); + int gasPriceBuffer = getInt(MINER_GAS_PRICE_BUFFER_CONFIG, 110); - if(!gasPriceBuffer.isEmpty()) { - try { - return new BigInteger(gasPriceBuffer); - } catch (NumberFormatException e) { - throw new NumberFormatException("Invalid gasPriceBuffer value in config file"); - } + if(gasPriceBuffer > 100) { + return BigInteger.valueOf(gasPriceBuffer); + } else { + throw new RskConfigurationException(MINER_GAS_PRICE_BUFFER_CONFIG + " must be greater than 100"); } - - return null; } public List walletAccounts() { diff --git a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java index a2a3db711ea..d769d9979a0 100644 --- a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java +++ b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java @@ -51,8 +51,8 @@ public class GasPriceTracker extends EthereumListenerAdapter { private static final double BLOCK_COMPLETION_PERCENT_FOR_FEE_MARKET_WORKING = 0.9; - private static final BigInteger BI_10 = BigInteger.valueOf(10); - private static final BigInteger BI_11 = BigInteger.valueOf(11); + private static final BigInteger BI_100 = BigInteger.valueOf(100); + private static final BigInteger DEFAULT_BI_110 = BigInteger.valueOf(110); private final Coin[] txWindow = new Coin[TX_WINDOW_SIZE]; @@ -60,7 +60,7 @@ public class GasPriceTracker extends EthereumListenerAdapter { private final AtomicReference bestBlockPriceRef = new AtomicReference<>(); private final BlockStore blockStore; - private final BigInteger configBuffer; + private final BigInteger gasPriceBuffer; private Coin defaultPrice = Coin.valueOf(20_000_000_000L); private int txIdx = TX_WINDOW_SIZE - 1; @@ -71,11 +71,11 @@ public class GasPriceTracker extends EthereumListenerAdapter { private GasPriceTracker(BlockStore blockStore, BigInteger configBuffer) { this.blockStore = blockStore; - this.configBuffer = configBuffer; + this.gasPriceBuffer = configBuffer; } public static GasPriceTracker create(BlockStore blockStore) { - return create(blockStore, null); + return create(blockStore, DEFAULT_BI_110); } public static GasPriceTracker create(BlockStore blockStore, BigInteger configBuffer) { @@ -128,8 +128,8 @@ public synchronized Coin getGasPrice() { return lastVal; } - return Coin.max(lastVal, bestBlockPrice.multiply(BI_11) - .divide(configBuffer == null ? BI_10 : configBuffer)); + return Coin.max(lastVal, bestBlockPrice.multiply(gasPriceBuffer) + .divide(BI_100)); } public synchronized boolean isFeeMarketWorking() { diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index d10f8ba6caf..9032bfbf0a7 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -168,7 +168,7 @@ miner { # This property can be set to a numeric value by the node operator to over write the gas price buffer # used to calculate the gas price returned by eth_gasPrice - gasPriceBuffer = null + gasPriceBuffer = 110 server { enabled = false diff --git a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java index 56006cc86e9..f9d9c737c68 100644 --- a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java +++ b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java @@ -22,6 +22,7 @@ import co.rsk.cli.RskCli; import co.rsk.rpc.ModuleDescription; import com.typesafe.config.Config; +import com.typesafe.config.ConfigException; import com.typesafe.config.ConfigFactory; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -228,17 +229,18 @@ void testGetRpcModulesWithObject() { @Test void testGasPriceBuffer() { - assertEquals(BigInteger.valueOf(5), config.gasPriceBuffer()); + assertEquals(BigInteger.valueOf(105), config.gasPriceBuffer()); } @Test void testGasPriceBufferWithNull() { + // Set miner.gasPriceBuffer to null which yields the same result as not finding the path TestSystemProperties testSystemProperties = new TestSystemProperties(rawConfig -> ConfigFactory.parseString("{" + "miner.gasPriceBuffer = null" + " }").withFallback(rawConfig)); - assertNull(testSystemProperties.gasPriceBuffer()); + assertEquals(BigInteger.valueOf(110), testSystemProperties.gasPriceBuffer()); } @Test @@ -248,6 +250,6 @@ void testGasPriceBufferThrowsError() { "miner.gasPriceBuffer = invalid" + " }").withFallback(rawConfig)); - Assertions.assertThrows(NumberFormatException.class, testSystemProperties::gasPriceBuffer); + Assertions.assertThrows(ConfigException.WrongType.class, testSystemProperties::gasPriceBuffer); } } diff --git a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java index d8dec3b75f4..e0776934f65 100644 --- a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java +++ b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java @@ -152,7 +152,7 @@ void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_ReturnsBest @Test void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_GasPriceBufferOverWritten_ReturnsBestBlockAdjustedPriceWithNewBuffer() { - GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, BigInteger.valueOf(5)); + GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, BigInteger.valueOf(105)); Block bestBlock = makeBlock(Coin.valueOf(50_000_000_000L), 0, i -> null); Block block = makeBlock(Coin.valueOf(30_000_000_000L), TOTAL_SLOTS, i -> makeTx(Coin.valueOf(40_000_000_000L))); @@ -162,7 +162,7 @@ void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_GasPriceBuf Coin actualResult = gasPriceTracker.getGasPrice(); - assertEquals(Coin.valueOf(110_000_000_000L), actualResult); + assertEquals(Coin.valueOf(52_500_000_000L), actualResult); } @Test diff --git a/rskj-core/src/test/resources/test-rskj.conf b/rskj-core/src/test/resources/test-rskj.conf index b616f23bea7..17ed10ac4ed 100644 --- a/rskj-core/src/test/resources/test-rskj.conf +++ b/rskj-core/src/test/resources/test-rskj.conf @@ -161,7 +161,7 @@ vm.structured.storage.dictionary.enabled = false miner.client.enabled = false miner.server.enabled = false -miner.gasPriceBuffer = 5 +miner.gasPriceBuffer = 105 # eth sync process sync { From 68c77030a5a1f6da9def65dc5af77d04a34dd846 Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Mon, 8 Jan 2024 10:23:45 -0400 Subject: [PATCH 010/137] Code cleanup and update default value in config --- .../src/main/java/co/rsk/config/RskSystemProperties.java | 8 ++++---- rskj-core/src/main/resources/reference.conf | 6 +++--- .../test/java/org/ethereum/facade/EthereumImplTest.java | 7 ------- rskj-core/src/test/resources/test-rskj.conf | 2 +- 4 files changed, 8 insertions(+), 15 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index 7e88a569bd9..0756488a546 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -188,12 +188,12 @@ public boolean isWalletEnabled() { } public BigInteger gasPriceBuffer() { - int gasPriceBuffer = getInt(MINER_GAS_PRICE_BUFFER_CONFIG, 110); + int gasPriceBuffer = getInt(MINER_GAS_PRICE_BUFFER_CONFIG, 10); - if(gasPriceBuffer > 100) { - return BigInteger.valueOf(gasPriceBuffer); + if(gasPriceBuffer > 0) { + return BigInteger.valueOf(gasPriceBuffer + 100); } else { - throw new RskConfigurationException(MINER_GAS_PRICE_BUFFER_CONFIG + " must be greater than 100"); + throw new RskConfigurationException(MINER_GAS_PRICE_BUFFER_CONFIG + " must be greater than 0"); } } diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 9032bfbf0a7..562f3dd5091 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -166,9 +166,9 @@ miner { # The default gas price minGasPrice = 0 - # This property can be set to a numeric value by the node operator to over write the gas price buffer - # used to calculate the gas price returned by eth_gasPrice - gasPriceBuffer = 110 + # This property can be set to a numeric value by the node operator to over write the percentage for the + # gas price buffer used to calculate the gas price returned by eth_gasPrice + gasPriceBuffer = 10 server { enabled = false diff --git a/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java b/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java index afd468a1352..033023e22c5 100644 --- a/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/facade/EthereumImplTest.java @@ -22,9 +22,7 @@ import org.ethereum.core.Blockchain; import org.ethereum.listener.CompositeEthereumListener; import org.ethereum.listener.GasPriceTracker; -import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; @@ -32,11 +30,6 @@ class EthereumImplTest { - @AfterEach - void resetMocks() { - Mockito.reset(); - } - @Test void getGasPrice_returns_GasPriceTrackerValue_when_feeMarketWorking_is_true() { GasPriceTracker gasPriceTracker = mock(GasPriceTracker.class); diff --git a/rskj-core/src/test/resources/test-rskj.conf b/rskj-core/src/test/resources/test-rskj.conf index 17ed10ac4ed..b616f23bea7 100644 --- a/rskj-core/src/test/resources/test-rskj.conf +++ b/rskj-core/src/test/resources/test-rskj.conf @@ -161,7 +161,7 @@ vm.structured.storage.dictionary.enabled = false miner.client.enabled = false miner.server.enabled = false -miner.gasPriceBuffer = 105 +miner.gasPriceBuffer = 5 # eth sync process sync { From 74dfbac38f852891627c9cb0ea58f77dcee9d8a2 Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Mon, 8 Jan 2024 11:02:29 -0400 Subject: [PATCH 011/137] Fix sonarcloud issue --- .../src/main/java/co/rsk/config/RskSystemProperties.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index 0756488a546..ef36397d510 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -188,10 +188,10 @@ public boolean isWalletEnabled() { } public BigInteger gasPriceBuffer() { - int gasPriceBuffer = getInt(MINER_GAS_PRICE_BUFFER_CONFIG, 10); + long gasPriceBuffer = getLong(MINER_GAS_PRICE_BUFFER_CONFIG, 10L); if(gasPriceBuffer > 0) { - return BigInteger.valueOf(gasPriceBuffer + 100); + return BigInteger.valueOf(gasPriceBuffer + 100L); } else { throw new RskConfigurationException(MINER_GAS_PRICE_BUFFER_CONFIG + " must be greater than 0"); } From f5287c5f5942c00120239157e9af2dcb34edc4a3 Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Fri, 12 Jan 2024 08:49:50 -0400 Subject: [PATCH 012/137] Change gasPriceBuffer name, location and type --- .../src/main/java/co/rsk/RskContext.java | 5 ++--- .../co/rsk/config/RskSystemProperties.java | 13 ++++++------- .../ethereum/listener/GasPriceTracker.java | 17 +++++++++-------- rskj-core/src/main/resources/expected.conf | 2 +- rskj-core/src/main/resources/reference.conf | 8 ++++---- .../rsk/config/RskSystemPropertiesTest.java | 19 +++++++++---------- .../listener/GasPriceTrackerTest.java | 4 ++-- rskj-core/src/test/resources/test-rskj.conf | 2 +- 8 files changed, 34 insertions(+), 36 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/RskContext.java b/rskj-core/src/main/java/co/rsk/RskContext.java index 14e172c5ca0..441912dd939 100644 --- a/rskj-core/src/main/java/co/rsk/RskContext.java +++ b/rskj-core/src/main/java/co/rsk/RskContext.java @@ -131,7 +131,6 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.io.*; -import java.math.BigInteger; import java.net.InetSocketAddress; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -556,10 +555,10 @@ public synchronized Ethereum getRsk() { public GasPriceTracker getGasPriceTracker() { checkIfNotClosed(); - BigInteger gasPriceBuffer = getRskSystemProperties().gasPriceBuffer(); + double gasPriceMultiplier = getRskSystemProperties().gasPriceMultiplier(); if (this.gasPriceTracker == null) { - this.gasPriceTracker = GasPriceTracker.create(getBlockStore(), gasPriceBuffer); + this.gasPriceTracker = GasPriceTracker.create(getBlockStore(), gasPriceMultiplier); } return this.gasPriceTracker; } diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index ef36397d510..38fa7c849e8 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -31,7 +31,6 @@ import org.ethereum.crypto.HashUtil; import javax.annotation.Nullable; -import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.util.*; @@ -52,10 +51,10 @@ public class RskSystemProperties extends SystemProperties { private static final String MINER_REWARD_ADDRESS_CONFIG = "miner.reward.address"; private static final String MINER_COINBASE_SECRET_CONFIG = "miner.coinbase.secret"; - private static final String MINER_GAS_PRICE_BUFFER_CONFIG = "miner.gasPriceBuffer"; private static final String RPC_MODULES_PATH = "rpc.modules"; private static final String RPC_ETH_GET_LOGS_MAX_BLOCKS_TO_QUERY = "rpc.logs.maxBlocksToQuery"; private static final String RPC_ETH_GET_LOGS_MAX_LOGS_TO_RETURN = "rpc.logs.maxLogsToReturn"; + private static final String RPC_GAS_PRICE_MULTIPLIER_CONFIG = "rpc.gasPriceMultiplier"; private static final int CHUNK_SIZE = 192; @@ -187,13 +186,13 @@ public boolean isWalletEnabled() { return getBoolean("wallet.enabled", false); } - public BigInteger gasPriceBuffer() { - long gasPriceBuffer = getLong(MINER_GAS_PRICE_BUFFER_CONFIG, 10L); + public double gasPriceMultiplier() { + double gasPriceMultiplier = getDouble(RPC_GAS_PRICE_MULTIPLIER_CONFIG, 10); - if(gasPriceBuffer > 0) { - return BigInteger.valueOf(gasPriceBuffer + 100L); + if(gasPriceMultiplier > 0) { + return gasPriceMultiplier + 100; } else { - throw new RskConfigurationException(MINER_GAS_PRICE_BUFFER_CONFIG + " must be greater than 0"); + throw new RskConfigurationException(RPC_GAS_PRICE_MULTIPLIER_CONFIG + " must be greater than 0"); } } diff --git a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java index d769d9979a0..01743d65d88 100644 --- a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java +++ b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java @@ -29,6 +29,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.math.BigDecimal; import java.math.BigInteger; import java.util.*; import java.util.concurrent.atomic.AtomicReference; @@ -52,7 +53,7 @@ public class GasPriceTracker extends EthereumListenerAdapter { private static final double BLOCK_COMPLETION_PERCENT_FOR_FEE_MARKET_WORKING = 0.9; private static final BigInteger BI_100 = BigInteger.valueOf(100); - private static final BigInteger DEFAULT_BI_110 = BigInteger.valueOf(110); + private static final double DEFAULT_GAS_PRICE_MULTIPLIER = 110.0; private final Coin[] txWindow = new Coin[TX_WINDOW_SIZE]; @@ -60,7 +61,7 @@ public class GasPriceTracker extends EthereumListenerAdapter { private final AtomicReference bestBlockPriceRef = new AtomicReference<>(); private final BlockStore blockStore; - private final BigInteger gasPriceBuffer; + private final BigInteger gasPriceMultiplier; private Coin defaultPrice = Coin.valueOf(20_000_000_000L); private int txIdx = TX_WINDOW_SIZE - 1; @@ -69,17 +70,17 @@ public class GasPriceTracker extends EthereumListenerAdapter { private Coin lastVal; - private GasPriceTracker(BlockStore blockStore, BigInteger configBuffer) { + private GasPriceTracker(BlockStore blockStore, Double configMultiplier) { this.blockStore = blockStore; - this.gasPriceBuffer = configBuffer; + this.gasPriceMultiplier = BigDecimal.valueOf(configMultiplier).toBigInteger(); } public static GasPriceTracker create(BlockStore blockStore) { - return create(blockStore, DEFAULT_BI_110); + return create(blockStore, DEFAULT_GAS_PRICE_MULTIPLIER); } - public static GasPriceTracker create(BlockStore blockStore, BigInteger configBuffer) { - GasPriceTracker gasPriceTracker = new GasPriceTracker(blockStore, configBuffer); + public static GasPriceTracker create(BlockStore blockStore, Double configMultiplier) { + GasPriceTracker gasPriceTracker = new GasPriceTracker(blockStore, configMultiplier); gasPriceTracker.initializeWindowsFromDB(); return gasPriceTracker; } @@ -128,7 +129,7 @@ public synchronized Coin getGasPrice() { return lastVal; } - return Coin.max(lastVal, bestBlockPrice.multiply(gasPriceBuffer) + return Coin.max(lastVal, bestBlockPrice.multiply(gasPriceMultiplier) .divide(BI_100)); } diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index c4d58a2999a..58f009898b8 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -168,7 +168,6 @@ wallet = { miner = { gasUnitInDollars = minGasPrice = - gasPriceBuffer = server = { enabled = isFixedClock = @@ -249,6 +248,7 @@ rpc = { callGasCap = timeout = maxResponseSize = + gasPriceMultiplier = providers = { web = { cors = diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 562f3dd5091..dc4babf1d88 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -166,10 +166,6 @@ miner { # The default gas price minGasPrice = 0 - # This property can be set to a numeric value by the node operator to over write the percentage for the - # gas price buffer used to calculate the gas price returned by eth_gasPrice - gasPriceBuffer = 10 - server { enabled = false isFixedClock = false @@ -334,6 +330,10 @@ rpc { # Maximum Response size allowed in bytes. If value is 0 then there is no limit. maxResponseSize = 0 + # This property can be set to a numeric value by the node operator to over write the percentage for the + # gas price multiplier used to calculate the gas price returned by eth_gasPrice + gasPriceMultiplier = 10 + providers { web { cors = "localhost" diff --git a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java index f9d9c737c68..70bf4223f58 100644 --- a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java +++ b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java @@ -29,7 +29,6 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import java.math.BigInteger; import java.util.List; import java.util.Map; import java.util.function.Function; @@ -228,28 +227,28 @@ void testGetRpcModulesWithObject() { } @Test - void testGasPriceBuffer() { - assertEquals(BigInteger.valueOf(105), config.gasPriceBuffer()); + void testGasPriceMultiplier() { + assertEquals(Double.valueOf(105), config.gasPriceMultiplier()); } @Test - void testGasPriceBufferWithNull() { - // Set miner.gasPriceBuffer to null which yields the same result as not finding the path + void testGasPriceMultiplierWithNull() { + // Set miner.gasPriceMultiplier to null which yields the same result as not finding the path TestSystemProperties testSystemProperties = new TestSystemProperties(rawConfig -> ConfigFactory.parseString("{" + - "miner.gasPriceBuffer = null" + + "rpc.gasPriceMultiplier = null" + " }").withFallback(rawConfig)); - assertEquals(BigInteger.valueOf(110), testSystemProperties.gasPriceBuffer()); + assertEquals(Double.valueOf(110), testSystemProperties.gasPriceMultiplier()); } @Test - void testGasPriceBufferThrowsError() { + void testGasPriceMultiplierThrowsError() { TestSystemProperties testSystemProperties = new TestSystemProperties(rawConfig -> ConfigFactory.parseString("{" + - "miner.gasPriceBuffer = invalid" + + "rpc.gasPriceMultiplier = invalid" + " }").withFallback(rawConfig)); - Assertions.assertThrows(ConfigException.WrongType.class, testSystemProperties::gasPriceBuffer); + Assertions.assertThrows(ConfigException.WrongType.class, testSystemProperties::gasPriceMultiplier); } } diff --git a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java index e0776934f65..a66fd2cf017 100644 --- a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java +++ b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java @@ -151,8 +151,8 @@ void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_ReturnsBest } @Test - void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_GasPriceBufferOverWritten_ReturnsBestBlockAdjustedPriceWithNewBuffer() { - GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, BigInteger.valueOf(105)); + void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_GasPriceMultiplierOverWritten_ReturnsBestBlockAdjustedPriceWithNewBuffer() { + GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, 105.0); Block bestBlock = makeBlock(Coin.valueOf(50_000_000_000L), 0, i -> null); Block block = makeBlock(Coin.valueOf(30_000_000_000L), TOTAL_SLOTS, i -> makeTx(Coin.valueOf(40_000_000_000L))); diff --git a/rskj-core/src/test/resources/test-rskj.conf b/rskj-core/src/test/resources/test-rskj.conf index b616f23bea7..101d562145b 100644 --- a/rskj-core/src/test/resources/test-rskj.conf +++ b/rskj-core/src/test/resources/test-rskj.conf @@ -161,7 +161,6 @@ vm.structured.storage.dictionary.enabled = false miner.client.enabled = false miner.server.enabled = false -miner.gasPriceBuffer = 5 # eth sync process sync { @@ -211,6 +210,7 @@ sync { } rpc = { + gasPriceMultiplier = 5 callGasCap: 50000000, timeout: 0, maxResponseSize: 0, From 65dd3583161d0ea101dff9dd7caac1a1fb6b05f7 Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Fri, 12 Jan 2024 10:13:12 -0400 Subject: [PATCH 013/137] Change gasPriceMultiplier default value --- .../main/java/co/rsk/config/RskSystemProperties.java | 8 ++++---- .../java/org/ethereum/listener/GasPriceTracker.java | 12 +++++------- rskj-core/src/main/resources/reference.conf | 2 +- .../java/co/rsk/config/RskSystemPropertiesTest.java | 4 ++-- .../org/ethereum/listener/GasPriceTrackerTest.java | 2 +- rskj-core/src/test/resources/test-rskj.conf | 2 +- 6 files changed, 14 insertions(+), 16 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index 38fa7c849e8..b833baee99e 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -187,12 +187,12 @@ public boolean isWalletEnabled() { } public double gasPriceMultiplier() { - double gasPriceMultiplier = getDouble(RPC_GAS_PRICE_MULTIPLIER_CONFIG, 10); + double gasPriceMultiplier = getDouble(RPC_GAS_PRICE_MULTIPLIER_CONFIG, 1.1); - if(gasPriceMultiplier > 0) { - return gasPriceMultiplier + 100; + if(gasPriceMultiplier > 1.0) { + return gasPriceMultiplier; } else { - throw new RskConfigurationException(RPC_GAS_PRICE_MULTIPLIER_CONFIG + " must be greater than 0"); + throw new RskConfigurationException(RPC_GAS_PRICE_MULTIPLIER_CONFIG + " must be greater than 1.0"); } } diff --git a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java index 01743d65d88..d9a29d489c4 100644 --- a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java +++ b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java @@ -30,7 +30,6 @@ import org.slf4j.LoggerFactory; import java.math.BigDecimal; -import java.math.BigInteger; import java.util.*; import java.util.concurrent.atomic.AtomicReference; @@ -52,8 +51,7 @@ public class GasPriceTracker extends EthereumListenerAdapter { private static final double BLOCK_COMPLETION_PERCENT_FOR_FEE_MARKET_WORKING = 0.9; - private static final BigInteger BI_100 = BigInteger.valueOf(100); - private static final double DEFAULT_GAS_PRICE_MULTIPLIER = 110.0; + private static final double DEFAULT_GAS_PRICE_MULTIPLIER = 1.1; private final Coin[] txWindow = new Coin[TX_WINDOW_SIZE]; @@ -61,7 +59,7 @@ public class GasPriceTracker extends EthereumListenerAdapter { private final AtomicReference bestBlockPriceRef = new AtomicReference<>(); private final BlockStore blockStore; - private final BigInteger gasPriceMultiplier; + private final double gasPriceMultiplier; private Coin defaultPrice = Coin.valueOf(20_000_000_000L); private int txIdx = TX_WINDOW_SIZE - 1; @@ -72,7 +70,7 @@ public class GasPriceTracker extends EthereumListenerAdapter { private GasPriceTracker(BlockStore blockStore, Double configMultiplier) { this.blockStore = blockStore; - this.gasPriceMultiplier = BigDecimal.valueOf(configMultiplier).toBigInteger(); + this.gasPriceMultiplier = configMultiplier; } public static GasPriceTracker create(BlockStore blockStore) { @@ -129,8 +127,8 @@ public synchronized Coin getGasPrice() { return lastVal; } - return Coin.max(lastVal, bestBlockPrice.multiply(gasPriceMultiplier) - .divide(BI_100)); + return Coin.max(lastVal, new Coin(new BigDecimal(bestBlockPrice.asBigInteger()) + .multiply(BigDecimal.valueOf(gasPriceMultiplier)).toBigInteger())); } public synchronized boolean isFeeMarketWorking() { diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index dc4babf1d88..3f689a5ed4a 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -332,7 +332,7 @@ rpc { # This property can be set to a numeric value by the node operator to over write the percentage for the # gas price multiplier used to calculate the gas price returned by eth_gasPrice - gasPriceMultiplier = 10 + gasPriceMultiplier = 1.1 providers { web { diff --git a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java index 70bf4223f58..b3ab7ba1fc1 100644 --- a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java +++ b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java @@ -228,7 +228,7 @@ void testGetRpcModulesWithObject() { @Test void testGasPriceMultiplier() { - assertEquals(Double.valueOf(105), config.gasPriceMultiplier()); + assertEquals(1.05, config.gasPriceMultiplier()); } @Test @@ -239,7 +239,7 @@ void testGasPriceMultiplierWithNull() { "rpc.gasPriceMultiplier = null" + " }").withFallback(rawConfig)); - assertEquals(Double.valueOf(110), testSystemProperties.gasPriceMultiplier()); + assertEquals(1.1, testSystemProperties.gasPriceMultiplier()); } @Test diff --git a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java index a66fd2cf017..07382c02356 100644 --- a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java +++ b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java @@ -152,7 +152,7 @@ void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_ReturnsBest @Test void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_GasPriceMultiplierOverWritten_ReturnsBestBlockAdjustedPriceWithNewBuffer() { - GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, 105.0); + GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, 1.05); Block bestBlock = makeBlock(Coin.valueOf(50_000_000_000L), 0, i -> null); Block block = makeBlock(Coin.valueOf(30_000_000_000L), TOTAL_SLOTS, i -> makeTx(Coin.valueOf(40_000_000_000L))); diff --git a/rskj-core/src/test/resources/test-rskj.conf b/rskj-core/src/test/resources/test-rskj.conf index 101d562145b..c67a567701f 100644 --- a/rskj-core/src/test/resources/test-rskj.conf +++ b/rskj-core/src/test/resources/test-rskj.conf @@ -210,7 +210,7 @@ sync { } rpc = { - gasPriceMultiplier = 5 + gasPriceMultiplier = 1.05 callGasCap: 50000000, timeout: 0, maxResponseSize: 0, From dafb20a2bfc5a1e89c5defb3d478698d76f1b319 Mon Sep 17 00:00:00 2001 From: Reynold Morel Date: Mon, 15 Jan 2024 08:39:09 -0400 Subject: [PATCH 014/137] Update config value range check --- .../main/java/co/rsk/config/RskSystemProperties.java | 4 ++-- .../java/co/rsk/config/RskSystemPropertiesTest.java | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index b833baee99e..c1dde0b6d68 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -189,10 +189,10 @@ public boolean isWalletEnabled() { public double gasPriceMultiplier() { double gasPriceMultiplier = getDouble(RPC_GAS_PRICE_MULTIPLIER_CONFIG, 1.1); - if(gasPriceMultiplier > 1.0) { + if(gasPriceMultiplier >= 0) { return gasPriceMultiplier; } else { - throw new RskConfigurationException(RPC_GAS_PRICE_MULTIPLIER_CONFIG + " must be greater than 1.0"); + throw new RskConfigurationException(RPC_GAS_PRICE_MULTIPLIER_CONFIG + " cannot be a negative number"); } } diff --git a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java index b3ab7ba1fc1..f38c0334cd4 100644 --- a/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java +++ b/rskj-core/src/test/java/co/rsk/config/RskSystemPropertiesTest.java @@ -243,7 +243,7 @@ void testGasPriceMultiplierWithNull() { } @Test - void testGasPriceMultiplierThrowsError() { + void testGasPriceMultiplierThrowsErrorForInvalidType() { TestSystemProperties testSystemProperties = new TestSystemProperties(rawConfig -> ConfigFactory.parseString("{" + "rpc.gasPriceMultiplier = invalid" + @@ -251,4 +251,14 @@ void testGasPriceMultiplierThrowsError() { Assertions.assertThrows(ConfigException.WrongType.class, testSystemProperties::gasPriceMultiplier); } + + @Test + void testGasPriceMultiplierThrowsErrorForNegativeValue() { + TestSystemProperties testSystemProperties = new TestSystemProperties(rawConfig -> + ConfigFactory.parseString("{" + + "rpc.gasPriceMultiplier = -1" + + " }").withFallback(rawConfig)); + + Assertions.assertThrows(RskConfigurationException.class, testSystemProperties::gasPriceMultiplier); + } } From 5274b7a59747383e01630749aed4b893575a5fd2 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Tue, 18 Jul 2023 11:03:27 -0400 Subject: [PATCH 015/137] - Changed Activation mock to Activation obtained by using ActivationConfigsForTest helper - Got rid of sigHash parameter when testing null values - Got rid of no needed comments - Renamed BRIDGE_BTC_TX_SIG_HASH_KEY to BRIDGE_BTC_TX_SIG_HASH --- .../java/co/rsk/peg/BridgeStorageProviderBridgeTxsIndexTests.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderBridgeTxsIndexTests.java diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderBridgeTxsIndexTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderBridgeTxsIndexTests.java new file mode 100644 index 00000000000..e69de29bb2d From f372b2e657a18581a7e46c407d3e7301f60e6e7c Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Tue, 28 Nov 2023 22:33:10 -0400 Subject: [PATCH 016/137] - Declare minimumPeginTxValue and belowMinimumPeginTxValue as class instance variable so no need to be creating these variables for each test that needs it. - Fix some tests --- .../co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index 143ba162990..02bc9c65a6f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -86,6 +86,9 @@ class BridgeSupportRegisterBtcTransactionTest { private static final Coin minimumPeginTxValue = bridgeMainnetConstants.getMinimumPeginTxValue(ActivationConfigsForTest.all().forBlock(0)); private static final Coin belowMinimumPeginTxValue = minimumPeginTxValue.minus(Coin.SATOSHI); + private static final Coin minimumPeginTxValue = bridgeMainnetConstants.getMinimumPeginTxValue(ActivationConfigsForTest.all().forBlock(0)); + private static final Coin belowMinimumPeginTxValue = minimumPeginTxValue.minus(Coin.SATOSHI); + private static final int FIRST_OUTPUT_INDEX = 0; private static final int FIRST_INPUT_INDEX = 0; From 90878b7fc3824b932dcd49db818ec6f214156ff5 Mon Sep 17 00:00:00 2001 From: julia zack Date: Mon, 13 Nov 2023 17:48:05 -0300 Subject: [PATCH 017/137] Create ErpRedeemScriptBuilders --- .../co/rsk/peg/ErpRedeemScriptBuilder.java | 14 +++ .../rsk/peg/LegacyErpRedeemScriptBuilder.java | 93 +++++++++++++++++++ .../rsk/peg/P2shErpRedeemScriptBuilder.java | 76 +++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/LegacyErpRedeemScriptBuilder.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java new file mode 100644 index 00000000000..14cd4971de5 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java @@ -0,0 +1,14 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.script.Script; + +import java.util.List; + +public interface ErpRedeemScriptBuilder { + long MAX_CSV_VALUE = 65535L; + + Script createRedeemScript(List defaultPublicKeys, + List emergencyPublicKeys, + long csvValue); +} \ No newline at end of file diff --git a/rskj-core/src/main/java/co/rsk/peg/LegacyErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/LegacyErpRedeemScriptBuilder.java new file mode 100644 index 00000000000..3e37c0c0334 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/LegacyErpRedeemScriptBuilder.java @@ -0,0 +1,93 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.core.Utils; +import co.rsk.bitcoinj.core.VerificationException; +import co.rsk.bitcoinj.script.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class LegacyErpRedeemScriptBuilder implements ErpRedeemScriptBuilder { + private static final Logger logger = LoggerFactory.getLogger(LegacyErpRedeemScriptBuilder.class); + + public static Script createRedeemScript(Script defaultRedeemScript, + Script emergencyRedeemScript, + byte[] serializedCsvValue) { + + ScriptBuilder scriptBuilder = new ScriptBuilder(); + return scriptBuilder + .op(ScriptOpCodes.OP_NOTIF) + .addChunks(removeOpCheckMultisig(defaultRedeemScript)) + .op(ScriptOpCodes.OP_ELSE) + .data(serializedCsvValue) + .op(ScriptOpCodes.OP_CHECKSEQUENCEVERIFY) + .op(ScriptOpCodes.OP_DROP) + .addChunks(removeOpCheckMultisig(emergencyRedeemScript)) + .op(ScriptOpCodes.OP_ENDIF) + .op(ScriptOpCodes.OP_CHECKMULTISIG) + .build(); + } + public Script createRedeemScript(List defaultPublicKeys, + List emergencyPublicKeys, + long csvValue) { + Script defaultRedeemScript = ScriptBuilder.createRedeemScript( + defaultPublicKeys.size() / 2 + 1, + defaultPublicKeys); + Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( + emergencyPublicKeys.size() / 2 + 1, + emergencyPublicKeys); + byte[] serializedCsvValue = Utils.signedLongToByteArrayLE(csvValue); + + return createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); + } + + @Deprecated + public static Script createRedeemScriptDeprecated(List defaultPublicKeys, + List emergencyPublicKeys, + long csvValue) { + Script defaultRedeemScript = ScriptBuilder.createRedeemScript( + defaultPublicKeys.size() / 2 + 1, + defaultPublicKeys); + Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( + emergencyPublicKeys.size() / 2 + 1, + emergencyPublicKeys); + validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue); + + byte[] serializedCsvValue = Utils.unsignedLongToByteArrayBE(csvValue, 2); + return createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); + } + + private static void validateRedeemScriptValues( + Script defaultFederationRedeemScript, + Script erpFederationRedeemScript, + Long csvValue + ) { + if (!defaultFederationRedeemScript.isSentToMultiSig() || !erpFederationRedeemScript.isSentToMultiSig()) { + + String message = "Provided redeem scripts have an invalid structure, not standard"; + logger.debug( + "[validateLegacyErpRedeemScriptValues] {}. Default script {}. Emergency script {}", + message, + defaultFederationRedeemScript, + erpFederationRedeemScript + ); + throw new VerificationException(message); + } + + if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { + String message = String.format( + "Provided csv value %d must be between 0 and %d", + csvValue, + MAX_CSV_VALUE + ); + logger.warn("[validateP2shErpRedeemScriptValues] {}", message); + throw new VerificationException(message); + } + } + + protected static List removeOpCheckMultisig(Script redeemScript) { + return redeemScript.getChunks().subList(0, redeemScript.getChunks().size() - 1); + } +} \ No newline at end of file diff --git a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java new file mode 100644 index 00000000000..3a29bc037ae --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java @@ -0,0 +1,76 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.core.Utils; +import co.rsk.bitcoinj.core.VerificationException; +import co.rsk.bitcoinj.script.Script; +import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.bitcoinj.script.ScriptOpCodes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class P2shErpRedeemScriptBuilder implements ErpRedeemScriptBuilder{ + private static final Logger logger = LoggerFactory.getLogger(P2shErpRedeemScriptBuilder.class); + + public static Script createRedeemScript(Script defaultRedeemScript, + Script emergencyRedeemScript, + byte[] serializedCsvValue) { + + ScriptBuilder scriptBuilder = new ScriptBuilder(); + + return scriptBuilder + .op(ScriptOpCodes.OP_NOTIF) + .addChunks(defaultRedeemScript.getChunks()) + .op(ScriptOpCodes.OP_ELSE) + .data(serializedCsvValue) + .op(ScriptOpCodes.OP_CHECKSEQUENCEVERIFY) + .op(ScriptOpCodes.OP_DROP) + .addChunks(emergencyRedeemScript.getChunks()) + .op(ScriptOpCodes.OP_ENDIF) + .build(); + } + public Script createRedeemScript(List defaultPublicKeys, + List emergencyPublicKeys, + long csvValue) { + Script defaultRedeemScript = ScriptBuilder.createRedeemScript( + defaultPublicKeys.size() / 2 + 1, + defaultPublicKeys); + Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( + emergencyPublicKeys.size() / 2 + 1, + emergencyPublicKeys); + validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue); + + byte[] serializedCsvValue = Utils.signedLongToByteArrayLE(csvValue); + return createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); + } + + private static void validateRedeemScriptValues( + Script defaultFederationRedeemScript, + Script erpFederationRedeemScript, + Long csvValue + ) { + if (!defaultFederationRedeemScript.isSentToMultiSig() || !erpFederationRedeemScript.isSentToMultiSig()) { + + String message = "Provided redeem scripts have an invalid structure, not standard"; + logger.debug( + "[validateP2shErpRedeemScriptValues] {}. Default script {}. Emergency script {}", + message, + defaultFederationRedeemScript, + erpFederationRedeemScript + ); + throw new VerificationException(message); + } + + if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { + String message = String.format( + "Provided csv value %d must be between 0 and %d", + csvValue, + MAX_CSV_VALUE + ); + logger.warn("[validateP2shErpRedeemScriptValues] {}", message); + throw new VerificationException(message); + } + } +} From 8a2e6ba59a8c07d91b7412a28266dd7ebc9bab5d Mon Sep 17 00:00:00 2001 From: julia zack Date: Tue, 14 Nov 2023 18:22:17 -0300 Subject: [PATCH 018/137] Split old LegacyErpRedeemScriptBuilder into NonStandardErp builders related to activations --- .../co/rsk/peg/ErpRedeemScriptBuilder.java | 4 +- ...=> NonStandardErpRedeemScriptBuilder.java} | 81 ++++++++--------- ...ndardErpRedeemScriptBuilderHardcoaded.java | 22 +++++ ...pRedeemScriptBuilderWithCsvUnsignedBE.java | 91 +++++++++++++++++++ .../rsk/peg/P2shErpRedeemScriptBuilder.java | 34 ++++--- 5 files changed, 173 insertions(+), 59 deletions(-) rename rskj-core/src/main/java/co/rsk/peg/{LegacyErpRedeemScriptBuilder.java => NonStandardErpRedeemScriptBuilder.java} (62%) create mode 100644 rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java index 14cd4971de5..f75ff5d45dc 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java @@ -9,6 +9,6 @@ public interface ErpRedeemScriptBuilder { long MAX_CSV_VALUE = 65535L; Script createRedeemScript(List defaultPublicKeys, - List emergencyPublicKeys, - long csvValue); + List emergencyPublicKeys, + long csvValue); } \ No newline at end of file diff --git a/rskj-core/src/main/java/co/rsk/peg/LegacyErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java similarity index 62% rename from rskj-core/src/main/java/co/rsk/peg/LegacyErpRedeemScriptBuilder.java rename to rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java index 3e37c0c0334..15533de7851 100644 --- a/rskj-core/src/main/java/co/rsk/peg/LegacyErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java @@ -9,69 +9,44 @@ import java.util.List; -public class LegacyErpRedeemScriptBuilder implements ErpRedeemScriptBuilder { - private static final Logger logger = LoggerFactory.getLogger(LegacyErpRedeemScriptBuilder.class); - - public static Script createRedeemScript(Script defaultRedeemScript, - Script emergencyRedeemScript, - byte[] serializedCsvValue) { +public class NonStandardErpRedeemScriptBuilder implements ErpRedeemScriptBuilder { + private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilder.class); - ScriptBuilder scriptBuilder = new ScriptBuilder(); - return scriptBuilder - .op(ScriptOpCodes.OP_NOTIF) - .addChunks(removeOpCheckMultisig(defaultRedeemScript)) - .op(ScriptOpCodes.OP_ELSE) - .data(serializedCsvValue) - .op(ScriptOpCodes.OP_CHECKSEQUENCEVERIFY) - .op(ScriptOpCodes.OP_DROP) - .addChunks(removeOpCheckMultisig(emergencyRedeemScript)) - .op(ScriptOpCodes.OP_ENDIF) - .op(ScriptOpCodes.OP_CHECKMULTISIG) - .build(); - } public Script createRedeemScript(List defaultPublicKeys, List emergencyPublicKeys, long csvValue) { + Script defaultRedeemScript = ScriptBuilder.createRedeemScript( defaultPublicKeys.size() / 2 + 1, defaultPublicKeys); Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( emergencyPublicKeys.size() / 2 + 1, emergencyPublicKeys); + byte[] serializedCsvValue = Utils.signedLongToByteArrayLE(csvValue); - return createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); - } + logger.debug("[getRedeemScript] Creating the redeem script from the keys"); + Script redeemScript = createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); - @Deprecated - public static Script createRedeemScriptDeprecated(List defaultPublicKeys, - List emergencyPublicKeys, - long csvValue) { - Script defaultRedeemScript = ScriptBuilder.createRedeemScript( - defaultPublicKeys.size() / 2 + 1, - defaultPublicKeys); - Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( - emergencyPublicKeys.size() / 2 + 1, - emergencyPublicKeys); - validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue); + logger.debug("[getRedeemScript] Validating redeem script values"); + validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue, redeemScript); + return redeemScript; - byte[] serializedCsvValue = Utils.unsignedLongToByteArrayBE(csvValue, 2); - return createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); } private static void validateRedeemScriptValues( - Script defaultFederationRedeemScript, - Script erpFederationRedeemScript, - Long csvValue + Script defaultRedeemScript, + Script emergencyRedeemScript, + Long csvValue, + Script redeemScript ) { - if (!defaultFederationRedeemScript.isSentToMultiSig() || !erpFederationRedeemScript.isSentToMultiSig()) { - - String message = "Provided redeem scripts have an invalid structure, not standard"; + if (!defaultRedeemScript.isSentToMultiSig() || !emergencyRedeemScript.isSentToMultiSig()) { + String message = "Provided redeem scripts inside the erp one have an invalid structure, not standards"; logger.debug( "[validateLegacyErpRedeemScriptValues] {}. Default script {}. Emergency script {}", message, - defaultFederationRedeemScript, - erpFederationRedeemScript + defaultRedeemScript, + emergencyRedeemScript ); throw new VerificationException(message); } @@ -82,9 +57,29 @@ private static void validateRedeemScriptValues( csvValue, MAX_CSV_VALUE ); - logger.warn("[validateP2shErpRedeemScriptValues] {}", message); + logger.warn("[validateLegacyErpRedeemScriptValues] {}", message); throw new VerificationException(message); } + + FederationUtils.validateScriptSize(redeemScript); + } + + public static Script createRedeemScript(Script defaultRedeemScript, + Script emergencyRedeemScript, + byte[] serializedCsvValue) { + + ScriptBuilder scriptBuilder = new ScriptBuilder(); + return scriptBuilder + .op(ScriptOpCodes.OP_NOTIF) + .addChunks(removeOpCheckMultisig(defaultRedeemScript)) + .op(ScriptOpCodes.OP_ELSE) + .data(serializedCsvValue) + .op(ScriptOpCodes.OP_CHECKSEQUENCEVERIFY) + .op(ScriptOpCodes.OP_DROP) + .addChunks(removeOpCheckMultisig(emergencyRedeemScript)) + .op(ScriptOpCodes.OP_ENDIF) + .op(ScriptOpCodes.OP_CHECKMULTISIG) + .build(); } protected static List removeOpCheckMultisig(Script redeemScript) { diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java new file mode 100644 index 00000000000..241140a071b --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java @@ -0,0 +1,22 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.script.Script; +import org.bouncycastle.util.encoders.Hex; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class NonStandardErpRedeemScriptBuilderHardcoaded implements ErpRedeemScriptBuilder { + private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderHardcoaded.class); + private static final byte[] LEGACY_ERP_TESTNET_REDEEM_SCRIPT_BYTES = Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f42102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da210344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a0921039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb955670300cd50b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); + + public Script createRedeemScript(List defaultPublicKeys, + List emergencyPublicKeys, + long csvValue) { + + logger.debug("[getRedeemScript] Returning hardcoded redeem script"); + return new Script(LEGACY_ERP_TESTNET_REDEEM_SCRIPT_BYTES); + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java new file mode 100644 index 00000000000..c4bf3add875 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java @@ -0,0 +1,91 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.core.Utils; +import co.rsk.bitcoinj.core.VerificationException; +import co.rsk.bitcoinj.script.Script; +import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.bitcoinj.script.ScriptChunk; +import co.rsk.bitcoinj.script.ScriptOpCodes; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.List; + +public class NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE implements ErpRedeemScriptBuilder { + private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.class); + + public Script createRedeemScript(List defaultPublicKeys, + List emergencyPublicKeys, + long csvValue) { + + Script defaultRedeemScript = ScriptBuilder.createRedeemScript( + defaultPublicKeys.size() / 2 + 1, + defaultPublicKeys); + Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( + emergencyPublicKeys.size() / 2 + 1, + emergencyPublicKeys); + + byte[] serializedCsvValue = Utils.unsignedLongToByteArrayBE(csvValue, 2); + + logger.debug("[getRedeemScript] Creating the redeem script from the keys"); + Script redeemScript = createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); + + logger.debug("[getRedeemScript] Validating redeem script values"); + validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue, redeemScript); + return redeemScript; + + } + + private static void validateRedeemScriptValues( + Script defaultRedeemScript, + Script emergencyRedeemScript, + Long csvValue, + Script redeemScript + ) { + if (!defaultRedeemScript.isSentToMultiSig() || !emergencyRedeemScript.isSentToMultiSig()) { + String message = "Provided redeem scripts inside the erp one have an invalid structure, not standards"; + logger.debug( + "[validateLegacyErpRedeemScriptValues] {}. Default script {}. Emergency script {}", + message, + defaultRedeemScript, + emergencyRedeemScript + ); + throw new VerificationException(message); + } + + if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { + String message = String.format( + "Provided csv value %d must be between 0 and %d", + csvValue, + MAX_CSV_VALUE + ); + logger.warn("[validateLegacyErpRedeemScriptValues] {}", message); + throw new VerificationException(message); + } + + FederationUtils.validateScriptSize(redeemScript); + } + + public static Script createRedeemScript(Script defaultRedeemScript, + Script emergencyRedeemScript, + byte[] serializedCsvValue) { + + ScriptBuilder scriptBuilder = new ScriptBuilder(); + return scriptBuilder + .op(ScriptOpCodes.OP_NOTIF) + .addChunks(removeOpCheckMultisig(defaultRedeemScript)) + .op(ScriptOpCodes.OP_ELSE) + .data(serializedCsvValue) + .op(ScriptOpCodes.OP_CHECKSEQUENCEVERIFY) + .op(ScriptOpCodes.OP_DROP) + .addChunks(removeOpCheckMultisig(emergencyRedeemScript)) + .op(ScriptOpCodes.OP_ENDIF) + .op(ScriptOpCodes.OP_CHECKMULTISIG) + .build(); + } + + protected static List removeOpCheckMultisig(Script redeemScript) { + return redeemScript.getChunks().subList(0, redeemScript.getChunks().size() - 1); + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java index 3a29bc037ae..5da63eacd43 100644 --- a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java @@ -14,6 +14,22 @@ public class P2shErpRedeemScriptBuilder implements ErpRedeemScriptBuilder{ private static final Logger logger = LoggerFactory.getLogger(P2shErpRedeemScriptBuilder.class); + public Script createRedeemScript(List defaultPublicKeys, + List emergencyPublicKeys, + long csvValue) { + Script defaultRedeemScript = ScriptBuilder.createRedeemScript( + defaultPublicKeys.size() / 2 + 1, + defaultPublicKeys); + Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( + emergencyPublicKeys.size() / 2 + 1, + emergencyPublicKeys); + + byte[] serializedCsvValue = Utils.signedLongToByteArrayLE(csvValue); + Script redeemScript = createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); + validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue, redeemScript); + + return redeemScript; + } public static Script createRedeemScript(Script defaultRedeemScript, Script emergencyRedeemScript, byte[] serializedCsvValue) { @@ -31,25 +47,13 @@ public static Script createRedeemScript(Script defaultRedeemScript, .op(ScriptOpCodes.OP_ENDIF) .build(); } - public Script createRedeemScript(List defaultPublicKeys, - List emergencyPublicKeys, - long csvValue) { - Script defaultRedeemScript = ScriptBuilder.createRedeemScript( - defaultPublicKeys.size() / 2 + 1, - defaultPublicKeys); - Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( - emergencyPublicKeys.size() / 2 + 1, - emergencyPublicKeys); - validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue); - byte[] serializedCsvValue = Utils.signedLongToByteArrayLE(csvValue); - return createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); - } private static void validateRedeemScriptValues( Script defaultFederationRedeemScript, Script erpFederationRedeemScript, - Long csvValue + Long csvValue, + Script redeemScript ) { if (!defaultFederationRedeemScript.isSentToMultiSig() || !erpFederationRedeemScript.isSentToMultiSig()) { @@ -72,5 +76,7 @@ private static void validateRedeemScriptValues( logger.warn("[validateP2shErpRedeemScriptValues] {}", message); throw new VerificationException(message); } + + FederationUtils.validateScriptSize(redeemScript); } } From 85bd4688c3c36f288aeb2fed79c7fb8d844f20ba Mon Sep 17 00:00:00 2001 From: julia zack Date: Wed, 15 Nov 2023 18:01:04 -0300 Subject: [PATCH 019/137] Make ErpFederation a non-abstract class again. Inject ErpRedeemScriptBuilder to its constructor. Remove LegacyErpFederation and P2shErpFederation. Add activations and network parameters logic to the NonStandard builders --- .../co/rsk/peg/BridgeSerializationUtils.java | 20 ++- .../co/rsk/peg/BridgeStorageProvider.java | 60 ++++--- .../main/java/co/rsk/peg/ErpFederation.java | 38 ++++- .../rsk/peg/ErpRedeemScriptBuilderUtils.java | 52 +++++++ .../java/co/rsk/peg/LegacyErpFederation.java | 93 ----------- .../java/co/rsk/peg/P2shErpFederation.java | 60 ------- .../java/co/rsk/peg/PendingFederation.java | 14 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 14 +- .../BridgeStorageProviderFederationTests.java | 15 +- .../co/rsk/peg/BridgeStorageProviderTest.java | 64 +++++--- .../BridgeSupportGetTransactionTypeTest.java | 0 .../java/co/rsk/peg/BridgeSupportTest.java | 15 +- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 18 ++- ...verCompatibleBtcWalletWithStorageTest.java | 5 +- ...patibleBtcWallextWithSingleScriptTest.java | 5 +- .../co/rsk/peg/LegacyErpFederationTest.java | 147 +++++++++--------- .../co/rsk/peg/P2shErpFederationTest.java | 53 ++++--- .../co/rsk/peg/PendingFederationTest.java | 12 +- .../java/co/rsk/peg/PowpegMigrationTest.java | 17 +- .../peg/ReleaseTransactionBuilderTest.java | 5 +- 20 files changed, 357 insertions(+), 350 deletions(-) create mode 100644 rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java delete mode 100644 rskj-core/src/main/java/co/rsk/peg/LegacyErpFederation.java delete mode 100644 rskj-core/src/main/java/co/rsk/peg/P2shErpFederation.java create mode 100644 rskj-core/src/test/java/co/rsk/peg/BridgeSupportGetTransactionTypeTest.java diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index b9cdac52c4c..ca70efc467e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -314,8 +314,8 @@ public static StandardMultisigFederation deserializeStandardMultisigFederation( BridgeSerializationUtils::deserializeFederationMember ); } - - public static LegacyErpFederation deserializeLegacyErpFederation( +// TODO change Legacy to NonStandard in the name + public static ErpFederation deserializeLegacyErpFederation( byte[] data, BridgeConstants bridgeConstants, ActivationConfig.ForBlock activations @@ -326,18 +326,22 @@ public static LegacyErpFederation deserializeLegacyErpFederation( BridgeSerializationUtils::deserializeFederationMember ); - return new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder = + ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + + return new ErpFederation( federation.getMembers(), federation.creationTime, federation.getCreationBlockNumber(), federation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); } - public static P2shErpFederation deserializeP2shErpFederation( + public static ErpFederation deserializeP2shErpFederation( byte[] data, BridgeConstants bridgeConstants, ActivationConfig.ForBlock activations @@ -347,15 +351,15 @@ public static P2shErpFederation deserializeP2shErpFederation( bridgeConstants.getBtcParams(), BridgeSerializationUtils::deserializeFederationMember ); - - return new P2shErpFederation( + return new ErpFederation( federation.getMembers(), federation.creationTime, federation.getCreationBlockNumber(), federation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new P2shErpRedeemScriptBuilder() ); } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 256059905fa..62a00ac1745 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -349,6 +349,7 @@ public void setNewFederation(Federation federation) { newFederation = federation; } + // TODO: refactor this builder logic /** * Save the new federation * Only saved if a federation was set with BridgeStorageProvider::setNewFederation @@ -361,16 +362,23 @@ public void saveNewFederation() { RepositorySerializer serializer = BridgeSerializationUtils::serializeFederationOnlyBtcKeys; if (activations.isActive(RSKIP123)) { - if (activations.isActive(RSKIP353) && newFederation instanceof P2shErpFederation) { - saveStorageVersion( - NEW_FEDERATION_FORMAT_VERSION.getKey(), - P2SH_ERP_FEDERATION_FORMAT_VERSION - ); - } else if (activations.isActive(RSKIP201) && newFederation instanceof LegacyErpFederation) { - saveStorageVersion( - NEW_FEDERATION_FORMAT_VERSION.getKey(), - LEGACY_ERP_FEDERATION_FORMAT_VERSION - ); + if (newFederation instanceof ErpFederation) { + ErpRedeemScriptBuilder builder = ((ErpFederation) newFederation).erpRedeemScriptBuilder; + if (activations.isActive(RSKIP353) + && builder instanceof P2shErpRedeemScriptBuilder) { + saveStorageVersion( + NEW_FEDERATION_FORMAT_VERSION.getKey(), + P2SH_ERP_FEDERATION_FORMAT_VERSION + ); + } else if (activations.isActive(RSKIP201) + && (builder instanceof NonStandardErpRedeemScriptBuilder + || builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE + || builder instanceof NonStandardErpRedeemScriptBuilderHardcoaded)) { + saveStorageVersion( + NEW_FEDERATION_FORMAT_VERSION.getKey(), + LEGACY_ERP_FEDERATION_FORMAT_VERSION + ); + } } else { saveStorageVersion( NEW_FEDERATION_FORMAT_VERSION.getKey(), @@ -412,6 +420,7 @@ public void setOldFederation(Federation federation) { oldFederation = federation; } + // TODO refactor this builder logic /** * Save the old federation */ @@ -422,16 +431,24 @@ protected void saveOldFederation() { RepositorySerializer serializer = BridgeSerializationUtils::serializeFederationOnlyBtcKeys; if (activations.isActive(RSKIP123)) { - if (activations.isActive(RSKIP353) && oldFederation instanceof P2shErpFederation) { - saveStorageVersion( - OLD_FEDERATION_FORMAT_VERSION.getKey(), - P2SH_ERP_FEDERATION_FORMAT_VERSION - ); - } else if (activations.isActive(RSKIP201) && oldFederation instanceof ErpFederation) { - saveStorageVersion( - OLD_FEDERATION_FORMAT_VERSION.getKey(), - LEGACY_ERP_FEDERATION_FORMAT_VERSION - ); + if (oldFederation instanceof ErpFederation) { + ErpRedeemScriptBuilder builder = ((ErpFederation) oldFederation).erpRedeemScriptBuilder; + if (activations.isActive(RSKIP353) + && builder instanceof P2shErpRedeemScriptBuilder) { + saveStorageVersion( + OLD_FEDERATION_FORMAT_VERSION.getKey(), + P2SH_ERP_FEDERATION_FORMAT_VERSION + ); + } else if (activations.isActive(RSKIP201) + && (builder instanceof NonStandardErpRedeemScriptBuilder + || builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE + || builder instanceof NonStandardErpRedeemScriptBuilderHardcoaded + )) { + saveStorageVersion( + OLD_FEDERATION_FORMAT_VERSION.getKey(), + LEGACY_ERP_FEDERATION_FORMAT_VERSION + ); + } } else { saveStorageVersion( OLD_FEDERATION_FORMAT_VERSION.getKey(), @@ -1037,7 +1054,8 @@ private DataWord getStorageKeyForFlyoverFederationInformation(byte[] flyoverFede private DataWord getStorageKeyForNewFederationBtcUtxos() { DataWord key = NEW_FEDERATION_BTC_UTXOS_KEY.getKey(); - if (networkParameters.getId().equals(NetworkParameters.ID_TESTNET)) { + if (networkParameters.getId().equals(NetworkParameters.ID_TESTNET) + || networkParameters.getId().equals(NetworkParameters.ID_REGTEST)) { if (activations.isActive(RSKIP284)) { key = NEW_FEDERATION_BTC_UTXOS_KEY_FOR_TESTNET_PRE_HOP.getKey(); } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java index 28228bbc22a..a21ee9c5692 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java @@ -2,17 +2,19 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.bitcoinj.script.RedeemScriptParserFactory; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.peg.utils.EcKeyUtils; import java.time.Instant; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import static co.rsk.peg.FederationCreationException.Reason.INVALID_CSV_VALUE; import static co.rsk.peg.FederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; -public abstract class ErpFederation extends Federation { +public class ErpFederation extends Federation { protected static final long MAX_CSV_VALUE = 65_535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value protected final List erpPubKeys; protected final long activationDelay; @@ -20,6 +22,8 @@ public abstract class ErpFederation extends Federation { protected Script standardRedeemScript; protected Script standardP2SHScript; + protected ErpRedeemScriptBuilder erpRedeemScriptBuilder; + protected ErpFederation( List members, Instant creationTime, @@ -27,7 +31,8 @@ protected ErpFederation( NetworkParameters btcParams, List erpPubKeys, long activationDelay, - ActivationConfig.ForBlock activations) { + ActivationConfig.ForBlock activations, + ErpRedeemScriptBuilder erpRedeemScriptBuilder) { super(members, creationTime, creationBlockNumber, btcParams); validateErpFederationValues(erpPubKeys, activationDelay); @@ -35,6 +40,15 @@ protected ErpFederation( this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpPubKeys); this.activationDelay = activationDelay; this.activations = activations; + this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; + } + + public List getDefaultPublicKeys() { + List defaultPubKeys = new ArrayList<>(); + for (FederationMember member : members) { + defaultPubKeys.add(member.getBtcPublicKey()); + } + return Collections.unmodifiableList(defaultPubKeys); } public List getErpPubKeys() { @@ -45,7 +59,24 @@ public long getActivationDelay() { return activationDelay; } - public abstract Script getStandardRedeemScript(); + public Script getStandardRedeemScript() { + if (standardRedeemScript == null) { + standardRedeemScript = RedeemScriptParserFactory.get(getRedeemScript().getChunks()) + .extractStandardRedeemScript(); + } + return standardRedeemScript; + } + + + @Override + public Script getRedeemScript() { + if (redeemScript == null) { + redeemScript = erpRedeemScriptBuilder.createRedeemScript(getDefaultPublicKeys(), erpPubKeys, activationDelay); + } + // TODO: definir donde va esta validacion. + FederationUtils.validateScriptSize(redeemScript); + return redeemScript; + } public Script getStandardP2SHScript() { if (standardP2SHScript == null) { @@ -70,5 +101,4 @@ private void validateErpFederationValues(List erpPubKeys, long activat throw new FederationCreationException(message, INVALID_CSV_VALUE); } } - } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java new file mode 100644 index 00000000000..9a57e78b5a3 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java @@ -0,0 +1,52 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.config.BridgeConstants; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; + +public class ErpRedeemScriptBuilderUtils { + + private ErpRedeemScriptBuilderUtils() { + } + + public static ErpRedeemScriptBuilder defineErpRedeemScriptBuilder( + ActivationConfig.ForBlock activations, + BridgeConstants bridgeConstants) { + + ErpRedeemScriptBuilder erpRedeemScriptBuilder; + + NetworkParameters networkParameters = bridgeConstants.getBtcParams(); + boolean networkParametersIsTestnetOrRegtest = checkIfNetworkParameterIsTestnetOrRegtest(networkParameters); + + if(!activations.isActive(ConsensusRule.RSKIP284) && networkParametersIsTestnetOrRegtest) { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoaded(); + } else if (!activations.isActive(ConsensusRule.RSKIP293)) { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); + } else erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); + + return erpRedeemScriptBuilder; + } + + public static ErpRedeemScriptBuilder defineErpRedeemScriptBuilder( + ActivationConfig.ForBlock activations, + NetworkParameters networkParameters) { + + ErpRedeemScriptBuilder erpRedeemScriptBuilder; + + boolean networkParametersIsTestnetOrRegtest = checkIfNetworkParameterIsTestnetOrRegtest(networkParameters); + + if(!activations.isActive(ConsensusRule.RSKIP284) && networkParametersIsTestnetOrRegtest) { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoaded(); + } else if (!activations.isActive(ConsensusRule.RSKIP293)) { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); + } else erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); + + return erpRedeemScriptBuilder; + } + + private static boolean checkIfNetworkParameterIsTestnetOrRegtest(NetworkParameters networkParametersId) { + return networkParametersId.getId().equals(NetworkParameters.ID_TESTNET) + || networkParametersId.getId().equals(NetworkParameters.ID_REGTEST); + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/LegacyErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/LegacyErpFederation.java deleted file mode 100644 index 828c0809eb1..00000000000 --- a/rskj-core/src/main/java/co/rsk/peg/LegacyErpFederation.java +++ /dev/null @@ -1,93 +0,0 @@ -package co.rsk.peg; - -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.script.ErpFederationRedeemScriptParser; -import co.rsk.bitcoinj.script.Script; -import co.rsk.bitcoinj.script.ScriptBuilder; -import java.time.Instant; -import java.util.List; - -import org.bouncycastle.util.encoders.Hex; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import static co.rsk.peg.FederationCreationException.Reason.*; - -/** - * @deprecated This class represents a Legacy ERP Federation that is non-standard. - * It has been deprecated but it must be kept because of backwards compatibility. - */ - -@Deprecated -public class LegacyErpFederation extends ErpFederation { - private static final Logger logger = LoggerFactory.getLogger(LegacyErpFederation.class); - private static final byte[] LEGACY_ERP_TESTNET_REDEEM_SCRIPT_BYTES = Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f42102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da210344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a0921039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb955670300cd50b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); - - public LegacyErpFederation( - List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams, - List erpPubKeys, - long activationDelay, - ActivationConfig.ForBlock activations) { - - super(members, creationTime, creationBlockNumber, btcParams, erpPubKeys, activationDelay, activations); - - validateRedeemScript(); - } - - @Override - public Script getRedeemScript() { - if (!activations.isActive(ConsensusRule.RSKIP284) && - btcParams.getId().equals(NetworkParameters.ID_TESTNET)) { - logger.debug("[getRedeemScript] Returning hardcoded redeem script"); - return new Script(LEGACY_ERP_TESTNET_REDEEM_SCRIPT_BYTES); - } - - if (redeemScript == null) { - logger.debug("[getRedeemScript] Creating the redeem script from the keys"); - redeemScript = activations.isActive(ConsensusRule.RSKIP293) ? - ErpFederationRedeemScriptParser.createErpRedeemScript( - ScriptBuilder.createRedeemScript(getNumberOfSignaturesRequired(), getBtcPublicKeys()), - ScriptBuilder.createRedeemScript(erpPubKeys.size() / 2 + 1, erpPubKeys), - activationDelay - ) : - ErpFederationRedeemScriptParser.createErpRedeemScriptDeprecated( - ScriptBuilder.createRedeemScript(getNumberOfSignaturesRequired(), getBtcPublicKeys()), - ScriptBuilder.createRedeemScript(erpPubKeys.size() / 2 + 1, erpPubKeys), - activationDelay - ); - } - - return redeemScript; - } - - @Override - public Script getStandardRedeemScript() { - if (standardRedeemScript == null) { - standardRedeemScript = ErpFederationRedeemScriptParser.extractStandardRedeemScript( - getRedeemScript().getChunks() - ); - } - return standardRedeemScript; - } - - private void validateRedeemScript() { - Script redeemScript = this.getRedeemScript(); - - if (activations.isActive(ConsensusRule.RSKIP293) && - redeemScript.equals(new Script(LEGACY_ERP_TESTNET_REDEEM_SCRIPT_BYTES))) { - - String message = "Unable to create ERP Federation. The obtained redeem script matches the one hardcoded for testnet. " - + "This would cause bitcoinj-thin to identify it as invalid"; - logger.debug("[validateRedeemScript] {}", message); - throw new FederationCreationException(message, HARDCODED_LEGACY_ERP_TESTNET_REDEEM_SCRIPT); - } - - FederationUtils.validateScriptSize(redeemScript); - } -} - diff --git a/rskj-core/src/main/java/co/rsk/peg/P2shErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/P2shErpFederation.java deleted file mode 100644 index b578ee4ee5f..00000000000 --- a/rskj-core/src/main/java/co/rsk/peg/P2shErpFederation.java +++ /dev/null @@ -1,60 +0,0 @@ -package co.rsk.peg; - -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.script.P2shErpFederationRedeemScriptParser; -import co.rsk.bitcoinj.script.Script; -import co.rsk.bitcoinj.script.ScriptBuilder; -import java.time.Instant; -import java.util.List; - -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -public class P2shErpFederation extends ErpFederation { - private static final Logger logger = LoggerFactory.getLogger(P2shErpFederation.class); - - public P2shErpFederation( - List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams, - List erpPubKeys, - long activationDelay, - ActivationConfig.ForBlock activations - ) { - super(members, creationTime, creationBlockNumber, btcParams, erpPubKeys, activationDelay, activations); - - validateRedeemScriptSize(); - } - - @Override - public final Script getRedeemScript() { - if (redeemScript == null) { - logger.debug("[getRedeemScript] Creating the redeem script from the keys"); - redeemScript = P2shErpFederationRedeemScriptParser.createP2shErpRedeemScript( - ScriptBuilder.createRedeemScript(getNumberOfSignaturesRequired(), getBtcPublicKeys()), - ScriptBuilder.createRedeemScript(erpPubKeys.size() / 2 + 1, erpPubKeys), - activationDelay - ); - } - - return redeemScript; - } - - @Override - public final Script getStandardRedeemScript() { - if (standardRedeemScript == null) { - standardRedeemScript = P2shErpFederationRedeemScriptParser.extractStandardRedeemScript( - getRedeemScript().getChunks() - ); - } - return standardRedeemScript; - } - - private void validateRedeemScriptSize() { - Script redeemScript = this.getRedeemScript(); - FederationUtils.validateScriptSize(redeemScript); - } -} diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java index c0ddd49878e..a7cc97ad246 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java @@ -106,27 +106,33 @@ public Federation buildFederation( if (activations.isActive(ConsensusRule.RSKIP353)) { logger.info("[buildFederation] Going to create a P2SH ERP Federation"); - return new P2shErpFederation( + return new ErpFederation( members, creationTime, blockNumber, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new P2shErpRedeemScriptBuilder() ); } if (activations.isActive(ConsensusRule.RSKIP201)) { logger.info("[buildFederation] Going to create an ERP Federation"); - return new LegacyErpFederation( + + ErpRedeemScriptBuilder erpRedeemScriptBuilder + = ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + + return new ErpFederation( members, creationTime, blockNumber, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 35190f974fc..4a21668aa58 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -1220,6 +1220,7 @@ void deserializeCoinbaseInformation_dataIsValid_returnsValidCoinbaseInformation( Assertions.assertEquals(witnessRoot, BridgeSerializationUtils.deserializeCoinbaseInformation(serializedCoinbaseInformation).getWitnessMerkleRoot()); } + // TODO split this test? private void testSerializeAndDeserializeFederation( boolean isRskip284Active, boolean isRskip353Active, @@ -1238,6 +1239,9 @@ private void testSerializeAndDeserializeFederation( when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(isRskip284Active); when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(isRskip353Active); + ErpRedeemScriptBuilder erpRedeemScriptBuilder = + ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + for (int i = 0; i < NUM_CASES; i++) { int numMembers = randomInRange(2, 14); List members = new ArrayList<>(); @@ -1259,14 +1263,15 @@ private void testSerializeAndDeserializeFederation( bridgeConstants.getBtcParams() ); - Federation testErpFederation = new LegacyErpFederation( + Federation testErpFederation = new ErpFederation( members, Instant.now(), 123, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); byte[] serializedTestErpFederation = BridgeSerializationUtils.serializeFederation(testErpFederation); @@ -1286,14 +1291,15 @@ private void testSerializeAndDeserializeFederation( } if (isRskip353Active) { - Federation testP2shErpFederation = new P2shErpFederation( + Federation testP2shErpFederation = new ErpFederation( members, Instant.now(), 123, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new P2shErpRedeemScriptBuilder() ); byte[] serializedTestP2shErpFederation = BridgeSerializationUtils.serializeFederation(testP2shErpFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index 23bf87e0b64..7a288f6ce23 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -9,11 +9,12 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.config.BridgeConstants; -import co.rsk.config.BridgeRegTestConstants; import java.io.IOException; import java.time.Instant; import java.util.List; +import co.rsk.config.BridgeRegTestConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -604,24 +605,28 @@ private Federation createFederation(int version) { switch (version) { case P2SH_ERP_FEDERATION_FORMAT_VERSION: - return new P2shErpFederation( + return new ErpFederation( members, Instant.now(), 1L, bridgeConstantsRegtest.getBtcParams(), bridgeConstantsRegtest.getErpFedPubKeysList(), bridgeConstantsRegtest.getErpFedActivationDelay(), - activations + activations, + new P2shErpRedeemScriptBuilder() ); case LEGACY_ERP_FEDERATION_FORMAT_VERSION: - return new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder = + ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstantsRegtest); + return new ErpFederation( members, Instant.now(), 1L, bridgeConstantsRegtest.getBtcParams(), bridgeConstantsRegtest.getErpFedPubKeysList(), bridgeConstantsRegtest.getErpFedActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); default: return new StandardMultisigFederation( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 8e8fd5a9301..30ca0a40161 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -401,15 +401,22 @@ void getNewFederation_multiKeyVersion() { @Test void getNewFederation_erp_fed() { +/* ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true);*/ + BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = new LegacyErpFederation( + ErpFederation erpFederation = new ErpFederation( newFederation.getMembers(), newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), - config.getNetworkConstants().getBridgeConstants().getErpFedPubKeysList(), - config.getNetworkConstants().getBridgeConstants().getErpFedActivationDelay(), - mock(ActivationConfig.ForBlock.class) + bridgeConstants.getErpFedPubKeysList(), + bridgeConstants.getErpFedActivationDelay(), + mock(ActivationConfig.ForBlock.class), + new NonStandardErpRedeemScriptBuilderHardcoaded() ); testGetNewFederationPostMultiKey(erpFederation); @@ -418,14 +425,15 @@ void getNewFederation_erp_fed() { @Test void getNewFederation_p2sh_erp_fed() { Federation newFederation = buildMockFederation(100, 200, 300); - P2shErpFederation p2shErpFederation = new P2shErpFederation( + ErpFederation p2shErpFederation = new ErpFederation( newFederation.getMembers(), newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), config.getNetworkConstants().getBridgeConstants().getErpFedPubKeysList(), config.getNetworkConstants().getBridgeConstants().getErpFedActivationDelay(), - mock(ActivationConfig.ForBlock.class) + mock(ActivationConfig.ForBlock.class), + new P2shErpRedeemScriptBuilder() ); testGetNewFederationPostMultiKey(p2shErpFederation); @@ -546,14 +554,15 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = new LegacyErpFederation( + ErpFederation erpFederation = new ErpFederation( newFederation.getMembers(), newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new NonStandardErpRedeemScriptBuilder() ); testSaveNewFederationPostMultiKey(erpFederation, ERP_FEDERATION_FORMAT_VERSION, activations); @@ -568,14 +577,15 @@ void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation newFederation = buildMockFederation(100, 200, 300); - P2shErpFederation p2shErpFederation = new P2shErpFederation( + ErpFederation p2shErpFederation = new ErpFederation( newFederation.getMembers(), newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new P2shErpRedeemScriptBuilder() ); testSaveNewFederationPostMultiKey(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activations); @@ -680,14 +690,15 @@ void getOldFederation_multiKeyVersion() { void getOldFederation_erp_fed() { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation oldFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = new LegacyErpFederation( + ErpFederation erpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - mock(ActivationConfig.ForBlock.class) + mock(ActivationConfig.ForBlock.class), + new NonStandardErpRedeemScriptBuilderHardcoaded() ); testGetOldFederation(erpFederation); @@ -697,14 +708,15 @@ void getOldFederation_erp_fed() { void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation oldFederation = buildMockFederation(100, 200, 300); - P2shErpFederation p2shErpFederation = new P2shErpFederation( + ErpFederation p2shErpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - mock(ActivationConfig.ForBlock.class) + mock(ActivationConfig.ForBlock.class), + new P2shErpRedeemScriptBuilder() ); testGetOldFederation(p2shErpFederation); @@ -820,14 +832,15 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation oldFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = new LegacyErpFederation( + ErpFederation erpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new NonStandardErpRedeemScriptBuilder() ); testSaveOldFederation(erpFederation, ERP_FEDERATION_FORMAT_VERSION, activations); @@ -841,14 +854,15 @@ void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation oldFederation = buildMockFederation(100, 200, 300); - P2shErpFederation p2shErpFederation = new P2shErpFederation( + ErpFederation p2shErpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new P2shErpRedeemScriptBuilder() ); testSaveOldFederation(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activations); @@ -3561,6 +3575,7 @@ void getReleaseRequestQueueSize_when_releaseRequestQueue_is_not_null() throws IO Assertions.assertEquals(2, storageProvider.getReleaseRequestQueueSize()); } + // siempre devuelve la hardcoaded? private void testGetOldFederation(Federation oldFederation) { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); List storageCalls = new ArrayList<>(); @@ -3649,6 +3664,7 @@ private void testSaveOldFederation(Federation oldFederation, int version, Activa } } + // este deberia devolver siempre la nonstandard harcoaded? dado que es justo la que vino post multikey? private void testGetNewFederationPostMultiKey(Federation federation) { List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); @@ -3787,7 +3803,7 @@ private void testGetNewFederationBtcUTXOs(boolean isRskip284Active, boolean isRs List obtainedUtxos = provider.getNewFederationBtcUTXOs(); - if (networkId.equals(NetworkParameters.ID_TESTNET) && (isRskip284Active || isRskip293Active)) { + if ((networkId.equals(NetworkParameters.ID_TESTNET)/* || networkId.equals(NetworkParameters.ID_REGTEST)*/)&& (isRskip284Active || isRskip293Active)) { if (isRskip293Active) { Assertions.assertEquals(federationUtxosAfterRskip293Activation, obtainedUtxos); } else { @@ -3836,7 +3852,7 @@ private void testSaveNewFederationBtcUTXOs(boolean isRskip284Active, String netw provider.getNewFederationBtcUTXOs(); // Ensure there are elements in the UTXOs list provider.saveNewFederationBtcUTXOs(); - if (isRskip284Active && networkId.equals(NetworkParameters.ID_TESTNET)) { + if (isRskip284Active && (networkId.equals(NetworkParameters.ID_TESTNET) /*|| networkId.equals(NetworkParameters.ID_REGTEST)*/)) { verify(repository, never()).addStorageBytes( eq(PrecompiledContracts.BRIDGE_ADDR), eq(NEW_FEDERATION_BTC_UTXOS_KEY.getKey()), @@ -3901,14 +3917,18 @@ private static Repository createRepository() { return new MutableRepository(new MutableTrieCache(new MutableTrieImpl(trieStore, new Trie(trieStore)))); } + // TODO refactor private int getFederationVersion(Federation federation) { if (federation instanceof StandardMultisigFederation) { return BridgeStorageProvider.STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION; } - if (federation instanceof LegacyErpFederation) { + ErpRedeemScriptBuilder builder = ((ErpFederation) federation).erpRedeemScriptBuilder; + if (builder instanceof NonStandardErpRedeemScriptBuilder + || builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE + || builder instanceof NonStandardErpRedeemScriptBuilderHardcoaded) { return BridgeStorageProvider.LEGACY_ERP_FEDERATION_FORMAT_VERSION; } - if (federation instanceof P2shErpFederation) { + if (builder instanceof P2shErpRedeemScriptBuilder) { return BridgeStorageProvider.P2SH_ERP_FEDERATION_FORMAT_VERSION; } throw new IllegalArgumentException("Unknown Federation type: " + federation.getClass()); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportGetTransactionTypeTest.java new file mode 100644 index 00000000000..e69de29bb2d 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 fb48b7efe86..82c8f720411 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -6562,14 +6562,15 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ when(preRSKIP271_activations.isActive(ConsensusRule.RSKIP271)).thenReturn(false); when(preRSKIP271_activations.isActive(ConsensusRule.RSKIP385)).thenReturn(false); - Federation p2shFed = new P2shErpFederation( + Federation p2shFed = new ErpFederation( members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - preRSKIP271_activations + preRSKIP271_activations, + new P2shErpRedeemScriptBuilder() ); Stream preRskip271 = Stream.of( @@ -6630,14 +6631,15 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ when(preRSKIP385_activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); when(preRSKIP385_activations.isActive(ConsensusRule.RSKIP385)).thenReturn(false); - Federation p2shFed = new P2shErpFederation( + Federation p2shFed = new ErpFederation( members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - preRSKIP385_activations + preRSKIP385_activations, + new P2shErpRedeemScriptBuilder() ); Stream preRskip385 = Stream.of( @@ -6697,14 +6699,15 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ PegTestUtils.createRandomBtcECKeys(7) ); - P2shErpFederation p2shFed = new P2shErpFederation( + ErpFederation p2shFed = new ErpFederation( members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - postRSKIP385_activations + postRSKIP385_activations, + new P2shErpRedeemScriptBuilder() ); Stream postRskip385 = Stream.of( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index 63ef370111d..477eb393199 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -60,7 +60,8 @@ import java.util.Collections; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.Mockito.*; class BridgeUtilsTest { @@ -1045,14 +1046,15 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs_erpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new LegacyErpFederation( + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - activations + activations, + new NonStandardErpRedeemScriptBuilder() ); // Create a pegout tx with 50 inputs and 200 outputs @@ -1089,14 +1091,15 @@ void testCalculatePegoutTxSize_100Inputs_50Outputs_erpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new LegacyErpFederation( + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - activations + activations, + new NonStandardErpRedeemScriptBuilder() ); // Create a pegout tx with 100 inputs and 50 outputs @@ -1420,14 +1423,15 @@ private Genesis getGenesisInstance(TrieStore trieStore) { private ErpFederation createErpFederation() { Federation genesisFederation = bridgeConstantsRegtest.getGenesisFederation(); - return new LegacyErpFederation( + return new ErpFederation( genesisFederation.getMembers(), genesisFederation.getCreationTime(), genesisFederation.getCreationBlockNumber(), genesisFederation.getBtcParams(), bridgeConstantsRegtest.getErpFedPubKeysList(), bridgeConstantsRegtest.getErpFedActivationDelay(), - activations + activations, + new NonStandardErpRedeemScriptBuilder() ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java index 8c2c5567e20..25b1fbab413 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java @@ -52,14 +52,15 @@ void setup() { NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - erpFederation = new LegacyErpFederation( + erpFederation = new ErpFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST), erpFedKeys, 5063, - activations + activations, + new NonStandardErpRedeemScriptBuilder() ); federationList = Collections.singletonList(federation); diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java index afb20abf11d..956b9933efd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java @@ -48,14 +48,15 @@ void setup() { NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - erpFederation = new LegacyErpFederation( + erpFederation = new ErpFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST), erpFedKeys, 5063, - activations + activations, + new NonStandardErpRedeemScriptBuilder() ); federationList = Collections.singletonList(federation); diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index e62b900e596..ba7b683f4de 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -47,12 +47,13 @@ import org.junit.jupiter.api.Test; class LegacyErpFederationTest { - private LegacyErpFederation federation; + private ErpFederation federation; private NetworkParameters networkParameters; private List standardKeys; private List emergencyKeys; private long activationDelayValue; private ActivationConfig.ForBlock activations; + private ErpRedeemScriptBuilder erpRedeemScriptBuilder; @BeforeEach void setup() { @@ -71,7 +72,8 @@ void setup() { standardKeys = Arrays.asList( federator0PublicKey, federator1PublicKey, federator2PublicKey, federator3PublicKey, federator4PublicKey, federator5PublicKey, - federator6PublicKey, federator7PublicKey, federator8PublicKey, federator9PublicKey + federator6PublicKey, federator7PublicKey, federator8PublicKey, + federator9PublicKey ); networkParameters = bridgeConstants.getBtcParams(); @@ -79,23 +81,26 @@ void setup() { activationDelayValue = bridgeConstants.getErpFedActivationDelay(); activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); federation = createDefaultLegacyErpFederation(); } - private LegacyErpFederation createDefaultLegacyErpFederation() { + private ErpFederation createDefaultLegacyErpFederation() { List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; + erpRedeemScriptBuilder = ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, networkParameters); - return new LegacyErpFederation( + return new ErpFederation( standardMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue, - activations + activations, + erpRedeemScriptBuilder ); } @@ -155,7 +160,7 @@ void createValidLegacyErpFederation_exactMaxCsvValue() { assertDoesNotThrow(this::createDefaultLegacyErpFederation); } - @Test +/* @Test void createInvalidLegacyErpFederation_aboveMaxScriptSigSize() { // add one member to exceed redeem script size limit List newStandardKeys = federation.getBtcPublicKeys(); @@ -168,7 +173,7 @@ void createInvalidLegacyErpFederation_aboveMaxScriptSigSize() { FederationCreationException.class, this::createDefaultLegacyErpFederation ); assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); - } + }*/ @Test void getErpPubKeys() { @@ -191,43 +196,45 @@ void testEquals_basic() { @Test void testEquals_same() { - ErpFederation otherFederation = new LegacyErpFederation( + ErpFederation otherFederation = new ErpFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); - assertEquals(federation, otherFederation); } @Test void testEquals_differentCreationTime() { - ErpFederation otherFederation = new LegacyErpFederation( + ErpFederation otherFederation = new ErpFederation( federation.getMembers(), federation.getCreationTime().plus(1, ChronoUnit.MILLIS), federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); assertEquals(federation, otherFederation); } @Test void testEquals_differentCreationBlockNumber() { - ErpFederation otherFederation = new LegacyErpFederation( + ErpFederation otherFederation = new ErpFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber() + 1, federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); assertEquals(federation, otherFederation); } @@ -244,7 +251,7 @@ void testEquals_differentNetworkParameters() { void testEquals_differentNumberOfMembers() { // remove federator9 List newStandardKeys = federation.getBtcPublicKeys(); - newStandardKeys.remove(9); + newStandardKeys.remove(newStandardKeys.size() - 1); standardKeys = newStandardKeys; ErpFederation otherFederation = createDefaultLegacyErpFederation(); @@ -268,7 +275,7 @@ void testEquals_differentMembers() { @Test void getP2SHScriptAndAddress() { - // standard and emergency keys from real legacy erp fed in testnet + // standard and emergency keys from last real non-standard erp fed in testnet BridgeConstants bridgeTestNetConstants = BridgeTestNetConstants.getInstance(); networkParameters = bridgeTestNetConstants.getBtcParams(); emergencyKeys = bridgeTestNetConstants.getErpFedPubKeysList(); @@ -296,10 +303,10 @@ void getP2SHScriptAndAddress() { Script p2shScript = realLegacyErpFederation.getP2SHScript(); Address address = realLegacyErpFederation.getAddress(); - String expectedProgram = "a9148f38b3d8ec8816f7f58a390f306bb90bb178d6ac87"; + String expectedProgram = "a91412d5d2996618c8abcb1e6fc17be3cd8e2790c25f87"; Address expectedAddress = Address.fromBase58( networkParameters, - "2N6JWYUb6Li4Kux6UB2eihT7n3rm3YX97uv" + "2MtxpJPt2xCa3AyFYUjTT7Aop9Z6gGf4rqA" ); assertEquals(expectedProgram, Hex.toHexString(p2shScript.getProgram())); @@ -340,14 +347,15 @@ void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { for (RawGeneratedRedeemScript generatedScript : generatedScripts) { // Skip test cases with invalid redeem script that exceed the maximum size if (generatedScript.script.getProgram().length <= MAX_SCRIPT_ELEMENT_SIZE) { - Federation erpFederation = new LegacyErpFederation( + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(generatedScript.mainFed), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 1, NetworkParameters.fromID(NetworkParameters.ID_TESTNET), generatedScript.emergencyFed, generatedScript.timelock, - activations + activations, + erpRedeemScriptBuilder ); Script rskjScript = erpFederation.getRedeemScript(); @@ -360,6 +368,8 @@ void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { @Test void getRedeemScript_before_RSKIP293() { + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + federation = createDefaultLegacyErpFederation(); Script redeemScript = federation.getRedeemScript(); validateErpRedeemScript( redeemScript, @@ -383,6 +393,8 @@ void getRedeemScript_after_RSKIP293() { @Test void getRedeemScript_changes_after_RSKIP293() { + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + federation = createDefaultLegacyErpFederation(); Script preRskip293RedeemScript = federation.getRedeemScript(); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); @@ -394,37 +406,42 @@ void getRedeemScript_changes_after_RSKIP293() { @Test void createErpFederation_testnet_constants_before_RSKIP293() { - createErpFederation(BridgeTestNetConstants.getInstance(), false); + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + createErpFederation(false); } @Test void createErpFederation_testnet_constants_after_RSKIP293() { - createErpFederation(BridgeTestNetConstants.getInstance(), true); + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + createErpFederation(true); } @Test void createErpFederation_mainnet_constants_before_RSKIP293() { - createErpFederation(BridgeMainNetConstants.getInstance(), false); + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET); + createErpFederation(false); } @Test void createErpFederation_mainnet_constants_after_RSKIP293() { - createErpFederation(BridgeMainNetConstants.getInstance(), true); + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET); + createErpFederation(true); } @Test void getRedeemScript_before_RSKIP_284_testnet() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); - - Federation erpFederation = new LegacyErpFederation( + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersFromPks(100, 200, 300), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 1, NetworkParameters.fromID(NetworkParameters.ID_TESTNET), emergencyKeys, activationDelayValue, - activations + activations, + new NonStandardErpRedeemScriptBuilderHardcoaded() ); assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, erpFederation.getRedeemScript()); @@ -432,22 +449,14 @@ void getRedeemScript_before_RSKIP_284_testnet() { @Test void getRedeemScript_before_RSKIP_284_mainnet() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET); + federation = createDefaultLegacyErpFederation(); - Federation erpFederation = new LegacyErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 1, - NetworkParameters.fromID(NetworkParameters.ID_MAINNET), - emergencyKeys, - activationDelayValue, - activations - ); - - Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, erpFederation.getRedeemScript()); + Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); validateErpRedeemScript( - erpFederation.getRedeemScript(), + federation.getRedeemScript(), activationDelayValue, false ); @@ -455,14 +464,15 @@ void getRedeemScript_before_RSKIP_284_mainnet() { @Test void getRedeemScript_after_RSKIP_284_testnet() { - Federation erpFederation = new LegacyErpFederation( + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 1, NetworkParameters.fromID(NetworkParameters.ID_TESTNET), emergencyKeys, activationDelayValue, - activations + activations, + new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() ); Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, erpFederation.getRedeemScript()); @@ -475,14 +485,15 @@ void getRedeemScript_after_RSKIP_284_testnet() { @Test void getRedeemScript_after_RSKIP_284_mainnet() { - Federation erpFederation = new LegacyErpFederation( + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 1, NetworkParameters.fromID(NetworkParameters.ID_MAINNET), emergencyKeys, activationDelayValue, - activations + activations, + new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() ); Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, erpFederation.getRedeemScript()); @@ -547,14 +558,15 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { List federationMembersWithBtcKeys = FederationTestUtils.getFederationMembersWithBtcKeys(standardMultisigKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); - assertThrows(FederationCreationException.class, () -> new LegacyErpFederation( + assertThrows(FederationCreationException.class, () -> new ErpFederation( federationMembersWithBtcKeys, creationTime, 1, btcParams, emergencyMultisigKeys, activationDelay, - activations + activations, + new NonStandardErpRedeemScriptBuilder() )); } @@ -697,63 +709,48 @@ void spendFromErpFed_after_RSKIP293_mainnet_using_standard_multisig() { )); } - private void createErpFederation(BridgeConstants constants, boolean isRskip293Active) { + private void createErpFederation(boolean isRskip293Active) { when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(isRskip293Active); - - Federation erpFederation = new LegacyErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 1, - constants.getBtcParams(), - constants.getErpFedPubKeysList(), - constants.getErpFedActivationDelay(), - activations - ); + federation = createDefaultLegacyErpFederation(); validateErpRedeemScript( - erpFederation.getRedeemScript(), + federation.getRedeemScript(), standardKeys, - constants.getErpFedPubKeysList(), - constants.getErpFedActivationDelay(), + emergencyKeys, + activationDelayValue, isRskip293Active ); } private void spendFromErpFed( - NetworkParameters networkParameters, + NetworkParameters networkParametersValue, long activationDelay, boolean isRskip293Active, boolean signWithEmergencyMultisig) { - List standardKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( + standardKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fed1", "fed2", "fed3", "fed4", "fed5", "fed6", "fed7", "fed8", "fed9", "fed10"}, true ); - List emergencyKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( + emergencyKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"erp1", "erp2", "erp3", "erp4"}, true ); + networkParameters = networkParametersValue; + activationDelayValue = activationDelay; List except = isRskip293Active ? Collections.emptyList() : Collections.singletonList(ConsensusRule.RSKIP293); - ActivationConfig activations = ActivationConfigsForTest.hop400(except); + activations = ActivationConfigsForTest.hop400(except).forBlock(0); - ErpFederation erpFed = new LegacyErpFederation( - FederationMember.getFederationMembersFromKeys(standardKeys), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 1, - networkParameters, - emergencyKeys, - activationDelay, - activations.forBlock(0) - ); + federation = createDefaultLegacyErpFederation(); Coin value = Coin.valueOf(1_000_000); Coin fee = Coin.valueOf(10_000); BtcTransaction fundTx = new BtcTransaction(networkParameters); - fundTx.addOutput(value, erpFed.getAddress()); + fundTx.addOutput(value, federation.getAddress()); Address destinationAddress = BitcoinTestUtils.createP2PKHAddress( networkParameters, @@ -762,7 +759,7 @@ private void spendFromErpFed( FederationTestUtils.spendFromErpFed( networkParameters, - erpFed, + federation, signWithEmergencyMultisig ? emergencyKeys : standardKeys, fundTx.getHash(), 0, diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index 46908b100cd..5e88187048a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -40,7 +40,7 @@ import org.junit.jupiter.params.provider.MethodSource; class P2shErpFederationTest { - private P2shErpFederation federation; + private ErpFederation federation; private NetworkParameters networkParameters; private List standardKeys; private List emergencyKeys; @@ -75,19 +75,20 @@ void setup() { federation = createDefaultP2shErpFederation(); } - private P2shErpFederation createDefaultP2shErpFederation() { + private ErpFederation createDefaultP2shErpFederation() { List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - return new P2shErpFederation( + return new ErpFederation( standardMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue, - activations + activations, + new P2shErpRedeemScriptBuilder() ); } @@ -148,7 +149,7 @@ void createValidP2shErpFederation_exactMaxCsvValue() { assertDoesNotThrow(this::createDefaultP2shErpFederation); } - @Test +/* @Test void createInvalidFederation_aboveMaxScriptSigSize() { // add one member to exceed redeem script size limit List newStandardKeys = federation.getBtcPublicKeys(); @@ -157,11 +158,9 @@ void createInvalidFederation_aboveMaxScriptSigSize() { ); newStandardKeys.add(federator10PublicKey); standardKeys = newStandardKeys; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultP2shErpFederation - ); - assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); - } + assertThrows(FederationCreationException.class, this::createDefaultP2shErpFederation); + //assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); + }*/ @Test void getErpPubKeys() { @@ -184,14 +183,16 @@ void testEquals_basic() { @Test void testEquals_same() { - ErpFederation otherFederation = new P2shErpFederation( + P2shErpRedeemScriptBuilder p2shErpRedeemScriptBuilder = new P2shErpRedeemScriptBuilder(); + ErpFederation otherFederation = new ErpFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - activations + activations, + p2shErpRedeemScriptBuilder ); assertEquals(federation, otherFederation); @@ -271,15 +272,15 @@ void getStandardRedeemScript() { creationBlock, btcParams ); - - P2shErpFederation p2shFed = new P2shErpFederation( - members, - creationTime, - creationBlock, - btcParams, - Arrays.asList(new BtcECKey(), new BtcECKey()), - 10_000, - activations + ErpFederation p2shFed = new ErpFederation( + members, + creationTime, + creationBlock, + btcParams, + Arrays.asList(new BtcECKey(), new BtcECKey()), + 10_000, + activations, + new P2shErpRedeemScriptBuilder() ); assertEquals(legacyFed.getRedeemScript(), p2shFed.getStandardRedeemScript()); @@ -388,14 +389,15 @@ void getErpRedeemScript_compareOtherImplementation_P2SHERPFederation() throws IO for (RawGeneratedRedeemScript generatedScript : generatedScripts) { // Skip test cases with invalid redeem script that exceed the maximum size if (generatedScript.script.getProgram().length <= MAX_SCRIPT_ELEMENT_SIZE) { - Federation erpFederation = new P2shErpFederation( + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(generatedScript.mainFed), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 1, NetworkParameters.fromID(NetworkParameters.ID_TESTNET), generatedScript.emergencyFed, generatedScript.timelock, - activations + activations, + new P2shErpRedeemScriptBuilder() ); Script rskjScript = erpFederation.getRedeemScript(); @@ -422,14 +424,15 @@ void spendFromP2shErpFed( true ); - P2shErpFederation p2shErpFed = new P2shErpFederation( + ErpFederation p2shErpFed = new ErpFederation( FederationMember.getFederationMembersFromKeys(standardKeys), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 0L, networkParameters, emergencyKeys, activationDelay, - mock(ActivationConfig.ForBlock.class) + mock(ActivationConfig.ForBlock.class), + new P2shErpRedeemScriptBuilder() ); Coin value = Coin.valueOf(1_000_000); diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index e0b2d77d73c..e4f49d2df39 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -288,24 +288,28 @@ private void testBuildFederation( Federation expectedFederation; if (isRskip353Active) { - expectedFederation = new P2shErpFederation( + expectedFederation = new ErpFederation( FederationTestUtils.getFederationMembersFromPks(privateKeys), creationTime, 0L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new P2shErpRedeemScriptBuilder() ); } else if (isRskip201Active) { - expectedFederation = new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder = + ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + expectedFederation = new ErpFederation( FederationTestUtils.getFederationMembersFromPks(privateKeys), creationTime, 0L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); } else { expectedFederation = new StandardMultisigFederation( diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index c682f43c700..8c4106c20bd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -136,25 +136,29 @@ private void testChangePowpeg( Federation originalPowpeg; switch (oldPowPegFederationType) { case legacyErp: - originalPowpeg = new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder = + ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + originalPowpeg = new ErpFederation( originalPowpegMembers, Instant.now(), 0, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + erpRedeemScriptBuilder ); break; case p2shErp: - originalPowpeg = new P2shErpFederation( + originalPowpeg = new ErpFederation( originalPowpegMembers, Instant.now(), 0, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new P2shErpRedeemScriptBuilder() ); // TODO: CHECK REDEEMSCRIPT break; @@ -201,15 +205,16 @@ private void testChangePowpeg( argumentCaptor.capture() ); + // TODO check this. maybe adding the FedType to the constructor solves it // Verify new powpeg information Federation newPowPeg = argumentCaptor.getValue(); assertEquals(newPowPegAddress, newPowPeg.getAddress()); switch (newPowPegFederationType) { case legacyErp: - assertSame(LegacyErpFederation.class, newPowPeg.getClass()); + assertSame(ErpFederation.class, newPowPeg.getClass()); break; case p2shErp: - assertSame(P2shErpFederation.class, newPowPeg.getClass()); + assertSame(ErpFederation.class, newPowPeg.getClass()); // TODO: CHECK REDEEMSCRIPT break; default: diff --git a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java index 8d2ef553fe8..17057a002a2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java @@ -164,7 +164,7 @@ void build_pegout_tx_from_erp_federation() { // Use mainnet constants to test a real situation BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); - Federation erpFederation = new LegacyErpFederation( + Federation erpFederation = new ErpFederation( FederationMember.getFederationMembersFromKeys(Arrays.asList( new BtcECKey(), new BtcECKey(), @@ -175,7 +175,8 @@ void build_pegout_tx_from_erp_federation() { bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations + activations, + new NonStandardErpRedeemScriptBuilder() ); List utxos = Arrays.asList( From 5d5a6d75acef022252ed8b590963866c877ae843 Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 16 Nov 2023 10:49:36 -0300 Subject: [PATCH 020/137] Add activations argument to getOldFederation tests. Create one test for each non-standard fed created with each non-standard builder --- .../co/rsk/peg/BridgeStorageProviderTest.java | 73 +++++++++++++++---- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 30ca0a40161..2550256709f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -401,11 +401,6 @@ void getNewFederation_multiKeyVersion() { @Test void getNewFederation_erp_fed() { -/* ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true);*/ BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation newFederation = buildMockFederation(100, 200, 300); ErpFederation erpFederation = new ErpFederation( @@ -683,13 +678,18 @@ void getOldFederation_initialVersion_nullBytes() { @Test void getOldFederation_multiKeyVersion() { Federation oldFederation = buildMockFederation(100, 200, 300); - testGetOldFederation(oldFederation); + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + testGetOldFederation(oldFederation, activations); } @Test - void getOldFederation_erp_fed() { + void getOldFederation_nonStandardHardcoaded_fed() { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation oldFederation = buildMockFederation(100, 200, 300); + + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); ErpFederation erpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), @@ -697,17 +697,63 @@ void getOldFederation_erp_fed() { oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - mock(ActivationConfig.ForBlock.class), + activations, new NonStandardErpRedeemScriptBuilderHardcoaded() ); - testGetOldFederation(erpFederation); + testGetOldFederation(erpFederation, activations); + } + + @Test + void getOldFederation_nonStandardWithUnsignedBE_fed() { + BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + Federation oldFederation = buildMockFederation(100, 200, 300); + + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + ErpFederation erpFederation = new ErpFederation( + oldFederation.getMembers(), + oldFederation.getCreationTime(), + oldFederation.getCreationBlockNumber(), + oldFederation.getBtcParams(), + bridgeConstants.getErpFedPubKeysList(), + bridgeConstants.getErpFedActivationDelay(), + activations, + new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() + ); + + testGetOldFederation(erpFederation, activations); + } + + @Test + void getOldFederation_nonStandard_fed() { + BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + Federation oldFederation = buildMockFederation(100, 200, 300); + + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + ErpFederation erpFederation = new ErpFederation( + oldFederation.getMembers(), + oldFederation.getCreationTime(), + oldFederation.getCreationBlockNumber(), + oldFederation.getBtcParams(), + bridgeConstants.getErpFedPubKeysList(), + bridgeConstants.getErpFedActivationDelay(), + activations, + new NonStandardErpRedeemScriptBuilder() + ); + + testGetOldFederation(erpFederation, activations); } @Test void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation oldFederation = buildMockFederation(100, 200, 300); + + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); ErpFederation p2shErpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), @@ -715,11 +761,11 @@ void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - mock(ActivationConfig.ForBlock.class), + activations, new P2shErpRedeemScriptBuilder() ); - testGetOldFederation(p2shErpFederation); + testGetOldFederation(p2shErpFederation, activations); } @Test @@ -3575,8 +3621,7 @@ void getReleaseRequestQueueSize_when_releaseRequestQueue_is_not_null() throws IO Assertions.assertEquals(2, storageProvider.getReleaseRequestQueueSize()); } - // siempre devuelve la hardcoaded? - private void testGetOldFederation(Federation oldFederation) { + private void testGetOldFederation(Federation oldFederation, ActivationConfig.ForBlock activations) { BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); @@ -3584,7 +3629,7 @@ private void testGetOldFederation(Federation oldFederation) { repositoryMock, mockAddress("aabbccdd"), bridgeConstants, - mock(ActivationConfig.ForBlock.class) + activations ); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { From 82844e7b7a69434b55ea37d4f50c2720b4c2e313 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Wed, 17 Jan 2024 19:07:12 -0300 Subject: [PATCH 021/137] fix eth_getStorage non existing key response --- .../co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java | 2 ++ .../src/main/java/org/ethereum/rpc/Web3Impl.java | 3 ++- .../test/java/org/ethereum/rpc/Web3ImplTest.java | 14 +++++++------- .../java/org/ethereum/rpc/Web3ImplUnitTest.java | 3 +-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java index dbb8029ed5e..d15decdc701 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java +++ b/rskj-core/src/main/java/co/rsk/rpc/netty/JsonRpcWeb3ServerHandler.java @@ -107,6 +107,8 @@ protected void channelRead0(ChannelHandlerContext ctx, ByteBufHolder request) th int errorCode = ErrorResolver.JsonError.CUSTOM_SERVER_ERROR_LOWER; responseContent = buildErrorContent(errorCode, unexpectedErrorMsg); responseCode = errorCode; + } finally { + ReflectionUtil.clearCache(); } ctx.fireChannelRead(new Web3Result( diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index 1c224f659d3..f9057787f13 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -86,6 +86,7 @@ public class Web3Impl implements Web3 { private static final Logger logger = LoggerFactory.getLogger("web3"); private static final String CLIENT_VERSION_PREFIX = "RskJ"; + private static final String NON_EXISTING_KEY_RESPONSE = "0x0000000000000000000000000000000000000000000000000000000000000000"; private final MinerClient minerClient; private final MinerServer minerServer; @@ -487,7 +488,7 @@ private String eth_getStorageAt(HexAddressParam address, HexNumberParam storageI .getStorageValue(addr, DataWord.valueOf(HexUtils.strHexOrStrNumberToByteArray(storageIdx.getHexNumber()))); if (sv == null) { - s = "0x0"; + s = NON_EXISTING_KEY_RESPONSE; } else { s = HexUtils.toUnformattedJsonHex(sv.getData()); } diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index f8ac098dfff..1ac91726598 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -107,9 +107,9 @@ * Created by Ruben Altman on 09/06/2016. */ class Web3ImplTest { - private static final String BALANCE_10K_HEX = "0x2710"; //10.000 private static final String CALL_RESPOND = "0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000"; + private static final String NON_EXISTING_KEY_RESPONSE = "0x0000000000000000000000000000000000000000000000000000000000000000"; private final TestSystemProperties config = new TestSystemProperties(); private final BlockFactory blockFactory = new BlockFactory(config.getActivationConfig()); @@ -367,7 +367,7 @@ void getBalanceWithAccountAndBlockWithTransaction() { //[ "0x
", { "blockNumber": "0x0" } -> return storage at given address in genesis block void getStorageAtAccountAndBlockNumber() { final ChainParams chain = chainWithAccount10kBalance(false); - assertByBlockNumber("0x0", blockRef -> chain.web3.eth_getStorageAt( + assertByBlockNumber(NON_EXISTING_KEY_RESPONSE, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -377,7 +377,7 @@ void getStorageAtAccountAndBlockNumber() { //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" } -> return storage at given address in genesis block void getStorageAtAccountAndBlockHash() { final ChainParams chain = chainWithAccount10kBalance(false); - assertByBlockHash("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertByBlockHash(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -428,7 +428,7 @@ void getStorageAtAccountAndNonCanonicalBlockHashWhenCanonicalIsRequired() { //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": true } -> return storage at given address in genesis block void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertCanonicalBlockHashWhenCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertCanonicalBlockHashWhenCanonical(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -438,7 +438,7 @@ void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsRequired() { //[ "0x
", { "blockHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", "requireCanonical": false } -> return storage at given address in genesis block void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(false); - assertCanonicalBlockHashWhenNotCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertCanonicalBlockHashWhenNotCanonical(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -448,7 +448,7 @@ void getStorageAtAccountAndCanonicalBlockHashWhenCanonicalIsNotRequired() { // [ "0x
", { "blockHash": "0x", "requireCanonical": false } -> return storage at given address in specified block void getStorageAtAccountAndNonCanonicalBlockHashWhenCanonicalIsNotRequired() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHashWhenNotCanonical("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertNonCanonicalBlockHashWhenNotCanonical(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); @@ -458,7 +458,7 @@ void getStorageAtAccountAndNonCanonicalBlockHashWhenCanonicalIsNotRequired() { // [ "0x
", { "blockHash": "0x" } -> return storage at given address in specified bloc void getStorageAtAccountAndNonCanonicalBlockHash() { final ChainParams chain = chainWithAccount10kBalance(true); - assertNonCanonicalBlockHash("0x0", chain.block, blockRef -> chain.web3.eth_getStorageAt( + assertNonCanonicalBlockHash(NON_EXISTING_KEY_RESPONSE, chain.block, blockRef -> chain.web3.eth_getStorageAt( new HexAddressParam(chain.accountAddress), new HexNumberParam("0x0"), new BlockRefParam(blockRef))); diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java index 6dfe17b61fd..5c1d7db144c 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplUnitTest.java @@ -222,8 +222,7 @@ void eth_getStorageAtEmptyCell() { .thenReturn(null); String result = target.eth_getStorageAt(hexAddressParam, hexNumberParam, blockRefParam); - assertEquals("0x0", - result); + assertEquals("0x0000000000000000000000000000000000000000000000000000000000000000", result); } @Test From 9bf0956ceaa2f9f9f2d608486cfec42ab97315d5 Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 16 Nov 2023 15:41:06 -0300 Subject: [PATCH 022/137] Refactor bridge storage logic. Make tests related to non-standard fed to use activations logic. Rename defineErpRedeemScriptBuilder to defineNonStandardErpRedeemScriptBuilder. --- .../co/rsk/peg/BridgeSerializationUtils.java | 2 +- .../co/rsk/peg/BridgeStorageProvider.java | 38 +++++++--------- .../main/java/co/rsk/peg/ErpFederation.java | 2 - .../rsk/peg/ErpRedeemScriptBuilderUtils.java | 29 +++---------- .../java/co/rsk/peg/PendingFederation.java | 2 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 2 +- .../BridgeStorageProviderFederationTests.java | 2 +- .../co/rsk/peg/BridgeStorageProviderTest.java | 43 +++++++++++-------- .../co/rsk/peg/LegacyErpFederationTest.java | 14 +++--- .../co/rsk/peg/P2shErpFederationTest.java | 13 ++++-- .../co/rsk/peg/PendingFederationTest.java | 2 +- .../java/co/rsk/peg/PowpegMigrationTest.java | 2 +- 12 files changed, 68 insertions(+), 83 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index ca70efc467e..b01b58475b5 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -327,7 +327,7 @@ public static ErpFederation deserializeLegacyErpFederation( ); ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); return new ErpFederation( federation.getMembers(), diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 62a00ac1745..06365d9eab9 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -39,6 +39,7 @@ import java.util.*; import static co.rsk.peg.BridgeStorageIndexKey.*; +import static co.rsk.peg.ErpRedeemScriptBuilderUtils.checkIfNetworkParametersAreTestnetOrRegtest; import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; /** @@ -349,7 +350,6 @@ public void setNewFederation(Federation federation) { newFederation = federation; } - // TODO: refactor this builder logic /** * Save the new federation * Only saved if a federation was set with BridgeStorageProvider::setNewFederation @@ -361,29 +361,26 @@ public void saveNewFederation() { RepositorySerializer serializer = BridgeSerializationUtils::serializeFederationOnlyBtcKeys; + // TODO refactor when we have federation types if (activations.isActive(RSKIP123)) { - if (newFederation instanceof ErpFederation) { + if (newFederation instanceof StandardMultisigFederation) { + saveStorageVersion( + NEW_FEDERATION_FORMAT_VERSION.getKey(), + STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION + ); + } else if (newFederation instanceof ErpFederation) { ErpRedeemScriptBuilder builder = ((ErpFederation) newFederation).erpRedeemScriptBuilder; - if (activations.isActive(RSKIP353) - && builder instanceof P2shErpRedeemScriptBuilder) { + if (builder instanceof P2shErpRedeemScriptBuilder) { saveStorageVersion( NEW_FEDERATION_FORMAT_VERSION.getKey(), P2SH_ERP_FEDERATION_FORMAT_VERSION ); - } else if (activations.isActive(RSKIP201) - && (builder instanceof NonStandardErpRedeemScriptBuilder - || builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE - || builder instanceof NonStandardErpRedeemScriptBuilderHardcoaded)) { + } else { saveStorageVersion( NEW_FEDERATION_FORMAT_VERSION.getKey(), LEGACY_ERP_FEDERATION_FORMAT_VERSION ); } - } else { - saveStorageVersion( - NEW_FEDERATION_FORMAT_VERSION.getKey(), - STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION - ); } serializer = BridgeSerializationUtils::serializeFederation; } @@ -420,7 +417,7 @@ public void setOldFederation(Federation federation) { oldFederation = federation; } - // TODO refactor this builder logic + /** * Save the old federation */ @@ -430,20 +427,16 @@ protected void saveOldFederation() { } RepositorySerializer serializer = BridgeSerializationUtils::serializeFederationOnlyBtcKeys; + // TODO: refactor when we have federation types if (activations.isActive(RSKIP123)) { if (oldFederation instanceof ErpFederation) { ErpRedeemScriptBuilder builder = ((ErpFederation) oldFederation).erpRedeemScriptBuilder; - if (activations.isActive(RSKIP353) - && builder instanceof P2shErpRedeemScriptBuilder) { + if (builder instanceof P2shErpRedeemScriptBuilder) { saveStorageVersion( OLD_FEDERATION_FORMAT_VERSION.getKey(), P2SH_ERP_FEDERATION_FORMAT_VERSION ); - } else if (activations.isActive(RSKIP201) - && (builder instanceof NonStandardErpRedeemScriptBuilder - || builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE - || builder instanceof NonStandardErpRedeemScriptBuilderHardcoaded - )) { + } else { saveStorageVersion( OLD_FEDERATION_FORMAT_VERSION.getKey(), LEGACY_ERP_FEDERATION_FORMAT_VERSION @@ -1054,8 +1047,7 @@ private DataWord getStorageKeyForFlyoverFederationInformation(byte[] flyoverFede private DataWord getStorageKeyForNewFederationBtcUtxos() { DataWord key = NEW_FEDERATION_BTC_UTXOS_KEY.getKey(); - if (networkParameters.getId().equals(NetworkParameters.ID_TESTNET) - || networkParameters.getId().equals(NetworkParameters.ID_REGTEST)) { + if (checkIfNetworkParametersAreTestnetOrRegtest(networkParameters)) { if (activations.isActive(RSKIP284)) { key = NEW_FEDERATION_BTC_UTXOS_KEY_FOR_TESTNET_PRE_HOP.getKey(); } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java index a21ee9c5692..4bd95d39f52 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java @@ -73,8 +73,6 @@ public Script getRedeemScript() { if (redeemScript == null) { redeemScript = erpRedeemScriptBuilder.createRedeemScript(getDefaultPublicKeys(), erpPubKeys, activationDelay); } - // TODO: definir donde va esta validacion. - FederationUtils.validateScriptSize(redeemScript); return redeemScript; } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java index 9a57e78b5a3..0029e0dcfc8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java @@ -1,7 +1,6 @@ package co.rsk.peg; import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.config.BridgeConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -10,31 +9,13 @@ public class ErpRedeemScriptBuilderUtils { private ErpRedeemScriptBuilderUtils() { } - public static ErpRedeemScriptBuilder defineErpRedeemScriptBuilder( - ActivationConfig.ForBlock activations, - BridgeConstants bridgeConstants) { - - ErpRedeemScriptBuilder erpRedeemScriptBuilder; - - NetworkParameters networkParameters = bridgeConstants.getBtcParams(); - boolean networkParametersIsTestnetOrRegtest = checkIfNetworkParameterIsTestnetOrRegtest(networkParameters); - - if(!activations.isActive(ConsensusRule.RSKIP284) && networkParametersIsTestnetOrRegtest) { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoaded(); - } else if (!activations.isActive(ConsensusRule.RSKIP293)) { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); - } else erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); - - return erpRedeemScriptBuilder; - } - - public static ErpRedeemScriptBuilder defineErpRedeemScriptBuilder( + public static ErpRedeemScriptBuilder defineNonStandardErpRedeemScriptBuilder( ActivationConfig.ForBlock activations, NetworkParameters networkParameters) { ErpRedeemScriptBuilder erpRedeemScriptBuilder; - boolean networkParametersIsTestnetOrRegtest = checkIfNetworkParameterIsTestnetOrRegtest(networkParameters); + boolean networkParametersIsTestnetOrRegtest = checkIfNetworkParametersAreTestnetOrRegtest(networkParameters); if(!activations.isActive(ConsensusRule.RSKIP284) && networkParametersIsTestnetOrRegtest) { erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoaded(); @@ -45,8 +26,8 @@ public static ErpRedeemScriptBuilder defineErpRedeemScriptBuilder( return erpRedeemScriptBuilder; } - private static boolean checkIfNetworkParameterIsTestnetOrRegtest(NetworkParameters networkParametersId) { - return networkParametersId.getId().equals(NetworkParameters.ID_TESTNET) - || networkParametersId.getId().equals(NetworkParameters.ID_REGTEST); + public static boolean checkIfNetworkParametersAreTestnetOrRegtest(NetworkParameters networkParameters) { + return networkParameters.getId().equals(NetworkParameters.ID_TESTNET) + || networkParameters.getId().equals(NetworkParameters.ID_REGTEST); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java index a7cc97ad246..0f2fb34589b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java @@ -122,7 +122,7 @@ public Federation buildFederation( logger.info("[buildFederation] Going to create an ERP Federation"); ErpRedeemScriptBuilder erpRedeemScriptBuilder - = ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + = ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); return new ErpFederation( members, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 4a21668aa58..b4daeb535e7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -1240,7 +1240,7 @@ private void testSerializeAndDeserializeFederation( when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(isRskip353Active); ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); for (int i = 0; i < NUM_CASES; i++) { int numMembers = randomInRange(2, 14); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index 7a288f6ce23..d11881ac2cd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -617,7 +617,7 @@ private Federation createFederation(int version) { ); case LEGACY_ERP_FEDERATION_FORMAT_VERSION: ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstantsRegtest); + ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstantsRegtest.getBtcParams()); return new ErpFederation( members, Instant.now(), diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 2550256709f..a52df640e9a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -688,8 +688,9 @@ void getOldFederation_nonStandardHardcoaded_fed() { Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + ErpFederation erpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), @@ -710,8 +711,10 @@ void getOldFederation_nonStandardWithUnsignedBE_fed() { Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + ErpFederation erpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), @@ -732,8 +735,11 @@ void getOldFederation_nonStandard_fed() { Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + ErpFederation erpFederation = new ErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), @@ -874,7 +880,6 @@ void saveOldFederation_postMultikey() { void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation oldFederation = buildMockFederation(100, 200, 300); @@ -896,7 +901,6 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(true); BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); Federation oldFederation = buildMockFederation(100, 200, 300); @@ -951,7 +955,12 @@ void saveOldFederation_postMultikey_setToNull() { try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class, CALLS_REAL_METHODS)) { List storageBytesCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsAllForks); + BridgeStorageProvider storageProvider = new BridgeStorageProvider( + repositoryMock, + mockAddress("aabbccdd"), + config.getNetworkConstants().getBridgeConstants(), + activationsAllForks + ); Mockito.doAnswer((InvocationOnMock invocation) -> { storageBytesCalls.add(0); @@ -3709,7 +3718,6 @@ private void testSaveOldFederation(Federation oldFederation, int version, Activa } } - // este deberia devolver siempre la nonstandard harcoaded? dado que es justo la que vino post multikey? private void testGetNewFederationPostMultiKey(Federation federation) { List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); @@ -3848,7 +3856,7 @@ private void testGetNewFederationBtcUTXOs(boolean isRskip284Active, boolean isRs List obtainedUtxos = provider.getNewFederationBtcUTXOs(); - if ((networkId.equals(NetworkParameters.ID_TESTNET)/* || networkId.equals(NetworkParameters.ID_REGTEST)*/)&& (isRskip284Active || isRskip293Active)) { + if (networkId.equals(NetworkParameters.ID_TESTNET) && (isRskip284Active || isRskip293Active)) { if (isRskip293Active) { Assertions.assertEquals(federationUtxosAfterRskip293Activation, obtainedUtxos); } else { @@ -3897,7 +3905,7 @@ private void testSaveNewFederationBtcUTXOs(boolean isRskip284Active, String netw provider.getNewFederationBtcUTXOs(); // Ensure there are elements in the UTXOs list provider.saveNewFederationBtcUTXOs(); - if (isRskip284Active && (networkId.equals(NetworkParameters.ID_TESTNET) /*|| networkId.equals(NetworkParameters.ID_REGTEST)*/)) { + if (isRskip284Active && networkId.equals(NetworkParameters.ID_TESTNET)) { verify(repository, never()).addStorageBytes( eq(PrecompiledContracts.BRIDGE_ADDR), eq(NEW_FEDERATION_BTC_UTXOS_KEY.getKey()), @@ -3962,19 +3970,16 @@ private static Repository createRepository() { return new MutableRepository(new MutableTrieCache(new MutableTrieImpl(trieStore, new Trie(trieStore)))); } - // TODO refactor private int getFederationVersion(Federation federation) { if (federation instanceof StandardMultisigFederation) { return BridgeStorageProvider.STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION; - } - ErpRedeemScriptBuilder builder = ((ErpFederation) federation).erpRedeemScriptBuilder; - if (builder instanceof NonStandardErpRedeemScriptBuilder - || builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE - || builder instanceof NonStandardErpRedeemScriptBuilderHardcoaded) { - return BridgeStorageProvider.LEGACY_ERP_FEDERATION_FORMAT_VERSION; - } - if (builder instanceof P2shErpRedeemScriptBuilder) { - return BridgeStorageProvider.P2SH_ERP_FEDERATION_FORMAT_VERSION; + } else if (federation instanceof ErpFederation) { + ErpRedeemScriptBuilder builder = ((ErpFederation) federation).erpRedeemScriptBuilder; + if (builder instanceof P2shErpRedeemScriptBuilder) { + return BridgeStorageProvider.P2SH_ERP_FEDERATION_FORMAT_VERSION; + } else { + return BridgeStorageProvider.LEGACY_ERP_FEDERATION_FORMAT_VERSION; + } } throw new IllegalArgumentException("Unknown Federation type: " + federation.getClass()); } diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index ba7b683f4de..33f17584ea8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -90,7 +90,8 @@ private ErpFederation createDefaultLegacyErpFederation() { List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - erpRedeemScriptBuilder = ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, networkParameters); + erpRedeemScriptBuilder = + ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, networkParameters); return new ErpFederation( standardMembers, @@ -160,8 +161,8 @@ void createValidLegacyErpFederation_exactMaxCsvValue() { assertDoesNotThrow(this::createDefaultLegacyErpFederation); } -/* @Test - void createInvalidLegacyErpFederation_aboveMaxScriptSigSize() { + @Test + void createInvalidNonStandardBuilder_aboveMaxScriptSigSize() { // add one member to exceed redeem script size limit List newStandardKeys = federation.getBtcPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( @@ -169,11 +170,14 @@ void createInvalidLegacyErpFederation_aboveMaxScriptSigSize() { ); newStandardKeys.add(federator10PublicKey); standardKeys = newStandardKeys; + + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultLegacyErpFederation + FederationCreationException.class, + () -> builder.createRedeemScript(standardKeys, emergencyKeys, activationDelayValue) ); assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); - }*/ + } @Test void getErpPubKeys() { diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index 5e88187048a..aeae04e8c27 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -149,7 +149,7 @@ void createValidP2shErpFederation_exactMaxCsvValue() { assertDoesNotThrow(this::createDefaultP2shErpFederation); } -/* @Test + @Test void createInvalidFederation_aboveMaxScriptSigSize() { // add one member to exceed redeem script size limit List newStandardKeys = federation.getBtcPublicKeys(); @@ -158,9 +158,14 @@ void createInvalidFederation_aboveMaxScriptSigSize() { ); newStandardKeys.add(federator10PublicKey); standardKeys = newStandardKeys; - assertThrows(FederationCreationException.class, this::createDefaultP2shErpFederation); - //assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); - }*/ + + ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + FederationCreationException exception = assertThrows( + FederationCreationException.class, + () -> builder.createRedeemScript(standardKeys, emergencyKeys, activationDelayValue) + ); + assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); + } @Test void getErpPubKeys() { diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index e4f49d2df39..24fd63b0fa1 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -300,7 +300,7 @@ private void testBuildFederation( ); } else if (isRskip201Active) { ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); expectedFederation = new ErpFederation( FederationTestUtils.getFederationMembersFromPks(privateKeys), creationTime, diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index 8c4106c20bd..a50d95250db 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -137,7 +137,7 @@ private void testChangePowpeg( switch (oldPowPegFederationType) { case legacyErp: ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineErpRedeemScriptBuilder(activations, bridgeConstants); + ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); originalPowpeg = new ErpFederation( originalPowpegMembers, Instant.now(), From a54010bd329e5734b5f19d24f9066125eb31d9af Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 16 Nov 2023 18:03:38 -0300 Subject: [PATCH 023/137] Make saveNewFederation logic order the same as saveOldFederation --- .../java/co/rsk/peg/BridgeSerializationUtils.java | 1 - .../java/co/rsk/peg/BridgeStorageProvider.java | 15 +++++++-------- .../co/rsk/peg/ErpRedeemScriptBuilderUtils.java | 4 +++- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index b01b58475b5..457b5d5ecd2 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -314,7 +314,6 @@ public static StandardMultisigFederation deserializeStandardMultisigFederation( BridgeSerializationUtils::deserializeFederationMember ); } -// TODO change Legacy to NonStandard in the name public static ErpFederation deserializeLegacyErpFederation( byte[] data, BridgeConstants bridgeConstants, diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 06365d9eab9..d75cf2732d4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -361,14 +361,8 @@ public void saveNewFederation() { RepositorySerializer serializer = BridgeSerializationUtils::serializeFederationOnlyBtcKeys; - // TODO refactor when we have federation types if (activations.isActive(RSKIP123)) { - if (newFederation instanceof StandardMultisigFederation) { - saveStorageVersion( - NEW_FEDERATION_FORMAT_VERSION.getKey(), - STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION - ); - } else if (newFederation instanceof ErpFederation) { + if (newFederation instanceof ErpFederation) { ErpRedeemScriptBuilder builder = ((ErpFederation) newFederation).erpRedeemScriptBuilder; if (builder instanceof P2shErpRedeemScriptBuilder) { saveStorageVersion( @@ -381,6 +375,11 @@ public void saveNewFederation() { LEGACY_ERP_FEDERATION_FORMAT_VERSION ); } + } else { + saveStorageVersion( + NEW_FEDERATION_FORMAT_VERSION.getKey(), + STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION + ); } serializer = BridgeSerializationUtils::serializeFederation; } @@ -427,7 +426,6 @@ protected void saveOldFederation() { } RepositorySerializer serializer = BridgeSerializationUtils::serializeFederationOnlyBtcKeys; - // TODO: refactor when we have federation types if (activations.isActive(RSKIP123)) { if (oldFederation instanceof ErpFederation) { ErpRedeemScriptBuilder builder = ((ErpFederation) oldFederation).erpRedeemScriptBuilder; @@ -443,6 +441,7 @@ protected void saveOldFederation() { ); } } else { + // assume it is a standard federation to keep backwards compatibility saveStorageVersion( OLD_FEDERATION_FORMAT_VERSION.getKey(), STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java index 0029e0dcfc8..15c71e5f744 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java @@ -21,7 +21,9 @@ public static ErpRedeemScriptBuilder defineNonStandardErpRedeemScriptBuilder( erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoaded(); } else if (!activations.isActive(ConsensusRule.RSKIP293)) { erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); - } else erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); + } else { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); + } return erpRedeemScriptBuilder; } From eb7489bf92a8fc4681ed1fc630cd61e7f166227a Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 17 Nov 2023 12:27:33 -0300 Subject: [PATCH 024/137] Rename ErpRedeemScriptBuilderUtils to NonStandardErpRedeemScriptBuilderFactory. Move validations methods from builders to a utils class. Rename standard to default in erp context. Split some classes, errors and methods to be clearer and more scalable. Remove regtest validation from NonStandard builder factory class --- .../main/java/co/rsk/peg/BridgeBtcWallet.java | 2 +- .../co/rsk/peg/BridgeSerializationUtils.java | 4 +- .../co/rsk/peg/BridgeStorageProvider.java | 4 +- .../main/java/co/rsk/peg/BridgeSupport.java | 14 +- .../src/main/java/co/rsk/peg/BridgeUtils.java | 32 +- .../main/java/co/rsk/peg/ErpFederation.java | 53 ++- .../co/rsk/peg/ErpRedeemScriptBuilder.java | 7 +- ...RedeemScriptBuilderCreationException.java} | 7 +- .../rsk/peg/ErpRedeemScriptBuilderUtils.java | 55 ++-- .../src/main/java/co/rsk/peg/Federation.java | 2 +- .../java/co/rsk/peg/FederationSupport.java | 4 +- .../rsk/peg/FlyoverCompatibleBtcWallet.java | 2 +- .../NonStandardErpRedeemScriptBuilder.java | 66 ++-- ...StandardErpRedeemScriptBuilderFactory.java | 34 ++ ...ndardErpRedeemScriptBuilderHardcoaded.java | 5 +- ...pRedeemScriptBuilderWithCsvUnsignedBE.java | 68 ++-- .../rsk/peg/P2shErpRedeemScriptBuilder.java | 62 +--- .../java/co/rsk/peg/PendingFederation.java | 6 +- .../co/rsk/peg/ScriptCreationException.java | 21 ++ ...ationUtils.java => ScriptValidations.java} | 14 +- .../rsk/peg/StandardMultisigFederation.java | 4 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 4 +- .../peg/utils/BrigeEventLoggerLegacyImpl.java | 4 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 14 +- .../BridgeStorageProviderFederationTests.java | 3 +- .../co/rsk/peg/BridgeStorageProviderTest.java | 304 +++++++++--------- .../peg/BridgeSupportAddSignatureTest.java | 16 +- .../rsk/peg/BridgeSupportTestIntegration.java | 12 +- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 4 +- .../co/rsk/peg/LegacyErpFederationTest.java | 55 ++-- .../co/rsk/peg/P2shErpFederationTest.java | 60 ++-- .../test/java/co/rsk/peg/PegTestUtils.java | 22 +- .../co/rsk/peg/PendingFederationTest.java | 2 +- .../java/co/rsk/peg/PowpegMigrationTest.java | 12 +- .../peg/StandardMultisigFederationTest.java | 20 +- .../peg/performance/ActiveFederationTest.java | 2 +- .../performance/PendingFederationTest.java | 2 +- .../performance/RetiringFederationTest.java | 2 +- .../peg/utils/BridgeEventLoggerImplTest.java | 4 +- .../BridgeEventLoggerLegacyImplTest.java | 4 +- 40 files changed, 492 insertions(+), 520 deletions(-) rename rskj-core/src/main/java/co/rsk/peg/{FederationCreationException.java => ErpRedeemScriptBuilderCreationException.java} (66%) create mode 100644 rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/ScriptCreationException.java rename rskj-core/src/main/java/co/rsk/peg/{FederationUtils.java => ScriptValidations.java} (53%) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java b/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java index c777f7b8a17..3c5b77973c1 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java @@ -55,6 +55,6 @@ public RedeemData findRedeemDataFromScriptHash(byte[] payToScriptHash) { Optional destinationFederation = getDestinationFederation(payToScriptHash); return destinationFederation.map(federation -> RedeemData - .of(federation.getBtcPublicKeys(), federation.getRedeemScript())).orElse(null); + .of(federation.getMembersPublicKeys(), federation.getRedeemScript())).orElse(null); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 457b5d5ecd2..0813cdfc2cd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -326,7 +326,7 @@ public static ErpFederation deserializeLegacyErpFederation( ); ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); return new ErpFederation( federation.getMembers(), @@ -402,7 +402,7 @@ private static FederationMember deserializeFederationMember(byte[] data) { * See BridgeSerializationUtils::serializeBtcPublicKeys */ public static byte[] serializePendingFederationOnlyBtcKeys(PendingFederation pendingFederation) { - return serializeBtcPublicKeys(pendingFederation.getBtcPublicKeys()); + return serializeBtcPublicKeys(pendingFederation.getMembersPublicKeys()); } // For the serialization format, see BridgeSerializationUtils::serializePendingFederationOnlyBtcKeys diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index d75cf2732d4..e708ab0bea5 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -39,7 +39,7 @@ import java.util.*; import static co.rsk.peg.BridgeStorageIndexKey.*; -import static co.rsk.peg.ErpRedeemScriptBuilderUtils.checkIfNetworkParametersAreTestnetOrRegtest; +import static co.rsk.peg.NonStandardErpRedeemScriptBuilderFactory.*; import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; /** @@ -1046,7 +1046,7 @@ private DataWord getStorageKeyForFlyoverFederationInformation(byte[] flyoverFede private DataWord getStorageKeyForNewFederationBtcUtxos() { DataWord key = NEW_FEDERATION_BTC_UTXOS_KEY.getKey(); - if (checkIfNetworkParametersAreTestnetOrRegtest(networkParameters)) { + if (checkIfNetworkIsTestnet(networkParameters)) { if (activations.isActive(RSKIP284)) { key = NEW_FEDERATION_BTC_UTXOS_KEY_FOR_TESTNET_PRE_HOP.getKey(); } 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 3190c29a646..e2fb8aa79a6 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1898,7 +1898,7 @@ public Address getFederationAddress() { * @return the federation size */ public Integer getFederationSize() { - return getActiveFederation().getBtcPublicKeys().size(); + return getActiveFederation().getMembersPublicKeys().size(); } /** @@ -1967,7 +1967,7 @@ public Integer getRetiringFederationSize() { return -1; } - return retiringFederation.getBtcPublicKeys().size(); + return retiringFederation.getMembersPublicKeys().size(); } /** @@ -1994,7 +1994,7 @@ public byte[] getRetiringFederatorPublicKey(int index) { return null; } - List publicKeys = retiringFederation.getBtcPublicKeys(); + List publicKeys = retiringFederation.getMembersPublicKeys(); if (index < 0 || index >= publicKeys.size()) { throw new IndexOutOfBoundsException(String.format("Retiring federator index must be between 0 and %d", publicKeys.size() - 1)); @@ -2117,7 +2117,7 @@ private Integer addFederatorPublicKeyMultikey(boolean dryRun, BtcECKey btcKey, E return -1; } - if (currentPendingFederation.getBtcPublicKeys().contains(btcKey) || + if (currentPendingFederation.getMembersPublicKeys().contains(btcKey) || currentPendingFederation.getMembers().stream().map(FederationMember::getRskPublicKey).anyMatch(k -> k.equals(rskKey)) || currentPendingFederation.getMembers().stream().map(FederationMember::getMstPublicKey).anyMatch(k -> k.equals(mstKey))) { return -2; @@ -2198,7 +2198,7 @@ protected Integer commitFederation(boolean dryRun, Keccak256 hash) throws IOExce long nextFederationCreationBlockHeight = rskExecutionBlock.getNumber(); provider.setNextFederationCreationBlockHeight(nextFederationCreationBlockHeight); Script oldFederationP2SHScript = activations.isActive(RSKIP377) && oldFederation instanceof ErpFederation ? - ((ErpFederation) oldFederation).getStandardP2SHScript() : oldFederation.getP2SHScript(); + ((ErpFederation) oldFederation).getDefaultP2SHScript() : oldFederation.getP2SHScript(); provider.setLastRetiredFederationP2SHScript(oldFederationP2SHScript); } @@ -2373,7 +2373,7 @@ public Integer getPendingFederationSize() { return -1; } - return currentPendingFederation.getBtcPublicKeys().size(); + return currentPendingFederation.getMembersPublicKeys().size(); } /** @@ -2388,7 +2388,7 @@ public byte[] getPendingFederatorPublicKey(int index) { return null; } - List publicKeys = currentPendingFederation.getBtcPublicKeys(); + List publicKeys = currentPendingFederation.getMembersPublicKeys(); if (index < 0 || index >= publicKeys.size()) { throw new IndexOutOfBoundsException(String.format("Federator index must be between 0 and %d", publicKeys.size() - 1)); 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 99bcbcdaa68..aea5bab53e4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java @@ -17,21 +17,7 @@ */ package co.rsk.peg; -import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP284; -import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP293; - -import co.rsk.bitcoinj.core.Address; -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.BtcTransaction; -import co.rsk.bitcoinj.core.Coin; -import co.rsk.bitcoinj.core.Context; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.core.PartialMerkleTree; -import co.rsk.bitcoinj.core.Sha256Hash; -import co.rsk.bitcoinj.core.TransactionInput; -import co.rsk.bitcoinj.core.UTXO; -import co.rsk.bitcoinj.core.Utils; -import co.rsk.bitcoinj.core.VerificationException; +import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.crypto.TransactionSignature; import co.rsk.bitcoinj.script.RedeemScriptParser; import co.rsk.bitcoinj.script.RedeemScriptParser.MultiSigType; @@ -45,12 +31,6 @@ import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.utils.BtcTransactionFormatUtils; -import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; -import javax.annotation.Nonnull; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -61,6 +41,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import javax.annotation.Nonnull; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP284; +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP293; + /** * @author Oscar Guindzberg */ diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java index 4bd95d39f52..b9e6c72ca0e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java @@ -7,21 +7,18 @@ import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.peg.utils.EcKeyUtils; import java.time.Instant; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import static co.rsk.peg.FederationCreationException.Reason.INVALID_CSV_VALUE; -import static co.rsk.peg.FederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; + +import static co.rsk.peg.ErpRedeemScriptBuilderCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; public class ErpFederation extends Federation { - protected static final long MAX_CSV_VALUE = 65_535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value protected final List erpPubKeys; protected final long activationDelay; protected final ActivationConfig.ForBlock activations; protected Script standardRedeemScript; protected Script standardP2SHScript; - protected ErpRedeemScriptBuilder erpRedeemScriptBuilder; protected ErpFederation( @@ -35,7 +32,7 @@ protected ErpFederation( ErpRedeemScriptBuilder erpRedeemScriptBuilder) { super(members, creationTime, creationBlockNumber, btcParams); - validateErpFederationValues(erpPubKeys, activationDelay); + validateEmergencyKeysAreNotNullNorEmpty(erpPubKeys); this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpPubKeys); this.activationDelay = activationDelay; @@ -43,23 +40,27 @@ protected ErpFederation( this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; } - public List getDefaultPublicKeys() { - List defaultPubKeys = new ArrayList<>(); - for (FederationMember member : members) { - defaultPubKeys.add(member.getBtcPublicKey()); + private void validateEmergencyKeysAreNotNullNorEmpty(List erpPubKeys) { + if (erpPubKeys == null || erpPubKeys.isEmpty()) { + String message = "Emergency keys are not provided"; + throw new ErpRedeemScriptBuilderCreationException(message, NULL_OR_EMPTY_EMERGENCY_KEYS); } - return Collections.unmodifiableList(defaultPubKeys); } public List getErpPubKeys() { return Collections.unmodifiableList(erpPubKeys); } + + public int getNumberOfEmergencySignaturesRequired() { + return erpPubKeys.size() / 2 + 1; + } + public long getActivationDelay() { return activationDelay; } - public Script getStandardRedeemScript() { + public Script getDefaultRedeemScript() { if (standardRedeemScript == null) { standardRedeemScript = RedeemScriptParserFactory.get(getRedeemScript().getChunks()) .extractStandardRedeemScript(); @@ -67,36 +68,26 @@ public Script getStandardRedeemScript() { return standardRedeemScript; } - @Override public Script getRedeemScript() { if (redeemScript == null) { - redeemScript = erpRedeemScriptBuilder.createRedeemScript(getDefaultPublicKeys(), erpPubKeys, activationDelay); + redeemScript = erpRedeemScriptBuilder.createRedeemScriptFromKeys( + getMembersPublicKeys(), + getNumberOfSignaturesRequired(), + erpPubKeys, + getNumberOfEmergencySignaturesRequired(), + activationDelay + ); } return redeemScript; } - public Script getStandardP2SHScript() { + public Script getDefaultP2SHScript() { if (standardP2SHScript == null) { - standardP2SHScript = ScriptBuilder.createP2SHOutputScript(getStandardRedeemScript()); + standardP2SHScript = ScriptBuilder.createP2SHOutputScript(getDefaultRedeemScript()); } return standardP2SHScript; } - private void validateErpFederationValues(List erpPubKeys, long activationDelay) { - if (erpPubKeys == null || erpPubKeys.isEmpty()) { - String message = "Emergency keys are not provided"; - throw new FederationCreationException(message, NULL_OR_EMPTY_EMERGENCY_KEYS); - } - - if (activationDelay <= 0 || activationDelay > MAX_CSV_VALUE) { - String message = String.format( - "Provided csv value %d must be larger than 0 and lower than %d", - activationDelay, - MAX_CSV_VALUE - ); - throw new FederationCreationException(message, INVALID_CSV_VALUE); - } - } } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java index f75ff5d45dc..2e938e60be2 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java @@ -6,9 +6,10 @@ import java.util.List; public interface ErpRedeemScriptBuilder { - long MAX_CSV_VALUE = 65535L; - Script createRedeemScript(List defaultPublicKeys, + Script createRedeemScriptFromKeys(List defaultPublicKeys, + int defaultThreshold, List emergencyPublicKeys, + int emergencyThreshold, long csvValue); -} \ No newline at end of file +} diff --git a/rskj-core/src/main/java/co/rsk/peg/FederationCreationException.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderCreationException.java similarity index 66% rename from rskj-core/src/main/java/co/rsk/peg/FederationCreationException.java rename to rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderCreationException.java index 4c440272063..4788c457138 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FederationCreationException.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderCreationException.java @@ -4,22 +4,21 @@ * Exception to be thrown when attempting to create a Federation with invalid values * that could result in the 2wp to stop working as expected */ -public class FederationCreationException extends RuntimeException { +public class ErpRedeemScriptBuilderCreationException extends RuntimeException { private final Reason reason; public enum Reason { - ABOVE_MAX_SCRIPT_ELEMENT_SIZE, NULL_OR_EMPTY_EMERGENCY_KEYS, INVALID_CSV_VALUE, HARDCODED_LEGACY_ERP_TESTNET_REDEEM_SCRIPT } - public FederationCreationException(String s, Reason reason) { + public ErpRedeemScriptBuilderCreationException(String s, Reason reason) { super(s); this.reason = reason; } - public FederationCreationException(String message, Throwable cause, Reason reason) { + public ErpRedeemScriptBuilderCreationException(String message, Throwable cause, Reason reason) { super(message, cause); this.reason = reason; } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java index 15c71e5f744..ea1b6196176 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java @@ -1,35 +1,44 @@ package co.rsk.peg; -import co.rsk.bitcoinj.core.NetworkParameters; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; +import co.rsk.bitcoinj.core.VerificationException; +import co.rsk.bitcoinj.script.Script; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import static co.rsk.peg.ErpRedeemScriptBuilderCreationException.Reason.INVALID_CSV_VALUE; public class ErpRedeemScriptBuilderUtils { + private static final long MAX_CSV_VALUE = 65535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value + private static final Logger logger = LoggerFactory.getLogger(ErpRedeemScriptBuilderUtils.class); private ErpRedeemScriptBuilderUtils() { } - public static ErpRedeemScriptBuilder defineNonStandardErpRedeemScriptBuilder( - ActivationConfig.ForBlock activations, - NetworkParameters networkParameters) { - - ErpRedeemScriptBuilder erpRedeemScriptBuilder; - - boolean networkParametersIsTestnetOrRegtest = checkIfNetworkParametersAreTestnetOrRegtest(networkParameters); - - if(!activations.isActive(ConsensusRule.RSKIP284) && networkParametersIsTestnetOrRegtest) { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoaded(); - } else if (!activations.isActive(ConsensusRule.RSKIP293)) { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); - } else { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); + public static void validateRedeemScriptValues( + Script defaultFederationRedeemScript, + Script erpFederationRedeemScript, + Long csvValue + ) { + if (!defaultFederationRedeemScript.isSentToMultiSig() || !erpFederationRedeemScript.isSentToMultiSig()) { + + String message = "Provided redeem scripts have an invalid structure, not standard"; + logger.debug( + "[validateRedeemScriptValues] {}. Default script {}. Emergency script {}", + message, + defaultFederationRedeemScript, + erpFederationRedeemScript + ); + throw new VerificationException(message); } - return erpRedeemScriptBuilder; - } - - public static boolean checkIfNetworkParametersAreTestnetOrRegtest(NetworkParameters networkParameters) { - return networkParameters.getId().equals(NetworkParameters.ID_TESTNET) - || networkParameters.getId().equals(NetworkParameters.ID_REGTEST); + if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { + String message = String.format( + "Provided csv value %d must be larger than 0 and lower than %d", + csvValue, + MAX_CSV_VALUE + ); + logger.warn("[validateRedeemScriptValues] {}", message); + throw new ErpRedeemScriptBuilderCreationException(message, INVALID_CSV_VALUE); + } } } diff --git a/rskj-core/src/main/java/co/rsk/peg/Federation.java b/rskj-core/src/main/java/co/rsk/peg/Federation.java index 247554623c1..aec4adb4939 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/Federation.java @@ -64,7 +64,7 @@ public List getMembers() { return members; } - public List getBtcPublicKeys() { + public List getMembersPublicKeys() { // Copy instances since we don't control // immutability of BtcECKey instances return members.stream() diff --git a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java index ea657d14fd5..03f6b7870b8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java @@ -49,7 +49,7 @@ public FederationSupport(BridgeConstants bridgeConstants, BridgeStorageProvider * @return the federation size */ public int getFederationSize() { - return getActiveFederation().getBtcPublicKeys().size(); + return getActiveFederation().getMembersPublicKeys().size(); } /** @@ -58,7 +58,7 @@ public int getFederationSize() { * @return the federator's public key */ public byte[] getFederatorBtcPublicKey(int index) { - List publicKeys = getActiveFederation().getBtcPublicKeys(); + List publicKeys = getActiveFederation().getMembersPublicKeys(); if (index < 0 || index >= publicKeys.size()) { throw new IndexOutOfBoundsException(String.format("Federator index must be between 0 and %d", publicKeys.size() - 1)); diff --git a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java index 06e0c99b13d..cf4a757ac5e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java +++ b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java @@ -64,7 +64,7 @@ public RedeemData findRedeemDataFromScriptHash(byte[] payToScriptHash) { ); } - return RedeemData.of(destinationFederationInstance.getBtcPublicKeys(), flyoverRedeemScript); + return RedeemData.of(destinationFederationInstance.getMembersPublicKeys(), flyoverRedeemScript); } return super.findRedeemDataFromScriptHash(payToScriptHash); diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java index 15533de7851..ea9703bf75d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java @@ -2,7 +2,6 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Utils; -import co.rsk.bitcoinj.core.VerificationException; import co.rsk.bitcoinj.script.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,61 +11,32 @@ public class NonStandardErpRedeemScriptBuilder implements ErpRedeemScriptBuilder { private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilder.class); - public Script createRedeemScript(List defaultPublicKeys, - List emergencyPublicKeys, - long csvValue) { + @Override + public Script createRedeemScriptFromKeys(List defaultPublicKeys, + int defaultThreshold, + List emergencyPublicKeys, + int emergencyThreshold, + long csvValue) { - Script defaultRedeemScript = ScriptBuilder.createRedeemScript( - defaultPublicKeys.size() / 2 + 1, - defaultPublicKeys); - Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( - emergencyPublicKeys.size() / 2 + 1, - emergencyPublicKeys); + Script defaultRedeemScript = ScriptBuilder.createRedeemScript(defaultThreshold, defaultPublicKeys); + Script emergencyRedeemScript = ScriptBuilder.createRedeemScript(emergencyThreshold, emergencyPublicKeys); + + ErpRedeemScriptBuilderUtils.validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue); byte[] serializedCsvValue = Utils.signedLongToByteArrayLE(csvValue); + logger.debug("[createRedeemScriptFromKeys] Creating the redeem script from the scripts"); + Script redeemScript = createRedeemScriptFromScripts(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); - logger.debug("[getRedeemScript] Creating the redeem script from the keys"); - Script redeemScript = createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); + logger.debug("[createRedeemScriptFromKeys] Validating redeem script size"); + ScriptValidations.validateScriptSize(redeemScript); - logger.debug("[getRedeemScript] Validating redeem script values"); - validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue, redeemScript); return redeemScript; } - private static void validateRedeemScriptValues( - Script defaultRedeemScript, - Script emergencyRedeemScript, - Long csvValue, - Script redeemScript - ) { - if (!defaultRedeemScript.isSentToMultiSig() || !emergencyRedeemScript.isSentToMultiSig()) { - String message = "Provided redeem scripts inside the erp one have an invalid structure, not standards"; - logger.debug( - "[validateLegacyErpRedeemScriptValues] {}. Default script {}. Emergency script {}", - message, - defaultRedeemScript, - emergencyRedeemScript - ); - throw new VerificationException(message); - } - - if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { - String message = String.format( - "Provided csv value %d must be between 0 and %d", - csvValue, - MAX_CSV_VALUE - ); - logger.warn("[validateLegacyErpRedeemScriptValues] {}", message); - throw new VerificationException(message); - } - - FederationUtils.validateScriptSize(redeemScript); - } - - public static Script createRedeemScript(Script defaultRedeemScript, - Script emergencyRedeemScript, - byte[] serializedCsvValue) { + private static Script createRedeemScriptFromScripts(Script defaultRedeemScript, + Script emergencyRedeemScript, + byte[] serializedCsvValue) { ScriptBuilder scriptBuilder = new ScriptBuilder(); return scriptBuilder @@ -85,4 +55,4 @@ public static Script createRedeemScript(Script defaultRedeemScript, protected static List removeOpCheckMultisig(Script redeemScript) { return redeemScript.getChunks().subList(0, redeemScript.getChunks().size() - 1); } -} \ No newline at end of file +} diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java new file mode 100644 index 00000000000..6210cdc54b4 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java @@ -0,0 +1,34 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.NetworkParameters; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; + +public class NonStandardErpRedeemScriptBuilderFactory { + + private NonStandardErpRedeemScriptBuilderFactory() { + } + + public static ErpRedeemScriptBuilder defineNonStandardErpRedeemScriptBuilder( + ActivationConfig.ForBlock activations, + NetworkParameters networkParameters) { + + ErpRedeemScriptBuilder erpRedeemScriptBuilder; + + boolean networkParametersIsTestnetOrRegtest = checkIfNetworkIsTestnet(networkParameters); + + if(!activations.isActive(ConsensusRule.RSKIP284) && networkParametersIsTestnetOrRegtest) { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoaded(); + } else if (!activations.isActive(ConsensusRule.RSKIP293)) { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); + } else { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); + } + + return erpRedeemScriptBuilder; + } + + public static boolean checkIfNetworkIsTestnet(NetworkParameters networkParameters) { + return networkParameters.getId().equals(NetworkParameters.ID_TESTNET); + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java index 241140a071b..c7b0ead5901 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java @@ -12,8 +12,11 @@ public class NonStandardErpRedeemScriptBuilderHardcoaded implements ErpRedeemScr private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderHardcoaded.class); private static final byte[] LEGACY_ERP_TESTNET_REDEEM_SCRIPT_BYTES = Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f42102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da210344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a0921039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb955670300cd50b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); - public Script createRedeemScript(List defaultPublicKeys, + @Override + public Script createRedeemScriptFromKeys(List defaultPublicKeys, + int defaultThreshold, List emergencyPublicKeys, + int emergencyThreshold, long csvValue) { logger.debug("[getRedeemScript] Returning hardcoded redeem script"); diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java index c4bf3add875..abe7e9ecb28 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java @@ -2,7 +2,6 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Utils; -import co.rsk.bitcoinj.core.VerificationException; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.script.ScriptChunk; @@ -15,61 +14,32 @@ public class NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE implements ErpRedeemScriptBuilder { private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.class); - public Script createRedeemScript(List defaultPublicKeys, - List emergencyPublicKeys, - long csvValue) { + @Override + public Script createRedeemScriptFromKeys(List defaultPublicKeys, + int defaultThreshold, + List emergencyPublicKeys, + int emergencyThreshold, + long csvValue) { - Script defaultRedeemScript = ScriptBuilder.createRedeemScript( - defaultPublicKeys.size() / 2 + 1, - defaultPublicKeys); - Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( - emergencyPublicKeys.size() / 2 + 1, - emergencyPublicKeys); + Script defaultRedeemScript = ScriptBuilder.createRedeemScript(defaultThreshold, defaultPublicKeys); + Script emergencyRedeemScript = ScriptBuilder.createRedeemScript(emergencyThreshold, emergencyPublicKeys); + ErpRedeemScriptBuilderUtils.validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue); + byte[] serializedCsvValue = Utils.unsignedLongToByteArrayBE(csvValue, 2); - - logger.debug("[getRedeemScript] Creating the redeem script from the keys"); - Script redeemScript = createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); - - logger.debug("[getRedeemScript] Validating redeem script values"); - validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue, redeemScript); + logger.debug("[createRedeemScriptFromKeys] Creating the redeem script from the scripts"); + Script redeemScript = createRedeemScriptFromScripts(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); + + logger.debug("[createRedeemScriptFromKeys] Validating redeem script size"); + ScriptValidations.validateScriptSize(redeemScript); + return redeemScript; } - private static void validateRedeemScriptValues( - Script defaultRedeemScript, - Script emergencyRedeemScript, - Long csvValue, - Script redeemScript - ) { - if (!defaultRedeemScript.isSentToMultiSig() || !emergencyRedeemScript.isSentToMultiSig()) { - String message = "Provided redeem scripts inside the erp one have an invalid structure, not standards"; - logger.debug( - "[validateLegacyErpRedeemScriptValues] {}. Default script {}. Emergency script {}", - message, - defaultRedeemScript, - emergencyRedeemScript - ); - throw new VerificationException(message); - } - - if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { - String message = String.format( - "Provided csv value %d must be between 0 and %d", - csvValue, - MAX_CSV_VALUE - ); - logger.warn("[validateLegacyErpRedeemScriptValues] {}", message); - throw new VerificationException(message); - } - - FederationUtils.validateScriptSize(redeemScript); - } - - public static Script createRedeemScript(Script defaultRedeemScript, - Script emergencyRedeemScript, - byte[] serializedCsvValue) { + private static Script createRedeemScriptFromScripts(Script defaultRedeemScript, + Script emergencyRedeemScript, + byte[] serializedCsvValue) { ScriptBuilder scriptBuilder = new ScriptBuilder(); return scriptBuilder diff --git a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java index 5da63eacd43..c9cc84a1ffd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java @@ -2,7 +2,6 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Utils; -import co.rsk.bitcoinj.core.VerificationException; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.script.ScriptOpCodes; @@ -14,23 +13,28 @@ public class P2shErpRedeemScriptBuilder implements ErpRedeemScriptBuilder{ private static final Logger logger = LoggerFactory.getLogger(P2shErpRedeemScriptBuilder.class); - public Script createRedeemScript(List defaultPublicKeys, - List emergencyPublicKeys, - long csvValue) { - Script defaultRedeemScript = ScriptBuilder.createRedeemScript( - defaultPublicKeys.size() / 2 + 1, - defaultPublicKeys); - Script emergencyRedeemScript = ScriptBuilder.createRedeemScript( - emergencyPublicKeys.size() / 2 + 1, - emergencyPublicKeys); + @Override + public Script createRedeemScriptFromKeys(List defaultPublicKeys, + int defaultThreshold, + List emergencyPublicKeys, + int emergencyThreshold, + long csvValue) { + + Script defaultRedeemScript = ScriptBuilder.createRedeemScript(defaultThreshold, defaultPublicKeys); + Script emergencyRedeemScript = ScriptBuilder.createRedeemScript(emergencyThreshold, emergencyPublicKeys); + + ErpRedeemScriptBuilderUtils.validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue); byte[] serializedCsvValue = Utils.signedLongToByteArrayLE(csvValue); - Script redeemScript = createRedeemScript(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); - validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue, redeemScript); + logger.debug("[createRedeemScriptFromKeys] Creating the redeem script from the scripts"); + Script redeemScript = createRedeemScriptFromScripts(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); + + logger.debug("[createRedeemScriptFromKeys] Validating redeem script size"); + ScriptValidations.validateScriptSize(redeemScript); return redeemScript; } - public static Script createRedeemScript(Script defaultRedeemScript, + private static Script createRedeemScriptFromScripts(Script defaultRedeemScript, Script emergencyRedeemScript, byte[] serializedCsvValue) { @@ -47,36 +51,4 @@ public static Script createRedeemScript(Script defaultRedeemScript, .op(ScriptOpCodes.OP_ENDIF) .build(); } - - - private static void validateRedeemScriptValues( - Script defaultFederationRedeemScript, - Script erpFederationRedeemScript, - Long csvValue, - Script redeemScript - ) { - if (!defaultFederationRedeemScript.isSentToMultiSig() || !erpFederationRedeemScript.isSentToMultiSig()) { - - String message = "Provided redeem scripts have an invalid structure, not standard"; - logger.debug( - "[validateP2shErpRedeemScriptValues] {}. Default script {}. Emergency script {}", - message, - defaultFederationRedeemScript, - erpFederationRedeemScript - ); - throw new VerificationException(message); - } - - if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { - String message = String.format( - "Provided csv value %d must be between 0 and %d", - csvValue, - MAX_CSV_VALUE - ); - logger.warn("[validateP2shErpRedeemScriptValues] {}", message); - throw new VerificationException(message); - } - - FederationUtils.validateScriptSize(redeemScript); - } } diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java index 0f2fb34589b..2bb3550d313 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java @@ -64,7 +64,7 @@ public List getMembers() { return members; } - public List getBtcPublicKeys() { + public List getMembersPublicKeys() { // Copy keys since we don't control immutability of BtcECKey(s) return members.stream() .map(FederationMember::getBtcPublicKey) @@ -122,7 +122,7 @@ public Federation buildFederation( logger.info("[buildFederation] Going to create an ERP Federation"); ErpRedeemScriptBuilder erpRedeemScriptBuilder - = ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + = NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); return new ErpFederation( members, @@ -171,6 +171,6 @@ public Keccak256 getHash() { public int hashCode() { // Can use java.util.Objects.hash since List has a // well-defined hashCode() - return Objects.hash(getBtcPublicKeys()); + return Objects.hash(getMembersPublicKeys()); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/ScriptCreationException.java b/rskj-core/src/main/java/co/rsk/peg/ScriptCreationException.java new file mode 100644 index 00000000000..ba0fc2d8d43 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/ScriptCreationException.java @@ -0,0 +1,21 @@ +package co.rsk.peg; + +public class ScriptCreationException extends RuntimeException { + private final Reason reason; + + public enum Reason { + ABOVE_MAX_SCRIPT_ELEMENT_SIZE + } + + public ScriptCreationException(String s, Reason reason) { + super(s); + this.reason = reason; + } + + public ScriptCreationException(String message, Throwable cause, Reason reason) { + super(message, cause); + this.reason = reason; + } + + public Reason getReason() { return reason; } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/FederationUtils.java b/rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java similarity index 53% rename from rskj-core/src/main/java/co/rsk/peg/FederationUtils.java rename to rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java index bf8b3509555..807e5dd52d0 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FederationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java @@ -1,22 +1,20 @@ package co.rsk.peg; import co.rsk.bitcoinj.script.Script; -import co.rsk.peg.bitcoin.Standardness; -import static co.rsk.peg.FederationCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; -public class FederationUtils { - private FederationUtils() { +public class ScriptValidations { + private ScriptValidations() { } - - public static void validateScriptSize(Script script) throws FederationCreationException { + public static void validateScriptSize(Script script) throws ErpRedeemScriptBuilderCreationException { // Check if the size of the script does not exceed the maximum size allowed int bytesFromScript = script.getProgram().length; - if (bytesFromScript > Standardness.MAX_SCRIPT_ELEMENT_SIZE) { + if (bytesFromScript > Script.MAX_SCRIPT_ELEMENT_SIZE) { String message = String.format("The script size is %d, that is above the maximum allowed.", bytesFromScript ); - throw new FederationCreationException(message, ABOVE_MAX_SCRIPT_ELEMENT_SIZE); + throw new ScriptCreationException(message, ABOVE_MAX_SCRIPT_ELEMENT_SIZE); } } } diff --git a/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java b/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java index 50965e8e9e2..ae9b9981e63 100644 --- a/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java @@ -47,7 +47,7 @@ public StandardMultisigFederation( @Override public Script getRedeemScript() { if (redeemScript == null) { - redeemScript = ScriptBuilder.createRedeemScript(getNumberOfSignaturesRequired(), getBtcPublicKeys()); + redeemScript = ScriptBuilder.createRedeemScript(getNumberOfSignaturesRequired(), getMembersPublicKeys()); } return redeemScript; @@ -55,6 +55,6 @@ public Script getRedeemScript() { private void validateRedeemScriptSize() { Script redeemScript = this.getRedeemScript(); - FederationUtils.validateScriptSize(redeemScript); + ScriptValidations.validateScriptSize(redeemScript); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index 9f8c328f975..b47d13969f2 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -103,9 +103,9 @@ public void logReleaseBtc(BtcTransaction btcTx, byte[] rskTxHash) { @Override public void logCommitFederation(Block executionBlock, Federation oldFederation, Federation newFederation) { // Convert old federation public keys in bytes array - byte[] oldFederationFlatPubKeys = flatKeysAsByteArray(oldFederation.getBtcPublicKeys()); + byte[] oldFederationFlatPubKeys = flatKeysAsByteArray(oldFederation.getMembersPublicKeys()); String oldFederationBtcAddress = oldFederation.getAddress().toBase58(); - byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getBtcPublicKeys()); + byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getMembersPublicKeys()); String newFederationBtcAddress = newFederation.getAddress().toBase58(); long newFedActivationBlockNumber = executionBlock.getNumber() + this.bridgeConstants.getFederationActivationAge(activations); diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java index 81d521ea1cb..13f338878a3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java @@ -113,10 +113,10 @@ public void logCommitFederation(Block executionBlock, Federation oldFederation, } List topics = Collections.singletonList(Bridge.COMMIT_FEDERATION_TOPIC); - byte[] oldFedFlatPubKeys = flatKeysAsRlpCollection(oldFederation.getBtcPublicKeys()); + byte[] oldFedFlatPubKeys = flatKeysAsRlpCollection(oldFederation.getMembersPublicKeys()); byte[] oldFedData = RLP.encodeList(RLP.encodeElement(oldFederation.getAddress().getHash160()), RLP.encodeList(oldFedFlatPubKeys)); - byte[] newFedFlatPubKeys = flatKeysAsRlpCollection(newFederation.getBtcPublicKeys()); + byte[] newFedFlatPubKeys = flatKeysAsRlpCollection(newFederation.getMembersPublicKeys()); byte[] newFedData = RLP.encodeList(RLP.encodeElement(newFederation.getAddress().getHash160()), RLP.encodeList(newFedFlatPubKeys)); long newFedActivationBlockNumber = executionBlock.getNumber() + this.bridgeConstants.getFederationActivationAge(activations); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index b4daeb535e7..7ac3c60b9bf 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -172,7 +172,7 @@ void serializeFederationOnlyBtcKeys() throws Exception { expectedBuilder.append("2a"); // Creation block number expectedBuilder.append("f8cc"); // Inner list - federation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { + federation.getMembersPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { expectedBuilder.append("a1"); expectedBuilder.append(ByteUtil.toHexString(key.getPubKey())); }); @@ -206,11 +206,11 @@ void deserializeFederationOnlyBtcKeys_ok() throws Exception { Assertions.assertEquals(5000, deserializedFederation.getCreationTime().toEpochMilli()); Assertions.assertEquals(4, deserializedFederation.getNumberOfSignaturesRequired()); - Assertions.assertEquals(6, deserializedFederation.getBtcPublicKeys().size()); + Assertions.assertEquals(6, deserializedFederation.getMembersPublicKeys().size()); MatcherAssert.assertThat(deserializedFederation.getCreationBlockNumber(), is(42L)); for (int i = 0; i < 6; i++) { - Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedFederation.getBtcPublicKeys().get(i).getPubKey())); + Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedFederation.getMembersPublicKeys().get(i).getPubKey())); } Assertions.assertEquals(NetworkParameters.fromID(NetworkParameters.ID_REGTEST), deserializedFederation.getBtcParams()); @@ -438,7 +438,7 @@ void serializePendingFederationOnlyBtcKeys() throws Exception { byte[] result = BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(pendingFederation); StringBuilder expectedBuilder = new StringBuilder(); expectedBuilder.append("f8cc"); - pendingFederation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { + pendingFederation.getMembersPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { expectedBuilder.append("a1"); expectedBuilder.append(ByteUtil.toHexString(key.getPubKey())); }); @@ -465,9 +465,9 @@ void deserializePendingFederationOnlyBtcKeys() throws Exception { PendingFederation deserializedPendingFederation = BridgeSerializationUtils.deserializePendingFederationOnlyBtcKeys(data); - Assertions.assertEquals(6, deserializedPendingFederation.getBtcPublicKeys().size()); + Assertions.assertEquals(6, deserializedPendingFederation.getMembersPublicKeys().size()); for (int i = 0; i < 6; i++) { - Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedPendingFederation.getBtcPublicKeys().get(i).getPubKey())); + Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedPendingFederation.getMembersPublicKeys().get(i).getPubKey())); } } @@ -1240,7 +1240,7 @@ private void testSerializeAndDeserializeFederation( when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(isRskip353Active); ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); for (int i = 0; i < NUM_CASES; i++) { int numMembers = randomInRange(2, 14); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index d11881ac2cd..7800614f9df 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -9,7 +9,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.config.BridgeConstants; import java.io.IOException; import java.time.Instant; @@ -617,7 +616,7 @@ private Federation createFederation(int version) { ); case LEGACY_ERP_FEDERATION_FORMAT_VERSION: ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstantsRegtest.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstantsRegtest.getBtcParams()); return new ErpFederation( members, Instant.now(), diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index a52df640e9a..012a9bd990c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -87,7 +87,7 @@ class BridgeStorageProviderTest { private final TestSystemProperties config = new TestSystemProperties(); private final ActivationConfig.ForBlock activationsBeforeFork = ActivationConfigsForTest.genesis().forBlock(0L); private final ActivationConfig.ForBlock activationsAllForks = ActivationConfigsForTest.all().forBlock(0); - private final NetworkParameters networkParameters = config.getNetworkConstants().getBridgeConstants().getBtcParams(); + private final NetworkParameters networkParameters = BridgeTestNetConstants.getInstance().getBtcParams(); private int transactionOffset; @@ -97,7 +97,7 @@ void createInstance() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -130,7 +130,7 @@ void createSaveAndRecreateInstance() throws IOException { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider0.getReleaseRequestQueue(); @@ -155,7 +155,7 @@ void createSaveAndRecreateInstance() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -196,7 +196,7 @@ void createSaveAndRecreateInstanceWithProcessedHashes() throws IOException { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider0.setHeightBtcTxhashAlreadyProcessed(hash1, 1L); @@ -209,7 +209,7 @@ void createSaveAndRecreateInstanceWithProcessedHashes() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -232,7 +232,7 @@ void createSaveAndRecreateInstanceWithTxsWaitingForSignatures() throws IOExcepti BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider0.getPegoutsWaitingForSignatures().put(hash1, tx1); @@ -247,7 +247,7 @@ void createSaveAndRecreateInstanceWithTxsWaitingForSignatures() throws IOExcepti BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -272,14 +272,14 @@ void createSaveAndRecreateInstanceWithUTXOS() throws IOException { Repository repository = createRepository(); Repository track = repository.startTracking(); - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); // Federation is the genesis federation ATM Federation federation = bridgeConstants.getGenesisFederation(); BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider0.getNewFederationBtcUTXOs().add(new UTXO(hash1, 1, Coin.COIN, 0, false, ScriptBuilder.createOutputScript(federation.getAddress()))); @@ -292,7 +292,7 @@ void createSaveAndRecreateInstanceWithUTXOS() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -311,7 +311,7 @@ void getNewFederation_initialVersion() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -342,7 +342,7 @@ void getNewFederation_initialVersion() { // Make sure we're deserializing what just came from the repo with the correct BTC context assertArrayEquals(new byte[]{(byte) 0xaa}, data); - Assertions.assertEquals(networkParameters, config.getNetworkConstants().getBridgeConstants().getBtcParams()); + Assertions.assertEquals(networkParameters, BridgeTestNetConstants.getInstance().getBtcParams()); return newFederation; }); @@ -361,7 +361,7 @@ void getNewFederation_initialVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -401,7 +401,7 @@ void getNewFederation_multiKeyVersion() { @Test void getNewFederation_erp_fed() { - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation newFederation = buildMockFederation(100, 200, 300); ErpFederation erpFederation = new ErpFederation( newFederation.getMembers(), @@ -425,8 +425,8 @@ void getNewFederation_p2sh_erp_fed() { newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), - config.getNetworkConstants().getBridgeConstants().getErpFedPubKeysList(), - config.getNetworkConstants().getBridgeConstants().getErpFedActivationDelay(), + BridgeTestNetConstants.getInstance().getErpFedPubKeysList(), + BridgeTestNetConstants.getInstance().getErpFedActivationDelay(), mock(ActivationConfig.ForBlock.class), new P2shErpRedeemScriptBuilder() ); @@ -442,7 +442,7 @@ void getNewFederation_multiKeyVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -494,7 +494,7 @@ void saveNewFederation_preMultikey() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -546,7 +546,7 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation newFederation = buildMockFederation(100, 200, 300); ErpFederation erpFederation = new ErpFederation( @@ -569,7 +569,7 @@ void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(true); - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation newFederation = buildMockFederation(100, 200, 300); ErpFederation p2shErpFederation = new ErpFederation( @@ -595,7 +595,7 @@ void getOldFederation_initialVersion() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -625,7 +625,7 @@ void getOldFederation_initialVersion() { NetworkParameters networkParameters = invocation.getArgument(1); // Make sure we're deserializing what just came from the repo with the correct BTC context assertArrayEquals(new byte[]{(byte) 0xaa}, data); - assertEquals(networkParameters, config.getNetworkConstants().getBridgeConstants().getBtcParams()); + assertEquals(networkParameters, BridgeTestNetConstants.getInstance().getBtcParams()); return oldFederation; }); @@ -643,7 +643,7 @@ void getOldFederation_initialVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -684,7 +684,7 @@ void getOldFederation_multiKeyVersion() { @Test void getOldFederation_nonStandardHardcoaded_fed() { - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -707,7 +707,7 @@ void getOldFederation_nonStandardHardcoaded_fed() { @Test void getOldFederation_nonStandardWithUnsignedBE_fed() { - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -731,7 +731,7 @@ void getOldFederation_nonStandardWithUnsignedBE_fed() { @Test void getOldFederation_nonStandard_fed() { - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -756,7 +756,7 @@ void getOldFederation_nonStandard_fed() { @Test void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -782,7 +782,7 @@ void getOldFederation_multiKeyVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -831,7 +831,7 @@ void saveOldFederation_preMultikey() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -881,7 +881,7 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation oldFederation = buildMockFederation(100, 200, 300); ErpFederation erpFederation = new ErpFederation( oldFederation.getMembers(), @@ -902,7 +902,7 @@ void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); Federation oldFederation = buildMockFederation(100, 200, 300); ErpFederation p2shErpFederation = new ErpFederation( oldFederation.getMembers(), @@ -923,7 +923,7 @@ void saveOldFederation_preMultikey_setToNull() { try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { List storageBytesCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); Mockito.doAnswer((InvocationOnMock invocation) -> { storageBytesCalls.add(0); @@ -958,7 +958,7 @@ void saveOldFederation_postMultikey_setToNull() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -1001,7 +1001,7 @@ void getPendingFederation_initialVersion() { List deserializeCalls = new ArrayList<>(); PendingFederation pendingFederation = buildMockPendingFederation(100, 200, 300); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { storageCalls.add(0); @@ -1043,7 +1043,7 @@ void getPendingFederation_initialVersion_nullBytes() { List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { storageCalls.add(0); @@ -1077,7 +1077,7 @@ void getPendingFederation_multiKeyVersion() { List deserializeCalls = new ArrayList<>(); PendingFederation pendingFederation = buildMockPendingFederation(100, 200, 300); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { storageCalls.add(0); @@ -1121,7 +1121,7 @@ void getPendingFederation_multiKeyVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -1156,7 +1156,7 @@ void savePendingFederation_preMultikey() { List storageBytesCalls = new ArrayList<>(); List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(any(PendingFederation.class))).then((InvocationOnMock invocation) -> { @@ -1194,7 +1194,7 @@ void savePendingFederation_preMultikey_setToNull() { try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { List storageBytesCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); Mockito.doAnswer((InvocationOnMock invocation) -> { storageBytesCalls.add(0); @@ -1226,7 +1226,7 @@ void savePendingFederation_postMultikey() { List storageBytesCalls = new ArrayList<>(); List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsAllForks); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsAllForks); try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class, Mockito.CALLS_REAL_METHODS)) { bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializePendingFederation(any(PendingFederation.class))).then((InvocationOnMock invocation) -> { @@ -1272,7 +1272,7 @@ void savePendingFederation_postMultikey_setToNull() { try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class, Mockito.CALLS_REAL_METHODS)) { List storageBytesCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsAllForks); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsAllForks); Mockito.doAnswer((InvocationOnMock invocation) -> { storageBytesCalls.add(0); @@ -1312,7 +1312,7 @@ void getFederationElection_nonNullBytes() { AddressBasedAuthorizer authorizerMock = mock(AddressBasedAuthorizer.class); ABICallElection electionMock = mock(ABICallElection.class); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { calls.add(0); @@ -1345,7 +1345,7 @@ void getFederationElection_nullBytes() { List calls = new ArrayList<>(); AddressBasedAuthorizer authorizerMock = mock(AddressBasedAuthorizer.class); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { calls.add(0); @@ -1376,7 +1376,7 @@ void saveFederationElection() { List storageBytesCalls = new ArrayList<>(); List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializeElection(any(ABICallElection.class))).then((InvocationOnMock invocation) -> { @@ -1422,7 +1422,7 @@ void getLockWhitelist_nonNullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -1453,7 +1453,7 @@ void getLockWhitelist_nonNullBytes() { calls.add(0); byte[] data = invocation.getArgument(0); NetworkParameters parameters = invocation.getArgument(1); - assertEquals(NetworkParameters.fromID(NetworkParameters.ID_REGTEST), parameters); + assertEquals(NetworkParameters.fromID(NetworkParameters.ID_TESTNET), parameters); // Make sure we're deserializing what just came from the repo with the correct AddressBasedAuthorizer assertTrue(Arrays.equals(new byte[]{(byte) 0xaa}, data)); HashMap map = new HashMap<>(); @@ -1466,7 +1466,7 @@ void getLockWhitelist_nonNullBytes() { calls.add(0); byte[] unlimitedData = invocation.getArgument(0); NetworkParameters parameters = invocation.getArgument(1); - assertEquals(NetworkParameters.fromID(NetworkParameters.ID_REGTEST), parameters); + assertEquals(NetworkParameters.fromID(NetworkParameters.ID_TESTNET), parameters); // Make sure we're deserializing what just came from the repo with the correct AddressBasedAuthorizer assertTrue(Arrays.equals(new byte[]{(byte) 0xbb}, unlimitedData)); HashMap map = new HashMap<>(); @@ -1483,7 +1483,7 @@ void getLockWhitelist_nonNullBytes() { void getLockWhitelist_nullBytes() { List calls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsAllForks); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))) @@ -1525,7 +1525,7 @@ void saveLockWhitelist() { List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); // Overriding activation to make sure it serializes the unlimited whitelist data - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsAllForks); try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { @@ -1595,7 +1595,7 @@ void saveLockWhiteListAfterGetWithData() { storageCalled.set(Boolean.FALSE); Repository repositoryMock = mock(Repository.class); OneOffWhiteListEntry oneOffEntry = new OneOffWhiteListEntry(getBtcAddress("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), Coin.COIN); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), config.getActivationConfig().forBlock(500L)); when(repositoryMock.getStorageBytes(any(RskAddress.class), eq(LOCK_ONE_OFF_WHITELIST_KEY.getKey()))) @@ -1632,7 +1632,7 @@ void saveLockWhiteListAfterGetWithData() { @Test void getReleaseRequestQueue_before_rskip_146_activation() throws IOException { Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); List oldEntriesList = new ArrayList<>(Collections.singletonList( new ReleaseRequestQueue.Entry( @@ -1671,7 +1671,7 @@ void getReleaseRequestQueue_after_rskip_146_activation() throws IOException { when(repositoryMock.getStorageBytes(any(),eq(RELEASE_REQUEST_QUEUE.getKey()))). thenReturn(BridgeSerializationUtils.serializeReleaseRequestQueue(new ReleaseRequestQueue(new ArrayList<>(Arrays.asList(oldEntry))))); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activations); ReleaseRequestQueue releaseRequestQueue = storageProvider.getReleaseRequestQueue(); @@ -1690,7 +1690,7 @@ void getReleaseRequestQueue_after_rskip_146_activation() throws IOException { @Test void saveReleaseRequestQueue_before_rskip_146_activation() throws IOException { Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); List oldEntriesList = new ArrayList<>(Collections.singletonList( new ReleaseRequestQueue.Entry( @@ -1735,7 +1735,7 @@ void saveReleaseRequestQueue_after_rskip_146_activation() throws IOException { when(repositoryMock.getStorageBytes(any(),eq(RELEASE_REQUEST_QUEUE.getKey()))). thenReturn(BridgeSerializationUtils.serializeReleaseRequestQueue(new ReleaseRequestQueue(new ArrayList<>(Arrays.asList(oldEntry))))); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activations); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activations); ReleaseRequestQueue releaseRequestQueue = storageProvider.getReleaseRequestQueue(); releaseRequestQueue.add(Address.fromBase58(BridgeRegTestConstants.getInstance().getBtcParams(), "mseEsMLuzaEdGbyAv9c9VRL9qGcb49qnxB"), @@ -1766,10 +1766,10 @@ void saveReleaseRequestQueue_after_rskip_146_activation() throws IOException { void getPegoutsWaitingForConfirmations_before_rskip_146_activation() throws IOException { Repository repositoryMock = mock(Repository.class); BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeTestNetConstants.getInstance(), activationsBeforeFork); Set oldEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams()), 1L) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L) )); when(repositoryMock.getStorageBytes(any(RskAddress.class), eq(PEGOUTS_WAITING_FOR_CONFIRMATIONS.getKey()))) @@ -1790,11 +1790,11 @@ void getPegoutsWaitingForConfirmations_after_rskip_146_activation() throws IOExc when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); Set oldEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams()), 1L) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L) )); Set newEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams()), + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L, PegTestUtils.createHash3(0) ))); @@ -1805,11 +1805,11 @@ void getPegoutsWaitingForConfirmations_after_rskip_146_activation() throws IOExc .thenReturn(BridgeSerializationUtils.serializePegoutsWaitingForConfirmations(new PegoutsWaitingForConfirmations(oldEntriesSet))); BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), activations); + BridgeTestNetConstants.getInstance(), activations); PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations = storageProvider.getPegoutsWaitingForConfirmations(); - pegoutsWaitingForConfirmations.add(new SimpleBtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams(), PegTestUtils.createHash(0)), + pegoutsWaitingForConfirmations.add(new SimpleBtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams(), PegTestUtils.createHash(0)), 1L, PegTestUtils.createHash3(0)); @@ -1821,14 +1821,14 @@ void getPegoutsWaitingForConfirmations_after_rskip_146_activation() throws IOExc @Test void savePegoutsWaitingForConfirmations_before_rskip_146_activations() throws IOException { Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); Set oldEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams()), 1L) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L) )); PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations = storageProvider.getPegoutsWaitingForConfirmations(); - pegoutsWaitingForConfirmations.add(new BtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams()), 1L); + pegoutsWaitingForConfirmations.add(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L); doAnswer((i) -> { Set entries = BridgeSerializationUtils.deserializePegoutsWaitingForConfirmations(i.getArgument(2), networkParameters).getEntries(); @@ -1848,11 +1848,11 @@ void savePegoutsWaitingForConfirmations_after_rskip_146_activations() throws IOE when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); Set newEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams()), 1L, PegTestUtils.createHash3(0)) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L, PegTestUtils.createHash3(0)) )); Set oldEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams()), 1L) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L) )); Repository repositoryMock = mock(Repository.class); @@ -1860,10 +1860,10 @@ void savePegoutsWaitingForConfirmations_after_rskip_146_activations() throws IOE when(repositoryMock.getStorageBytes(any(),eq(PEGOUTS_WAITING_FOR_CONFIRMATIONS.getKey()))). thenReturn(BridgeSerializationUtils.serializePegoutsWaitingForConfirmations(new PegoutsWaitingForConfirmations(oldEntriesSet))); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), config.getNetworkConstants().getBridgeConstants(), activations); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activations); PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations = storageProvider.getPegoutsWaitingForConfirmations(); - pegoutsWaitingForConfirmations.add(new SimpleBtcTransaction(config.getNetworkConstants().getBridgeConstants().getBtcParams(), PegTestUtils.createHash(1)), + pegoutsWaitingForConfirmations.add(new SimpleBtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams(), PegTestUtils.createHash(1)), 1L, PegTestUtils.createHash3(0)); @@ -1901,7 +1901,7 @@ void getReleaseTransaction_after_rskip_146_activations() throws IOException { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -1917,7 +1917,7 @@ void getReleaseTransaction_after_rskip_146_activations() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -1933,7 +1933,7 @@ void setFeePerKb_savedAndRecreated() { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -1947,7 +1947,7 @@ void setFeePerKb_savedAndRecreated() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -1961,7 +1961,7 @@ void getFeePerKbElection_emptyVotes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -1987,7 +1987,7 @@ void getFeePerKbElection_withVotes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2016,7 +2016,7 @@ void setLockingCap_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider0.setLockingCap(Coin.ZERO); @@ -2033,7 +2033,7 @@ void setLockingCap_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2055,7 +2055,7 @@ void getLockingCap_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2074,7 +2074,7 @@ void getLockingCap_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2092,7 +2092,7 @@ void setLockingCapAndGetLockingCap() { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2108,7 +2108,7 @@ void setLockingCapAndGetLockingCap() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2132,7 +2132,7 @@ void getHeightIfBtcTxhashIsAlreadyProcessed_before_RSKIP134_does_not_use_new_sto BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2167,7 +2167,7 @@ void getHeightIfBtcTxhashIsAlreadyProcessed_after_RSKIP134_uses_new_storage() BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2208,7 +2208,7 @@ void setHeightBtcTxhashAlreadyProcessed_before_RSKIP134_does_not_use_new_storage BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2231,7 +2231,7 @@ void setHeightBtcTxhashAlreadyProcessed_before_RSKIP134_uses_new_storage() throw BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2254,7 +2254,7 @@ void saveHeightBtcTxHashAlreadyProcessed() throws IOException { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2279,7 +2279,7 @@ void getCoinBaseInformation_before_RSKIP143() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2302,7 +2302,7 @@ void getCoinBaseInformation_after_RSKIP143() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2319,7 +2319,7 @@ void setCoinBaseInformation_before_RSKIP143() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2340,7 +2340,7 @@ void setCoinBaseInformation_after_RSKIP143() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2361,7 +2361,7 @@ void saveCoinBaseInformation_before_RSKIP143() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2390,7 +2390,7 @@ void saveCoinBaseInformation_after_RSKIP143() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2418,7 +2418,7 @@ void getBtcBestBlockHashByHeight_beforeRskip199() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2435,7 +2435,7 @@ void getBtcBestBlockHashByHeight_afterRskip199_hashNotFound() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2456,7 +2456,7 @@ void getBtcBestBlockHashByHeight_afterRskip199() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2479,7 +2479,7 @@ void saveBtcBlocksIndex_beforeRskip199() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2506,7 +2506,7 @@ void saveBtcBlocksIndex_afterRskip199() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2527,7 +2527,7 @@ void getActiveFederationCreationBlockHeight_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -2545,7 +2545,7 @@ void getActiveFederationCreationBlockHeight_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); assertEquals(Optional.of(1L), provider0.getActiveFederationCreationBlockHeight()); @@ -2561,7 +2561,7 @@ void setActiveFederationCreationBlockHeightAndGetActiveFederationCreationBlockHe BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); // We store the value @@ -2573,7 +2573,7 @@ void setActiveFederationCreationBlockHeightAndGetActiveFederationCreationBlockHe BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); // And then we get it back @@ -2587,7 +2587,7 @@ void saveActiveFederationCreationBlockHeight_after_RSKIP186() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2608,7 +2608,7 @@ void saveActiveFederationCreationBlockHeight_before_RSKIP186() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider0.setActiveFederationCreationBlockHeight(10L); @@ -2628,7 +2628,7 @@ void getNextFederationCreationBlockHeight_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); assertEquals(Optional.empty(), provider0.getNextFederationCreationBlockHeight()); @@ -2645,7 +2645,7 @@ void getNextFederationCreationBlockHeight_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); assertEquals(Optional.of(1L), provider0.getNextFederationCreationBlockHeight()); @@ -2661,7 +2661,7 @@ void setNextFederationCreationBlockHeightAndGetNextFederationCreationBlockHeight BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); // We store the value @@ -2673,7 +2673,7 @@ void setNextFederationCreationBlockHeightAndGetNextFederationCreationBlockHeight BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); // And then we get it back @@ -2686,7 +2686,7 @@ void saveNextFederationCreationBlockHeight_after_RSKIP186() { BridgeStorageProvider provider1 = new BridgeStorageProvider( repository1, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); provider1.setNextFederationCreationBlockHeight(10L); @@ -2703,7 +2703,7 @@ void saveNextFederationCreationBlockHeight_after_RSKIP186() { BridgeStorageProvider provider2 = new BridgeStorageProvider( repository2, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); provider2.clearNextFederationCreationBlockHeight(); @@ -2735,7 +2735,7 @@ void isFlyoverFederationDerivationHashUsed_afterRSKIP176_returnTrue() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -2756,7 +2756,7 @@ void isFlyoverFederationDerivationHashUsed_beforeRSKIP176_returnFalse() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -2782,7 +2782,7 @@ void isFlyoverFederationDerivationHashUsed_storageReturnsNull_returnFalse() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -2808,7 +2808,7 @@ void isFlyoverFederationDerivationHashUsed_storageReturnsEmpty_returnFalse() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -2834,7 +2834,7 @@ void isFlyoverFederationDerivationHashUsed_storageReturnsWrongValue_returnFalse( BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -2848,7 +2848,7 @@ void saveNextFederationCreationBlockHeight_before_RSKIP186() { BridgeStorageProvider provider1 = new BridgeStorageProvider( repository1, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider1.setNextFederationCreationBlockHeight(10L); @@ -2865,7 +2865,7 @@ void saveNextFederationCreationBlockHeight_before_RSKIP186() { BridgeStorageProvider provider2 = new BridgeStorageProvider( repository2, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider2.clearNextFederationCreationBlockHeight(); @@ -2885,7 +2885,7 @@ void getLastRetiredFederationP2SHScript_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); assertEquals(Optional.empty(), provider0.getLastRetiredFederationP2SHScript()); @@ -2904,7 +2904,7 @@ void getLastRetiredFederationP2SHScript_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); assertEquals(Optional.of(script), provider0.getLastRetiredFederationP2SHScript()); @@ -2921,7 +2921,7 @@ void setLastRetiredFederationP2SHScriptAndGetLastRetiredFederationP2SHScript() { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); // We store the value @@ -2933,7 +2933,7 @@ void setLastRetiredFederationP2SHScriptAndGetLastRetiredFederationP2SHScript() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); // And then we get it back @@ -2947,7 +2947,7 @@ void saveLastRetiredFederationP2SHScript_after_RSKIP186() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsAllForks ); @@ -2971,7 +2971,7 @@ void saveLastRetiredFederationP2SHScript_before_RSKIP186() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); @@ -3001,7 +3001,7 @@ void saveDerivationArgumentsScriptHash_afterRSKIP176_ok() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3028,7 +3028,7 @@ void saveDerivationArgumentsScriptHash_afterRSKIP176_nullBtcTxHash_notSaved() th BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3052,7 +3052,7 @@ void saveDerivationArgumentsScriptHash_afterRSKIP176_nullDerivationHash_notSaved BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3076,7 +3076,7 @@ void saveDerivationArgumentsScriptHash_beforeRSKIP176_ok() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3115,7 +3115,7 @@ void getFlyoverFederationInformation_afterRSKIP176_ok() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3151,7 +3151,7 @@ void getFlyoverFederationInformation_beforeRSKIP176_ok() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3176,7 +3176,7 @@ void getFlyoverFederationInformation_notFound() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3194,7 +3194,7 @@ void getFlyoverFederationInformation_nullParameter_returnEmpty() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3212,7 +3212,7 @@ void getFlyoverFederationInformation_arrayEmpty_returnEmpty() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3239,7 +3239,7 @@ void saveFlyoverFederationInformation_afterRSKIP176_ok() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3272,7 +3272,7 @@ void saveFlyoverFederationInformation_beforeRSKIP176_ok() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3305,7 +3305,7 @@ void saveFlyoverFederationInformation_alreadySet_dont_set_again() throws IOExcep BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3328,7 +3328,7 @@ void getReceiveHeadersLastTimestamp_before_RSKIP200() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); assertFalse(provider.getReceiveHeadersLastTimestamp().isPresent()); @@ -3345,7 +3345,7 @@ void getReceiveHeadersLastTimestamp_after_RSKIP200() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); Optional result = provider.getReceiveHeadersLastTimestamp(); @@ -3360,7 +3360,7 @@ void getReceiveHeadersLastTimestamp_not_in_repository() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); assertFalse(provider.getReceiveHeadersLastTimestamp().isPresent()); @@ -3372,7 +3372,7 @@ void saveReceiveHeadersLastTimestamp_before_RSKIP200() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider.setReceiveHeadersLastTimestamp(System.currentTimeMillis()); @@ -3391,7 +3391,7 @@ void saveReceiveHeadersLastTimestamp_after_RSKIP200() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); Long timeInMillis = System.currentTimeMillis(); @@ -3411,7 +3411,7 @@ void saveReceiveHeadersLastTimestamp_not_set() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); provider.save(); @@ -3428,7 +3428,7 @@ void getNextPegoutHeight_before_RSKIP271_activation() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); assertEquals(Optional.empty(), provider.getNextPegoutHeight()); @@ -3444,7 +3444,7 @@ void getNextPegoutHeight_after_RSKIP271_activation() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); assertEquals(Optional.of(1L), provider.getNextPegoutHeight()); @@ -3459,7 +3459,7 @@ void setNextPegoutHeightAndGetNextPegoutHeight_after_RSKIP271_activation() { BridgeStorageProvider provider1 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); provider1.setNextPegoutHeight(1L); @@ -3470,7 +3470,7 @@ void setNextPegoutHeightAndGetNextPegoutHeight_after_RSKIP271_activation() { BridgeStorageProvider provider2 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); MatcherAssert.assertThat(provider2.getNextPegoutHeight(), is(Optional.of(1L))); @@ -3482,7 +3482,7 @@ void saveNextPegoutHeight_before_RSKIP271() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsBeforeFork + BridgeTestNetConstants.getInstance(), activationsBeforeFork ); provider.setNextPegoutHeight(10L); @@ -3501,7 +3501,7 @@ void saveNextPegoutHeight_after_RSKIP271() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); provider.setNextPegoutHeight(10L); @@ -3602,7 +3602,7 @@ void getReleaseRequestQueueSize_when_releaseRequestQueue_is_null() throws IOExce BridgeStorageProvider storageProvider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); Assertions.assertEquals(0, storageProvider.getReleaseRequestQueueSize()); @@ -3614,7 +3614,7 @@ void getReleaseRequestQueueSize_when_releaseRequestQueue_is_not_null() throws IO BridgeStorageProvider storageProvider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - config.getNetworkConstants().getBridgeConstants(), activationsAllForks + BridgeTestNetConstants.getInstance(), activationsAllForks ); ReleaseRequestQueue releaseRequestQueue = storageProvider.getReleaseRequestQueue(); @@ -3631,7 +3631,7 @@ void getReleaseRequestQueueSize_when_releaseRequestQueue_is_not_null() throws IO } private void testGetOldFederation(Federation oldFederation, ActivationConfig.ForBlock activations) { - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); BridgeStorageProvider storageProvider = new BridgeStorageProvider( @@ -3672,7 +3672,7 @@ private void testSaveOldFederation(Federation oldFederation, int version, Activa BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3721,7 +3721,7 @@ private void testSaveOldFederation(Federation oldFederation, int version, Activa private void testGetNewFederationPostMultiKey(Federation federation) { List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeConstants bridgeConstants = config.getNetworkConstants().getBridgeConstants(); + BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), @@ -3763,7 +3763,7 @@ private void testSaveNewFederationPostMultiKey(Federation newFederation, int ver BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - config.getNetworkConstants().getBridgeConstants(), + BridgeTestNetConstants.getInstance(), activations ); @@ -3944,7 +3944,7 @@ private RskAddress mockAddress(String addr) { } private Address getBtcAddress(String addr) { - return new Address(config.getNetworkConstants().getBridgeConstants().getBtcParams(), Hex.decode(addr)); + return new Address(BridgeTestNetConstants.getInstance().getBtcParams(), Hex.decode(addr)); } private Federation buildMockFederation(Integer... pks) { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index 5f4744eef9e..9fdb4e3d2a3 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -255,7 +255,7 @@ void addSignatureToMissingTransaction() throws Exception { .withRepository(repository) .build(); - bridgeSupport.addSignature(federation.getBtcPublicKeys().get(0), null, createHash().getBytes()); + bridgeSupport.addSignature(federation.getMembersPublicKeys().get(0), null, createHash().getBytes()); bridgeSupport.save(); BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, @@ -503,7 +503,7 @@ void addSignatureMultipleInputsPartiallyValid() throws Exception { } // Sign with two valid signatures and one invalid signature - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); bridgeSupport.save(); // Sign with two valid signatures and one malformed signature @@ -512,16 +512,16 @@ void addSignatureMultipleInputsPartiallyValid() throws Exception { malformedSignature[i] = (byte) i; } derEncodedSigsFirstFed.set(2, malformedSignature); - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); bridgeSupport.save(); // Sign with fully valid signatures for same federator derEncodedSigsFirstFed.set(2, lastSig.encodeToDER()); - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); bridgeSupport.save(); // Sign with second federation - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeyOfSecondFed), derEncodedSigsSecondFed, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeyOfSecondFed), derEncodedSigsSecondFed, keccak256.getBytes()); bridgeSupport.save(); provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstantsRegtest, activationsBeforeForks); @@ -608,7 +608,7 @@ private void addSignatureFromValidFederator(List privateKeysToSignWith for (int i = 0; i < numberOfInputsToSign; i++) { derEncodedSigs.add(derEncodedSig); } - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(0)), derEncodedSigs, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeysToSignWith.get(0)), derEncodedSigs, keccak256.getBytes()); if (signTwice) { // Create another valid signature with the same private key ECDSASigner signer = new ECDSASigner(); @@ -620,7 +620,7 @@ private void addSignatureFromValidFederator(List privateKeysToSignWith BtcECKey.ECDSASignature sig2 = new BtcECKey.ECDSASignature(components[0], components[1]).toCanonicalised(); List list = new ArrayList<>(); list.add(sig2.encodeToDER()); - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(0)), list, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeysToSignWith.get(0)), list, keccak256.getBytes()); } if (privateKeysToSignWith.size() > 1) { BtcECKey.ECDSASignature sig2 = privateKeysToSignWith.get(1).sign(sighash); @@ -629,7 +629,7 @@ private void addSignatureFromValidFederator(List privateKeysToSignWith for (int i = 0; i < numberOfInputsToSign; i++) { derEncodedSigs2.add(derEncodedSig2); } - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(1)), derEncodedSigs2, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeysToSignWith.get(1)), derEncodedSigs2, keccak256.getBytes()); } bridgeSupport.save(); track.commit(); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java index 386560080f5..54c54dd914c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java @@ -1301,17 +1301,17 @@ void registerBtcTransactionReleaseTx() throws BlockStoreException, AddressFormat // Create tx input base script sig Script scriptSig = PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation); // Create sighash - Script redeemScript = ScriptBuilder.createRedeemScript(federation.getNumberOfSignaturesRequired(), federation.getBtcPublicKeys()); + Script redeemScript = ScriptBuilder.createRedeemScript(federation.getNumberOfSignaturesRequired(), federation.getMembersPublicKeys()); Sha256Hash sighash = tx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false); // Sign by federator 0 BtcECKey.ECDSASignature sig0 = BridgeRegTestConstants.REGTEST_FEDERATION_PRIVATE_KEYS.get(0).sign(sighash); TransactionSignature txSig0 = new TransactionSignature(sig0, BtcTransaction.SigHash.ALL, false); - int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, federation.getBtcPublicKeys().get(0)); + int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, federation.getMembersPublicKeys().get(0)); scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig0.encodeToBitcoin(), sigIndex0, 1, 1); // Sign by federator 1 BtcECKey.ECDSASignature sig1 = BridgeRegTestConstants.REGTEST_FEDERATION_PRIVATE_KEYS.get(1).sign(sighash); TransactionSignature txSig1 = new TransactionSignature(sig1, BtcTransaction.SigHash.ALL, false); - int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, federation.getBtcPublicKeys().get(1)); + int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, federation.getMembersPublicKeys().get(1)); scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig1.encodeToBitcoin(), sigIndex1, 1, 1); // Set scipt sign to tx input tx.getInput(0).setScriptSig(scriptSig); @@ -1417,17 +1417,17 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm // Create tx input base script sig Script scriptSig = PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(retiringFederation); // Create sighash - Script redeemScript = ScriptBuilder.createRedeemScript(retiringFederation.getNumberOfSignaturesRequired(), retiringFederation.getBtcPublicKeys()); + Script redeemScript = ScriptBuilder.createRedeemScript(retiringFederation.getNumberOfSignaturesRequired(), retiringFederation.getMembersPublicKeys()); Sha256Hash sighash = tx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false); // Sign by federator 0 BtcECKey.ECDSASignature sig0 = retiringFederationKeys.get(0).sign(sighash); TransactionSignature txSig0 = new TransactionSignature(sig0, BtcTransaction.SigHash.ALL, false); - int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getBtcPublicKeys().get(0)); + int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getMembersPublicKeys().get(0)); scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig0.encodeToBitcoin(), sigIndex0, 1, 1); // Sign by federator 1 BtcECKey.ECDSASignature sig1 = retiringFederationKeys.get(1).sign(sighash); TransactionSignature txSig1 = new TransactionSignature(sig1, BtcTransaction.SigHash.ALL, false); - int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getBtcPublicKeys().get(1)); + int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getMembersPublicKeys().get(1)); scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig1.encodeToBitcoin(), sigIndex1, 1, 1); // Set scipt sign to tx input tx.getInput(0).setScriptSig(scriptSig); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index 477eb393199..76bf6f798a8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -1617,7 +1617,7 @@ private void signWithNKeys( int numberOfSignatures) { Script scriptPubKey = federation.getP2SHScript(); - RedeemData redeemData = RedeemData.of(federation.getBtcPublicKeys(), federationRedeemScript); + RedeemData redeemData = RedeemData.of(federation.getMembersPublicKeys(), federationRedeemScript); Script inputScript = scriptPubKey.createEmptyInputScript(redeemData.keys.get(0), redeemData.redeemScript); txIn.setScriptSig(inputScript); @@ -1643,7 +1643,7 @@ private Script signWithOneKey( int federatorIndex) { BtcECKey federatorPrivKey = privateKeys.get(federatorIndex); - BtcECKey federatorPublicKey = federation.getBtcPublicKeys().get(federatorIndex); + BtcECKey federatorPublicKey = federation.getMembersPublicKeys().get(federatorIndex); BtcECKey.ECDSASignature sig = federatorPrivKey.sign(sighash); TransactionSignature txSig = new TransactionSignature(sig, BtcTransaction.SigHash.ALL, false); diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index 33f17584ea8..a2b0b887397 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -1,7 +1,7 @@ package co.rsk.peg; -import static co.rsk.peg.ErpFederation.MAX_CSV_VALUE; -import static co.rsk.peg.FederationCreationException.Reason.*; +import static co.rsk.peg.ErpRedeemScriptBuilderCreationException.Reason.*; +import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static co.rsk.peg.bitcoin.Standardness.MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; @@ -14,7 +14,6 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.core.ScriptException; import co.rsk.bitcoinj.core.Utils; -import co.rsk.bitcoinj.script.ErpFederationRedeemScriptParser; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptOpCodes; import co.rsk.config.BridgeConstants; @@ -47,10 +46,13 @@ import org.junit.jupiter.api.Test; class LegacyErpFederationTest { + public static long MAX_CSV_VALUE = 65535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value private ErpFederation federation; private NetworkParameters networkParameters; private List standardKeys; + int defaultThreshold; private List emergencyKeys; + int emergencyThreshold; private long activationDelayValue; private ActivationConfig.ForBlock activations; private ErpRedeemScriptBuilder erpRedeemScriptBuilder; @@ -75,10 +77,11 @@ void setup() { federator6PublicKey, federator7PublicKey, federator8PublicKey, federator9PublicKey ); - - networkParameters = bridgeConstants.getBtcParams(); + defaultThreshold = standardKeys.size() / 2 + 1; emergencyKeys = bridgeConstants.getErpFedPubKeysList(); + emergencyThreshold = emergencyKeys.size() / 2 + 1; activationDelayValue = bridgeConstants.getErpFedActivationDelay(); + networkParameters = bridgeConstants.getBtcParams(); activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); @@ -91,7 +94,7 @@ private ErpFederation createDefaultLegacyErpFederation() { Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, networkParameters); + NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, networkParameters); return new ErpFederation( standardMembers, @@ -108,8 +111,8 @@ private ErpFederation createDefaultLegacyErpFederation() { @Test void createInvalidLegacyErpFederation_nullErpKeys() { emergencyKeys = null; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultLegacyErpFederation + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, this::createDefaultLegacyErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -117,8 +120,8 @@ void createInvalidLegacyErpFederation_nullErpKeys() { @Test void createInvalidLegacyErpFederation_emptyErpKeys() { emergencyKeys = new ArrayList<>(); - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultLegacyErpFederation + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, this::createDefaultLegacyErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -131,8 +134,10 @@ void createValidLegacyErpFederation_oneErpKey() { @Test void createInvalidLegacyErpFederation_negativeCsvValue() { activationDelayValue = -100L; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultLegacyErpFederation + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, + () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); } @@ -140,8 +145,10 @@ void createInvalidLegacyErpFederation_negativeCsvValue() { @Test void createInvalidLegacyErpFederation_zeroCsvValue() { activationDelayValue = 0L; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultLegacyErpFederation + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, + () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); } @@ -149,8 +156,10 @@ void createInvalidLegacyErpFederation_zeroCsvValue() { @Test void createInvalidLegacyErpFederation_aboveMaxCsvValue() { activationDelayValue = MAX_CSV_VALUE + 1; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultLegacyErpFederation + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, + () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); } @@ -164,7 +173,7 @@ void createValidLegacyErpFederation_exactMaxCsvValue() { @Test void createInvalidNonStandardBuilder_aboveMaxScriptSigSize() { // add one member to exceed redeem script size limit - List newStandardKeys = federation.getBtcPublicKeys(); + List newStandardKeys = federation.getMembersPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( Hex.decode("02550cc87fa9061162b1dd395a16662529c9d8094c0feca17905a3244713d65fe8") ); @@ -172,9 +181,9 @@ void createInvalidNonStandardBuilder_aboveMaxScriptSigSize() { standardKeys = newStandardKeys; ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); - FederationCreationException exception = assertThrows( - FederationCreationException.class, - () -> builder.createRedeemScript(standardKeys, emergencyKeys, activationDelayValue) + ScriptCreationException exception = assertThrows( + ScriptCreationException.class, + () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); } @@ -254,7 +263,7 @@ void testEquals_differentNetworkParameters() { @Test void testEquals_differentNumberOfMembers() { // remove federator9 - List newStandardKeys = federation.getBtcPublicKeys(); + List newStandardKeys = federation.getMembersPublicKeys(); newStandardKeys.remove(newStandardKeys.size() - 1); standardKeys = newStandardKeys; @@ -268,7 +277,7 @@ void testEquals_differentMembers() { BtcECKey federator9PublicKey = BtcECKey.fromPublicOnly( Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea") ); - List newStandardKeys = federation.getBtcPublicKeys(); + List newStandardKeys = federation.getMembersPublicKeys(); newStandardKeys.remove(8); newStandardKeys.add(federator9PublicKey); standardKeys = newStandardKeys; @@ -562,7 +571,7 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { List federationMembersWithBtcKeys = FederationTestUtils.getFederationMembersWithBtcKeys(standardMultisigKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); - assertThrows(FederationCreationException.class, () -> new ErpFederation( + assertThrows(ErpRedeemScriptBuilderCreationException.class, () -> new ErpFederation( federationMembersWithBtcKeys, creationTime, 1, diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index aeae04e8c27..03867476e22 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -1,7 +1,7 @@ package co.rsk.peg; -import static co.rsk.peg.ErpFederation.MAX_CSV_VALUE; -import static co.rsk.peg.FederationCreationException.Reason.*; +import static co.rsk.peg.ErpRedeemScriptBuilderCreationException.Reason.*; +import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static co.rsk.peg.bitcoin.Standardness.MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; @@ -40,10 +40,13 @@ import org.junit.jupiter.params.provider.MethodSource; class P2shErpFederationTest { + public static long MAX_CSV_VALUE = 65535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value private ErpFederation federation; private NetworkParameters networkParameters; private List standardKeys; + int defaultThreshold; private List emergencyKeys; + int emergencyThreshold; private long activationDelayValue; private ActivationConfig.ForBlock activations; @@ -66,12 +69,14 @@ void setup() { federator3PublicKey, federator4PublicKey, federator5PublicKey, federator6PublicKey, federator7PublicKey, federator8PublicKey, federator9PublicKey ); - - networkParameters = bridgeConstants.getBtcParams(); + defaultThreshold = standardKeys.size() / 2 + 1; emergencyKeys = bridgeConstants.getErpFedPubKeysList(); + emergencyThreshold = emergencyKeys.size() / 2 + 1; activationDelayValue = bridgeConstants.getErpFedActivationDelay(); - activations = mock(ActivationConfig.ForBlock.class); + networkParameters = bridgeConstants.getBtcParams(); + + activations = mock(ActivationConfig.ForBlock.class); federation = createDefaultP2shErpFederation(); } @@ -95,8 +100,8 @@ private ErpFederation createDefaultP2shErpFederation() { @Test void createInvalidP2shErpFederation_nullErpKeys() { emergencyKeys = null; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultP2shErpFederation + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, this::createDefaultP2shErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -104,8 +109,8 @@ void createInvalidP2shErpFederation_nullErpKeys() { @Test void createInvalidP2shErpFederation_emptyErpKeys() { emergencyKeys = new ArrayList<>(); - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultP2shErpFederation + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, this::createDefaultP2shErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -119,8 +124,11 @@ void createValidP2shErpFederation_oneErpKey() { @Test void createInvalidP2shErpFederation_negativeCsvValue() { activationDelayValue = -100L; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultP2shErpFederation + + ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, + () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); } @@ -128,8 +136,10 @@ void createInvalidP2shErpFederation_negativeCsvValue() { @Test void createInvalidP2shErpFederation_zeroCsvValue() { activationDelayValue = 0L; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultP2shErpFederation + ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, + () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); } @@ -137,8 +147,10 @@ void createInvalidP2shErpFederation_zeroCsvValue() { @Test void createInvalidP2shErpFederation_aboveMaxCsvValue() { activationDelayValue = MAX_CSV_VALUE + 1; - FederationCreationException exception = assertThrows( - FederationCreationException.class, this::createDefaultP2shErpFederation + ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + ErpRedeemScriptBuilderCreationException exception = assertThrows( + ErpRedeemScriptBuilderCreationException.class, + () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); } @@ -152,7 +164,7 @@ void createValidP2shErpFederation_exactMaxCsvValue() { @Test void createInvalidFederation_aboveMaxScriptSigSize() { // add one member to exceed redeem script size limit - List newStandardKeys = federation.getBtcPublicKeys(); + List newStandardKeys = federation.getMembersPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( Hex.decode("02550cc87fa9061162b1dd395a16662529c9d8094c0feca17905a3244713d65fe8") ); @@ -160,9 +172,9 @@ void createInvalidFederation_aboveMaxScriptSigSize() { standardKeys = newStandardKeys; ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); - FederationCreationException exception = assertThrows( - FederationCreationException.class, - () -> builder.createRedeemScript(standardKeys, emergencyKeys, activationDelayValue) + ScriptCreationException exception = assertThrows( + ScriptCreationException.class, + () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); } @@ -206,7 +218,7 @@ void testEquals_same() { @Test void testEquals_differentNumberOfMembers() { // remove federator9 - List newStandardKeys = federation.getBtcPublicKeys(); + List newStandardKeys = federation.getMembersPublicKeys(); newStandardKeys.remove(9); standardKeys = newStandardKeys; @@ -228,7 +240,7 @@ void testEquals_differentMembers() { Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea") ); // replace federator8 with federator9 - List newStandardKeys = federation.getBtcPublicKeys(); + List newStandardKeys = federation.getMembersPublicKeys(); newStandardKeys.remove(8); newStandardKeys.add(federator9PublicKey); standardKeys = newStandardKeys; @@ -244,7 +256,7 @@ void getRedeemScript(BridgeConstants bridgeConstants) { // should add this case because adding erp to mainnet genesis federation // throws a validation error, so in that case we use the one set up before each test. // if using testnet constants, we can add them with no errors - standardKeys = bridgeConstants.getGenesisFederation().getBtcPublicKeys(); + standardKeys = bridgeConstants.getGenesisFederation().getMembersPublicKeys(); } emergencyKeys = bridgeConstants.getErpFedPubKeysList(); @@ -288,8 +300,8 @@ void getStandardRedeemScript() { new P2shErpRedeemScriptBuilder() ); - assertEquals(legacyFed.getRedeemScript(), p2shFed.getStandardRedeemScript()); - Assertions.assertNotEquals(p2shFed.getRedeemScript(), p2shFed.getStandardRedeemScript()); + assertEquals(legacyFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); + Assertions.assertNotEquals(p2shFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java index 5691a0740cf..e9807dce5c2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java @@ -18,14 +18,7 @@ package co.rsk.peg; -import co.rsk.bitcoinj.core.Address; -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.BtcTransaction; -import co.rsk.bitcoinj.core.Coin; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.core.Sha256Hash; -import co.rsk.bitcoinj.core.TransactionOutput; -import co.rsk.bitcoinj.core.UTXO; +import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.params.RegTestParams; import co.rsk.bitcoinj.script.FastBridgeRedeemScriptParser; import co.rsk.bitcoinj.script.Script; @@ -34,12 +27,6 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.simples.SimpleRskTransaction; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.core.Transaction; @@ -47,6 +34,13 @@ import org.ethereum.crypto.Keccak256Helper; import org.mockito.Mockito; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + /** * Created by oscar on 05/08/2016. */ diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index 24fd63b0fa1..25fea177902 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -300,7 +300,7 @@ private void testBuildFederation( ); } else if (isRskip201Active) { ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); expectedFederation = new ErpFederation( FederationTestUtils.getFederationMembersFromPks(privateKeys), creationTime, diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index a50d95250db..ce15fc262a4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -137,7 +137,7 @@ private void testChangePowpeg( switch (oldPowPegFederationType) { case legacyErp: ErpRedeemScriptBuilder erpRedeemScriptBuilder = - ErpRedeemScriptBuilderUtils.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); originalPowpeg = new ErpFederation( originalPowpegMembers, Instant.now(), @@ -607,14 +607,14 @@ private void testChangePowpeg( if (oldPowPegFederationType == FederationType.legacyErp || oldPowPegFederationType == FederationType.p2shErp){ assertNotEquals(lastRetiredFederationP2SHScript, originalPowpeg.getP2SHScript()); } - assertEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getStandardP2SHScript() : originalPowpeg.getP2SHScript()); + assertEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getDefaultP2SHScript() : originalPowpeg.getP2SHScript()); } else { if (oldPowPegFederationType == FederationType.legacyErp || oldPowPegFederationType == FederationType.p2shErp){ assertEquals(lastRetiredFederationP2SHScript, originalPowpeg.getP2SHScript()); - assertNotEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getStandardP2SHScript() : originalPowpeg.getP2SHScript()); + assertNotEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getDefaultP2SHScript() : originalPowpeg.getP2SHScript()); } else { assertEquals(lastRetiredFederationP2SHScript, originalPowpeg.getP2SHScript()); - assertEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getStandardP2SHScript() : originalPowpeg.getP2SHScript()); + assertEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getDefaultP2SHScript() : originalPowpeg.getP2SHScript()); } } } @@ -646,10 +646,10 @@ private void verifyPegouts(BridgeStorageProvider bridgeStorageProvider) throws I Script inputStandardRedeemScript = RedeemScriptParserFactory.get(result.getChunks()).extractStandardRedeemScript(); Optional spendingFederationOptional = Optional.empty(); - if (inputStandardRedeemScript.equals(activeFederation instanceof ErpFederation ? ((ErpFederation) activeFederation).getStandardRedeemScript() : activeFederation.getRedeemScript())) { + if (inputStandardRedeemScript.equals(activeFederation instanceof ErpFederation ? ((ErpFederation) activeFederation).getDefaultRedeemScript() : activeFederation.getRedeemScript())) { spendingFederationOptional = Optional.of(activeFederation); } else if (retiringFederation != null && - inputStandardRedeemScript.equals(retiringFederation instanceof ErpFederation ? ((ErpFederation) retiringFederation).getStandardRedeemScript() : retiringFederation.getRedeemScript()) ) { + inputStandardRedeemScript.equals(retiringFederation instanceof ErpFederation ? ((ErpFederation) retiringFederation).getDefaultRedeemScript() : retiringFederation.getRedeemScript()) ) { spendingFederationOptional = Optional.of(retiringFederation); } else { fail("pegout scriptsig does not match any Federation"); diff --git a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java index fee7f0045e7..7120d8f117a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java @@ -18,7 +18,7 @@ package co.rsk.peg; -import static co.rsk.peg.FederationCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; import co.rsk.bitcoinj.core.Address; @@ -58,7 +58,7 @@ void setUp() { networkParameters = bridgeConstants.getBtcParams(); federation = bridgeConstants.getGenesisFederation(); - keys = federation.getBtcPublicKeys(); + keys = federation.getMembersPublicKeys(); sortedPublicKeys = keys.stream() .sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); @@ -73,7 +73,7 @@ void setUp() { @Test void createInvalidFederation_aboveMaxScriptSigSize() { - List newKeys = federation.getBtcPublicKeys(); + List newKeys = federation.getMembersPublicKeys(); BtcECKey federator15PublicKey = BtcECKey.fromPublicOnly( Hex.decode("03b65684ccccda83cbb1e56b31308acd08e993114c33f66a456b627c2c1c68bed6") ); @@ -82,8 +82,8 @@ void createInvalidFederation_aboveMaxScriptSigSize() { newKeys.add(federator15PublicKey); List newMembers = FederationTestUtils.getFederationMembersWithBtcKeys(newKeys); Instant creationTime = federation.getCreationTime(); - FederationCreationException exception = - assertThrows(FederationCreationException.class, () -> new StandardMultisigFederation( + ScriptCreationException exception = + assertThrows(ScriptCreationException.class, () -> new StandardMultisigFederation( newMembers, creationTime, federation.creationBlockNumber, @@ -169,7 +169,7 @@ void testEquals_differentNetworkParameters() { @Test void testEquals_differentNumberOfMembers() { // remove federator14 - List newKeys = federation.getBtcPublicKeys(); + List newKeys = federation.getMembersPublicKeys(); newKeys.remove(14); List newMembers = FederationTestUtils.getFederationMembersWithKeys(newKeys); @@ -189,7 +189,7 @@ void testEquals_differentMembers() { BtcECKey anotherPublicKey = BtcECKey.fromPublicOnly( Hex.decode("03b65694ccccda83cbb1e56b31308acd08e993114c33f66a456b627c2c1c68bed7") ); - List newKeys = federation.getBtcPublicKeys(); + List newKeys = federation.getMembersPublicKeys(); newKeys.remove(14); newKeys.add(anotherPublicKey); List differentMembers = FederationTestUtils.getFederationMembersWithKeys(newKeys); @@ -247,7 +247,7 @@ void getRedeemScript() { @Test void getBtcPublicKeyIndex() { - for (int i = 0; i < federation.getBtcPublicKeys().size(); i++) { + for (int i = 0; i < federation.getMembersPublicKeys().size(); i++) { Optional index = federation.getBtcPublicKeyIndex(sortedPublicKeys.get(i)); assertTrue(index.isPresent()); assertEquals(i, index.get().intValue()); @@ -257,7 +257,7 @@ void getBtcPublicKeyIndex() { @Test void hasBtcPublicKey() { - for (int i = 0; i < federation.getBtcPublicKeys().size(); i++) { + for (int i = 0; i < federation.getMembersPublicKeys().size(); i++) { assertTrue(federation.hasBtcPublicKey(sortedPublicKeys.get(i))); } assertFalse(federation.hasBtcPublicKey(BtcECKey.fromPrivate(BigInteger.valueOf(1234)))); @@ -265,7 +265,7 @@ void hasBtcPublicKey() { @Test void hasMemberWithRskAddress() { - for (int i = 0; i < federation.getBtcPublicKeys().size(); i++) { + for (int i = 0; i < federation.getMembersPublicKeys().size(); i++) { assertTrue(federation.hasMemberWithRskAddress(rskAddresses.get(i))); } diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java index 96b4a111779..a98a33a8dea 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java @@ -75,7 +75,7 @@ void getFederationCreationBlockNumber() throws IOException, VMException { @Test void getFederatorPublicKey() throws IOException, VMException { ExecutionStats stats = new ExecutionStats("getFederatorPublicKey"); - ABIEncoder abiEncoder = (int executionIndex) -> Bridge.GET_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, federation.getBtcPublicKeys().size()-1)}); + ABIEncoder abiEncoder = (int executionIndex) -> Bridge.GET_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, federation.getMembersPublicKeys().size()-1)}); executeTestCaseSection(abiEncoder, "getFederatorPublicKey", true,50, stats); executeTestCaseSection(abiEncoder, "getFederatorPublicKey", false,500, stats); diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java index 0d5c580939c..e15535b3046 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java @@ -47,7 +47,7 @@ void getPendingFederationSize() throws VMException { void getPendingFederatorPublicKey() throws VMException { ExecutionStats stats = new ExecutionStats("getPendingFederatorPublicKey"); ABIEncoder abiEncoder; - abiEncoder = (int executionIndex) -> Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, pendingFederation.getBtcPublicKeys().size()-1)}); + abiEncoder = (int executionIndex) -> Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, pendingFederation.getMembersPublicKeys().size()-1)}); executeTestCaseSection(abiEncoder, "getPendingFederatorPublicKey", true,200, stats); abiEncoder = (int executionIndex) -> Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, 10)}); executeTestCaseSection(abiEncoder, "getPendingFederatorPublicKey", false,200, stats); diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java index 227f4d13f5a..a15d6e460e6 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java @@ -66,7 +66,7 @@ void getRetiringFederationCreationBlockNumber() throws VMException { void getRetiringFederatorPublicKey() throws VMException { ExecutionStats stats = new ExecutionStats("getRetiringFederatorPublicKey"); ABIEncoder abiEncoder; - abiEncoder = (int executionIndex) -> Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, retiringFederation.getBtcPublicKeys().size()-1)}); + abiEncoder = (int executionIndex) -> Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, retiringFederation.getMembersPublicKeys().size()-1)}); executeTestCaseSection(abiEncoder, "getRetiringFederatorPublicKey", true,50, stats); abiEncoder = (int executionIndex) -> Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, 10)}); executeTestCaseSection(abiEncoder, "getRetiringFederatorPublicKey", false,500, stats); diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index 369dc1898bd..638b8f4f553 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -251,9 +251,9 @@ void logCommitFederation(boolean isRSKIP383Active) { assertTopics(1, eventLogs); // Assert log data - byte[] oldFederationFlatPubKeys = flatKeysAsByteArray(oldFederation.getBtcPublicKeys()); + byte[] oldFederationFlatPubKeys = flatKeysAsByteArray(oldFederation.getMembersPublicKeys()); String oldFederationBtcAddress = oldFederation.getAddress().toBase58(); - byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getBtcPublicKeys()); + byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getMembersPublicKeys()); String newFederationBtcAddress = newFederation.getAddress().toBase58(); long newFedActivationBlockNumber = executionBlock.getNumber() + CONSTANTS.getFederationActivationAge(activations); diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java index dfc52e60c63..e9b0201b9ad 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java @@ -255,7 +255,7 @@ void testLogCommitFederationBeforeRskip146() { RLPList oldFedPubKeys = (RLPList) oldFedData.get(1); Assertions.assertEquals(4, oldFedPubKeys.size()); for (int i = 0; i < 4; i++) { - Assertions.assertEquals(oldFederation.getBtcPublicKeys().get(i), BtcECKey.fromPublicOnly(oldFedPubKeys.get(i).getRLPData())); + Assertions.assertEquals(oldFederation.getMembersPublicKeys().get(i), BtcECKey.fromPublicOnly(oldFedPubKeys.get(i).getRLPData())); } // Assert new federation data @@ -266,7 +266,7 @@ void testLogCommitFederationBeforeRskip146() { RLPList newFedPubKeys = (RLPList) newFedData.get(1); Assertions.assertEquals(3, newFedPubKeys.size()); for (int i = 0; i < 3; i++) { - Assertions.assertEquals(newFederation.getBtcPublicKeys().get(i), BtcECKey.fromPublicOnly(newFedPubKeys.get(i).getRLPData())); + Assertions.assertEquals(newFederation.getMembersPublicKeys().get(i), BtcECKey.fromPublicOnly(newFedPubKeys.get(i).getRLPData())); } // Assert new federation activation block number From b48970e463ff035a96fb1fe72acb352804550bbd Mon Sep 17 00:00:00 2001 From: julia zack Date: Tue, 21 Nov 2023 11:20:12 -0300 Subject: [PATCH 025/137] Make erpBuilder private in federation and create an accessor method. Rename validateEmergencyKeys method. Make methods non-static when not needed. Rename ErpRedeemScriptBuilderCreationException to FederationCreationException. Fix typo. Move removeOpCheckMultisig method to builder utils. Delete unused Standardness file --- .../main/java/co/rsk/peg/BridgeBtcWallet.java | 2 +- .../co/rsk/peg/BridgeSerializationUtils.java | 2 +- .../co/rsk/peg/BridgeStorageProvider.java | 7 ++-- .../main/java/co/rsk/peg/BridgeSupport.java | 12 +++---- .../main/java/co/rsk/peg/ErpFederation.java | 36 ++++++++++--------- ...va => ErpFederationCreationException.java} | 7 ++-- .../rsk/peg/ErpRedeemScriptBuilderUtils.java | 15 +++++--- .../src/main/java/co/rsk/peg/Federation.java | 2 +- .../java/co/rsk/peg/FederationSupport.java | 4 +-- .../rsk/peg/FlyoverCompatibleBtcWallet.java | 2 +- .../NonStandardErpRedeemScriptBuilder.java | 8 ++--- ...StandardErpRedeemScriptBuilderFactory.java | 8 ++--- ...ndardErpRedeemScriptBuilderHardcoded.java} | 4 +-- ...pRedeemScriptBuilderWithCsvUnsignedBE.java | 9 ++--- .../rsk/peg/P2shErpRedeemScriptBuilder.java | 2 +- .../java/co/rsk/peg/PendingFederation.java | 4 +-- .../java/co/rsk/peg/ScriptValidations.java | 2 +- .../rsk/peg/StandardMultisigFederation.java | 2 +- .../java/co/rsk/peg/bitcoin/Standardness.java | 7 ---- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 4 +-- .../peg/utils/BrigeEventLoggerLegacyImpl.java | 4 +-- .../rsk/peg/BridgeSerializationUtilsTest.java | 12 +++---- .../co/rsk/peg/BridgeStorageProviderTest.java | 6 ++-- .../peg/BridgeSupportAddSignatureTest.java | 16 ++++----- .../rsk/peg/BridgeSupportTestIntegration.java | 12 +++---- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 4 +-- .../co/rsk/peg/LegacyErpFederationTest.java | 35 +++++++++--------- .../co/rsk/peg/P2shErpFederationTest.java | 33 ++++++++--------- .../peg/StandardMultisigFederationTest.java | 14 ++++---- .../peg/performance/ActiveFederationTest.java | 2 +- .../performance/PendingFederationTest.java | 2 +- .../performance/RetiringFederationTest.java | 2 +- .../peg/utils/BridgeEventLoggerImplTest.java | 4 +-- .../BridgeEventLoggerLegacyImplTest.java | 4 +-- 34 files changed, 144 insertions(+), 145 deletions(-) rename rskj-core/src/main/java/co/rsk/peg/{ErpRedeemScriptBuilderCreationException.java => ErpFederationCreationException.java} (66%) rename rskj-core/src/main/java/co/rsk/peg/{NonStandardErpRedeemScriptBuilderHardcoaded.java => NonStandardErpRedeemScriptBuilderHardcoded.java} (90%) delete mode 100644 rskj-core/src/main/java/co/rsk/peg/bitcoin/Standardness.java diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java b/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java index 3c5b77973c1..c777f7b8a17 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java @@ -55,6 +55,6 @@ public RedeemData findRedeemDataFromScriptHash(byte[] payToScriptHash) { Optional destinationFederation = getDestinationFederation(payToScriptHash); return destinationFederation.map(federation -> RedeemData - .of(federation.getMembersPublicKeys(), federation.getRedeemScript())).orElse(null); + .of(federation.getBtcPublicKeys(), federation.getRedeemScript())).orElse(null); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 0813cdfc2cd..d21f6abf1a8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -402,7 +402,7 @@ private static FederationMember deserializeFederationMember(byte[] data) { * See BridgeSerializationUtils::serializeBtcPublicKeys */ public static byte[] serializePendingFederationOnlyBtcKeys(PendingFederation pendingFederation) { - return serializeBtcPublicKeys(pendingFederation.getMembersPublicKeys()); + return serializeBtcPublicKeys(pendingFederation.getBtcPublicKeys()); } // For the serialization format, see BridgeSerializationUtils::serializePendingFederationOnlyBtcKeys diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index e708ab0bea5..b00e0f10aeb 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -39,7 +39,6 @@ import java.util.*; import static co.rsk.peg.BridgeStorageIndexKey.*; -import static co.rsk.peg.NonStandardErpRedeemScriptBuilderFactory.*; import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; /** @@ -363,7 +362,7 @@ public void saveNewFederation() { if (activations.isActive(RSKIP123)) { if (newFederation instanceof ErpFederation) { - ErpRedeemScriptBuilder builder = ((ErpFederation) newFederation).erpRedeemScriptBuilder; + ErpRedeemScriptBuilder builder = ((ErpFederation) newFederation).getErpRedeemScriptBuilder(); if (builder instanceof P2shErpRedeemScriptBuilder) { saveStorageVersion( NEW_FEDERATION_FORMAT_VERSION.getKey(), @@ -428,7 +427,7 @@ protected void saveOldFederation() { if (activations.isActive(RSKIP123)) { if (oldFederation instanceof ErpFederation) { - ErpRedeemScriptBuilder builder = ((ErpFederation) oldFederation).erpRedeemScriptBuilder; + ErpRedeemScriptBuilder builder = ((ErpFederation) oldFederation).getErpRedeemScriptBuilder(); if (builder instanceof P2shErpRedeemScriptBuilder) { saveStorageVersion( OLD_FEDERATION_FORMAT_VERSION.getKey(), @@ -1046,7 +1045,7 @@ private DataWord getStorageKeyForFlyoverFederationInformation(byte[] flyoverFede private DataWord getStorageKeyForNewFederationBtcUtxos() { DataWord key = NEW_FEDERATION_BTC_UTXOS_KEY.getKey(); - if (checkIfNetworkIsTestnet(networkParameters)) { + if (networkParameters.getId().equals(NetworkParameters.ID_TESTNET)) { if (activations.isActive(RSKIP284)) { key = NEW_FEDERATION_BTC_UTXOS_KEY_FOR_TESTNET_PRE_HOP.getKey(); } 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 e2fb8aa79a6..e202bc16f60 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1898,7 +1898,7 @@ public Address getFederationAddress() { * @return the federation size */ public Integer getFederationSize() { - return getActiveFederation().getMembersPublicKeys().size(); + return getActiveFederation().getBtcPublicKeys().size(); } /** @@ -1967,7 +1967,7 @@ public Integer getRetiringFederationSize() { return -1; } - return retiringFederation.getMembersPublicKeys().size(); + return retiringFederation.getBtcPublicKeys().size(); } /** @@ -1994,7 +1994,7 @@ public byte[] getRetiringFederatorPublicKey(int index) { return null; } - List publicKeys = retiringFederation.getMembersPublicKeys(); + List publicKeys = retiringFederation.getBtcPublicKeys(); if (index < 0 || index >= publicKeys.size()) { throw new IndexOutOfBoundsException(String.format("Retiring federator index must be between 0 and %d", publicKeys.size() - 1)); @@ -2117,7 +2117,7 @@ private Integer addFederatorPublicKeyMultikey(boolean dryRun, BtcECKey btcKey, E return -1; } - if (currentPendingFederation.getMembersPublicKeys().contains(btcKey) || + if (currentPendingFederation.getBtcPublicKeys().contains(btcKey) || currentPendingFederation.getMembers().stream().map(FederationMember::getRskPublicKey).anyMatch(k -> k.equals(rskKey)) || currentPendingFederation.getMembers().stream().map(FederationMember::getMstPublicKey).anyMatch(k -> k.equals(mstKey))) { return -2; @@ -2373,7 +2373,7 @@ public Integer getPendingFederationSize() { return -1; } - return currentPendingFederation.getMembersPublicKeys().size(); + return currentPendingFederation.getBtcPublicKeys().size(); } /** @@ -2388,7 +2388,7 @@ public byte[] getPendingFederatorPublicKey(int index) { return null; } - List publicKeys = currentPendingFederation.getMembersPublicKeys(); + List publicKeys = currentPendingFederation.getBtcPublicKeys(); if (index < 0 || index >= publicKeys.size()) { throw new IndexOutOfBoundsException(String.format("Federator index must be between 0 and %d", publicKeys.size() - 1)); diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java index b9e6c72ca0e..04e1cb3cbf8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java @@ -11,15 +11,15 @@ import java.util.List; import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import static co.rsk.peg.ErpRedeemScriptBuilderCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; +import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; public class ErpFederation extends Federation { - protected final List erpPubKeys; - protected final long activationDelay; - protected final ActivationConfig.ForBlock activations; - protected Script standardRedeemScript; - protected Script standardP2SHScript; - protected ErpRedeemScriptBuilder erpRedeemScriptBuilder; + private final List erpPubKeys; + private final long activationDelay; + private final ActivationConfig.ForBlock activations; + private Script defaultRedeemScript; + private Script defaultP2SHScript; + private ErpRedeemScriptBuilder erpRedeemScriptBuilder; protected ErpFederation( List members, @@ -32,7 +32,7 @@ protected ErpFederation( ErpRedeemScriptBuilder erpRedeemScriptBuilder) { super(members, creationTime, creationBlockNumber, btcParams); - validateEmergencyKeysAreNotNullNorEmpty(erpPubKeys); + validateEmergencyKeys(erpPubKeys); this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpPubKeys); this.activationDelay = activationDelay; @@ -40,13 +40,15 @@ protected ErpFederation( this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; } - private void validateEmergencyKeysAreNotNullNorEmpty(List erpPubKeys) { + private void validateEmergencyKeys(List erpPubKeys) { if (erpPubKeys == null || erpPubKeys.isEmpty()) { String message = "Emergency keys are not provided"; - throw new ErpRedeemScriptBuilderCreationException(message, NULL_OR_EMPTY_EMERGENCY_KEYS); + throw new ErpFederationCreationException(message, NULL_OR_EMPTY_EMERGENCY_KEYS); } } + public ErpRedeemScriptBuilder getErpRedeemScriptBuilder() { return erpRedeemScriptBuilder; } + public List getErpPubKeys() { return Collections.unmodifiableList(erpPubKeys); } @@ -61,18 +63,18 @@ public long getActivationDelay() { } public Script getDefaultRedeemScript() { - if (standardRedeemScript == null) { - standardRedeemScript = RedeemScriptParserFactory.get(getRedeemScript().getChunks()) + if (defaultRedeemScript == null) { + defaultRedeemScript = RedeemScriptParserFactory.get(getRedeemScript().getChunks()) .extractStandardRedeemScript(); } - return standardRedeemScript; + return defaultRedeemScript; } @Override public Script getRedeemScript() { if (redeemScript == null) { redeemScript = erpRedeemScriptBuilder.createRedeemScriptFromKeys( - getMembersPublicKeys(), + getBtcPublicKeys(), getNumberOfSignaturesRequired(), erpPubKeys, getNumberOfEmergencySignaturesRequired(), @@ -83,11 +85,11 @@ public Script getRedeemScript() { } public Script getDefaultP2SHScript() { - if (standardP2SHScript == null) { - standardP2SHScript = ScriptBuilder.createP2SHOutputScript(getDefaultRedeemScript()); + if (defaultP2SHScript == null) { + defaultP2SHScript = ScriptBuilder.createP2SHOutputScript(getDefaultRedeemScript()); } - return standardP2SHScript; + return defaultP2SHScript; } } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderCreationException.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java similarity index 66% rename from rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderCreationException.java rename to rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java index 4788c457138..9ae499a02eb 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderCreationException.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java @@ -4,21 +4,22 @@ * Exception to be thrown when attempting to create a Federation with invalid values * that could result in the 2wp to stop working as expected */ -public class ErpRedeemScriptBuilderCreationException extends RuntimeException { +public class ErpFederationCreationException extends RuntimeException { private final Reason reason; public enum Reason { NULL_OR_EMPTY_EMERGENCY_KEYS, + INVALID_INTERNAL_REDEEM_SCRIPTS, INVALID_CSV_VALUE, HARDCODED_LEGACY_ERP_TESTNET_REDEEM_SCRIPT } - public ErpRedeemScriptBuilderCreationException(String s, Reason reason) { + public ErpFederationCreationException(String s, Reason reason) { super(s); this.reason = reason; } - public ErpRedeemScriptBuilderCreationException(String message, Throwable cause, Reason reason) { + public ErpFederationCreationException(String message, Throwable cause, Reason reason) { super(message, cause); this.reason = reason; } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java index ea1b6196176..2aee931d2fd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java @@ -1,11 +1,14 @@ package co.rsk.peg; -import co.rsk.bitcoinj.core.VerificationException; import co.rsk.bitcoinj.script.Script; +import co.rsk.bitcoinj.script.ScriptChunk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static co.rsk.peg.ErpRedeemScriptBuilderCreationException.Reason.INVALID_CSV_VALUE; +import java.util.List; + +import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_INTERNAL_REDEEM_SCRIPTS; +import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; public class ErpRedeemScriptBuilderUtils { private static final long MAX_CSV_VALUE = 65535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value @@ -14,6 +17,10 @@ public class ErpRedeemScriptBuilderUtils { private ErpRedeemScriptBuilderUtils() { } + public static List removeOpCheckMultisig(Script redeemScript) { + return redeemScript.getChunks().subList(0, redeemScript.getChunks().size() - 1); + } + public static void validateRedeemScriptValues( Script defaultFederationRedeemScript, Script erpFederationRedeemScript, @@ -28,7 +35,7 @@ public static void validateRedeemScriptValues( defaultFederationRedeemScript, erpFederationRedeemScript ); - throw new VerificationException(message); + throw new ErpFederationCreationException(message, INVALID_INTERNAL_REDEEM_SCRIPTS); } if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { @@ -38,7 +45,7 @@ public static void validateRedeemScriptValues( MAX_CSV_VALUE ); logger.warn("[validateRedeemScriptValues] {}", message); - throw new ErpRedeemScriptBuilderCreationException(message, INVALID_CSV_VALUE); + throw new ErpFederationCreationException(message, INVALID_CSV_VALUE); } } } diff --git a/rskj-core/src/main/java/co/rsk/peg/Federation.java b/rskj-core/src/main/java/co/rsk/peg/Federation.java index aec4adb4939..247554623c1 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/Federation.java @@ -64,7 +64,7 @@ public List getMembers() { return members; } - public List getMembersPublicKeys() { + public List getBtcPublicKeys() { // Copy instances since we don't control // immutability of BtcECKey instances return members.stream() diff --git a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java index 03f6b7870b8..ea657d14fd5 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java @@ -49,7 +49,7 @@ public FederationSupport(BridgeConstants bridgeConstants, BridgeStorageProvider * @return the federation size */ public int getFederationSize() { - return getActiveFederation().getMembersPublicKeys().size(); + return getActiveFederation().getBtcPublicKeys().size(); } /** @@ -58,7 +58,7 @@ public int getFederationSize() { * @return the federator's public key */ public byte[] getFederatorBtcPublicKey(int index) { - List publicKeys = getActiveFederation().getMembersPublicKeys(); + List publicKeys = getActiveFederation().getBtcPublicKeys(); if (index < 0 || index >= publicKeys.size()) { throw new IndexOutOfBoundsException(String.format("Federator index must be between 0 and %d", publicKeys.size() - 1)); diff --git a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java index cf4a757ac5e..06e0c99b13d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java +++ b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java @@ -64,7 +64,7 @@ public RedeemData findRedeemDataFromScriptHash(byte[] payToScriptHash) { ); } - return RedeemData.of(destinationFederationInstance.getMembersPublicKeys(), flyoverRedeemScript); + return RedeemData.of(destinationFederationInstance.getBtcPublicKeys(), flyoverRedeemScript); } return super.findRedeemDataFromScriptHash(payToScriptHash); diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java index ea9703bf75d..778acc62d06 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java @@ -8,6 +8,8 @@ import java.util.List; +import static co.rsk.peg.ErpRedeemScriptBuilderUtils.removeOpCheckMultisig; + public class NonStandardErpRedeemScriptBuilder implements ErpRedeemScriptBuilder { private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilder.class); @@ -34,7 +36,7 @@ public Script createRedeemScriptFromKeys(List defaultPublicKeys, } - private static Script createRedeemScriptFromScripts(Script defaultRedeemScript, + private Script createRedeemScriptFromScripts(Script defaultRedeemScript, Script emergencyRedeemScript, byte[] serializedCsvValue) { @@ -51,8 +53,4 @@ private static Script createRedeemScriptFromScripts(Script defaultRedeemScript, .op(ScriptOpCodes.OP_CHECKMULTISIG) .build(); } - - protected static List removeOpCheckMultisig(Script redeemScript) { - return redeemScript.getChunks().subList(0, redeemScript.getChunks().size() - 1); - } } diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java index 6210cdc54b4..da8b40ae7d1 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java @@ -15,10 +15,10 @@ public static ErpRedeemScriptBuilder defineNonStandardErpRedeemScriptBuilder( ErpRedeemScriptBuilder erpRedeemScriptBuilder; - boolean networkParametersIsTestnetOrRegtest = checkIfNetworkIsTestnet(networkParameters); + boolean networkIsTestnet = checkIfNetworkIsTestnet(networkParameters); - if(!activations.isActive(ConsensusRule.RSKIP284) && networkParametersIsTestnetOrRegtest) { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoaded(); + if(!activations.isActive(ConsensusRule.RSKIP284) && networkIsTestnet) { + erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoded(); } else if (!activations.isActive(ConsensusRule.RSKIP293)) { erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); } else { @@ -28,7 +28,7 @@ public static ErpRedeemScriptBuilder defineNonStandardErpRedeemScriptBuilder( return erpRedeemScriptBuilder; } - public static boolean checkIfNetworkIsTestnet(NetworkParameters networkParameters) { + private static boolean checkIfNetworkIsTestnet(NetworkParameters networkParameters) { return networkParameters.getId().equals(NetworkParameters.ID_TESTNET); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoded.java similarity index 90% rename from rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java rename to rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoded.java index c7b0ead5901..cd636e77c94 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoaded.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoded.java @@ -8,8 +8,8 @@ import java.util.List; -public class NonStandardErpRedeemScriptBuilderHardcoaded implements ErpRedeemScriptBuilder { - private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderHardcoaded.class); +public class NonStandardErpRedeemScriptBuilderHardcoded implements ErpRedeemScriptBuilder { + private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderHardcoded.class); private static final byte[] LEGACY_ERP_TESTNET_REDEEM_SCRIPT_BYTES = Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f42102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da210344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a0921039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb955670300cd50b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); @Override diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java index abe7e9ecb28..993b007a391 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java @@ -4,13 +4,14 @@ import co.rsk.bitcoinj.core.Utils; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; -import co.rsk.bitcoinj.script.ScriptChunk; import co.rsk.bitcoinj.script.ScriptOpCodes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.List; +import static co.rsk.peg.ErpRedeemScriptBuilderUtils.removeOpCheckMultisig; + public class NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE implements ErpRedeemScriptBuilder { private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.class); @@ -37,7 +38,7 @@ public Script createRedeemScriptFromKeys(List defaultPublicKeys, } - private static Script createRedeemScriptFromScripts(Script defaultRedeemScript, + private Script createRedeemScriptFromScripts(Script defaultRedeemScript, Script emergencyRedeemScript, byte[] serializedCsvValue) { @@ -54,8 +55,4 @@ private static Script createRedeemScriptFromScripts(Script defaultRedeemScript, .op(ScriptOpCodes.OP_CHECKMULTISIG) .build(); } - - protected static List removeOpCheckMultisig(Script redeemScript) { - return redeemScript.getChunks().subList(0, redeemScript.getChunks().size() - 1); - } } diff --git a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java index c9cc84a1ffd..efc21bfd744 100644 --- a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java @@ -34,7 +34,7 @@ public Script createRedeemScriptFromKeys(List defaultPublicKeys, return redeemScript; } - private static Script createRedeemScriptFromScripts(Script defaultRedeemScript, + private Script createRedeemScriptFromScripts(Script defaultRedeemScript, Script emergencyRedeemScript, byte[] serializedCsvValue) { diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java index 2bb3550d313..472f33dee7f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java @@ -64,7 +64,7 @@ public List getMembers() { return members; } - public List getMembersPublicKeys() { + public List getBtcPublicKeys() { // Copy keys since we don't control immutability of BtcECKey(s) return members.stream() .map(FederationMember::getBtcPublicKey) @@ -171,6 +171,6 @@ public Keccak256 getHash() { public int hashCode() { // Can use java.util.Objects.hash since List has a // well-defined hashCode() - return Objects.hash(getMembersPublicKeys()); + return Objects.hash(getBtcPublicKeys()); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java b/rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java index 807e5dd52d0..dfe16068133 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java +++ b/rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java @@ -7,7 +7,7 @@ public class ScriptValidations { private ScriptValidations() { } - public static void validateScriptSize(Script script) throws ErpRedeemScriptBuilderCreationException { + public static void validateScriptSize(Script script) throws ErpFederationCreationException { // Check if the size of the script does not exceed the maximum size allowed int bytesFromScript = script.getProgram().length; if (bytesFromScript > Script.MAX_SCRIPT_ELEMENT_SIZE) { diff --git a/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java b/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java index ae9b9981e63..c628d3bd0dc 100644 --- a/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java @@ -47,7 +47,7 @@ public StandardMultisigFederation( @Override public Script getRedeemScript() { if (redeemScript == null) { - redeemScript = ScriptBuilder.createRedeemScript(getNumberOfSignaturesRequired(), getMembersPublicKeys()); + redeemScript = ScriptBuilder.createRedeemScript(getNumberOfSignaturesRequired(), getBtcPublicKeys()); } return redeemScript; diff --git a/rskj-core/src/main/java/co/rsk/peg/bitcoin/Standardness.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/Standardness.java deleted file mode 100644 index b4edf404b28..00000000000 --- a/rskj-core/src/main/java/co/rsk/peg/bitcoin/Standardness.java +++ /dev/null @@ -1,7 +0,0 @@ -package co.rsk.peg.bitcoin; - -public class Standardness { - public static final int MAX_SCRIPT_ELEMENT_SIZE = 520; - private Standardness() { - } -} diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index b47d13969f2..9f8c328f975 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -103,9 +103,9 @@ public void logReleaseBtc(BtcTransaction btcTx, byte[] rskTxHash) { @Override public void logCommitFederation(Block executionBlock, Federation oldFederation, Federation newFederation) { // Convert old federation public keys in bytes array - byte[] oldFederationFlatPubKeys = flatKeysAsByteArray(oldFederation.getMembersPublicKeys()); + byte[] oldFederationFlatPubKeys = flatKeysAsByteArray(oldFederation.getBtcPublicKeys()); String oldFederationBtcAddress = oldFederation.getAddress().toBase58(); - byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getMembersPublicKeys()); + byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getBtcPublicKeys()); String newFederationBtcAddress = newFederation.getAddress().toBase58(); long newFedActivationBlockNumber = executionBlock.getNumber() + this.bridgeConstants.getFederationActivationAge(activations); diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java index 13f338878a3..81d521ea1cb 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java @@ -113,10 +113,10 @@ public void logCommitFederation(Block executionBlock, Federation oldFederation, } List topics = Collections.singletonList(Bridge.COMMIT_FEDERATION_TOPIC); - byte[] oldFedFlatPubKeys = flatKeysAsRlpCollection(oldFederation.getMembersPublicKeys()); + byte[] oldFedFlatPubKeys = flatKeysAsRlpCollection(oldFederation.getBtcPublicKeys()); byte[] oldFedData = RLP.encodeList(RLP.encodeElement(oldFederation.getAddress().getHash160()), RLP.encodeList(oldFedFlatPubKeys)); - byte[] newFedFlatPubKeys = flatKeysAsRlpCollection(newFederation.getMembersPublicKeys()); + byte[] newFedFlatPubKeys = flatKeysAsRlpCollection(newFederation.getBtcPublicKeys()); byte[] newFedData = RLP.encodeList(RLP.encodeElement(newFederation.getAddress().getHash160()), RLP.encodeList(newFedFlatPubKeys)); long newFedActivationBlockNumber = executionBlock.getNumber() + this.bridgeConstants.getFederationActivationAge(activations); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 7ac3c60b9bf..b8838b08e9c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -172,7 +172,7 @@ void serializeFederationOnlyBtcKeys() throws Exception { expectedBuilder.append("2a"); // Creation block number expectedBuilder.append("f8cc"); // Inner list - federation.getMembersPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { + federation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { expectedBuilder.append("a1"); expectedBuilder.append(ByteUtil.toHexString(key.getPubKey())); }); @@ -206,11 +206,11 @@ void deserializeFederationOnlyBtcKeys_ok() throws Exception { Assertions.assertEquals(5000, deserializedFederation.getCreationTime().toEpochMilli()); Assertions.assertEquals(4, deserializedFederation.getNumberOfSignaturesRequired()); - Assertions.assertEquals(6, deserializedFederation.getMembersPublicKeys().size()); + Assertions.assertEquals(6, deserializedFederation.getBtcPublicKeys().size()); MatcherAssert.assertThat(deserializedFederation.getCreationBlockNumber(), is(42L)); for (int i = 0; i < 6; i++) { - Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedFederation.getMembersPublicKeys().get(i).getPubKey())); + Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedFederation.getBtcPublicKeys().get(i).getPubKey())); } Assertions.assertEquals(NetworkParameters.fromID(NetworkParameters.ID_REGTEST), deserializedFederation.getBtcParams()); @@ -438,7 +438,7 @@ void serializePendingFederationOnlyBtcKeys() throws Exception { byte[] result = BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(pendingFederation); StringBuilder expectedBuilder = new StringBuilder(); expectedBuilder.append("f8cc"); - pendingFederation.getMembersPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { + pendingFederation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { expectedBuilder.append("a1"); expectedBuilder.append(ByteUtil.toHexString(key.getPubKey())); }); @@ -465,9 +465,9 @@ void deserializePendingFederationOnlyBtcKeys() throws Exception { PendingFederation deserializedPendingFederation = BridgeSerializationUtils.deserializePendingFederationOnlyBtcKeys(data); - Assertions.assertEquals(6, deserializedPendingFederation.getMembersPublicKeys().size()); + Assertions.assertEquals(6, deserializedPendingFederation.getBtcPublicKeys().size()); for (int i = 0; i < 6; i++) { - Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedPendingFederation.getMembersPublicKeys().get(i).getPubKey())); + Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedPendingFederation.getBtcPublicKeys().get(i).getPubKey())); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 012a9bd990c..80e3e0ea0d8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -411,7 +411,7 @@ void getNewFederation_erp_fed() { bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), mock(ActivationConfig.ForBlock.class), - new NonStandardErpRedeemScriptBuilderHardcoaded() + new NonStandardErpRedeemScriptBuilderHardcoded() ); testGetNewFederationPostMultiKey(erpFederation); @@ -699,7 +699,7 @@ void getOldFederation_nonStandardHardcoaded_fed() { bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), activations, - new NonStandardErpRedeemScriptBuilderHardcoaded() + new NonStandardErpRedeemScriptBuilderHardcoded() ); testGetOldFederation(erpFederation, activations); @@ -3974,7 +3974,7 @@ private int getFederationVersion(Federation federation) { if (federation instanceof StandardMultisigFederation) { return BridgeStorageProvider.STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION; } else if (federation instanceof ErpFederation) { - ErpRedeemScriptBuilder builder = ((ErpFederation) federation).erpRedeemScriptBuilder; + ErpRedeemScriptBuilder builder = ((ErpFederation) federation).getErpRedeemScriptBuilder(); if (builder instanceof P2shErpRedeemScriptBuilder) { return BridgeStorageProvider.P2SH_ERP_FEDERATION_FORMAT_VERSION; } else { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index 9fdb4e3d2a3..5f4744eef9e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -255,7 +255,7 @@ void addSignatureToMissingTransaction() throws Exception { .withRepository(repository) .build(); - bridgeSupport.addSignature(federation.getMembersPublicKeys().get(0), null, createHash().getBytes()); + bridgeSupport.addSignature(federation.getBtcPublicKeys().get(0), null, createHash().getBytes()); bridgeSupport.save(); BridgeStorageProvider provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, @@ -503,7 +503,7 @@ void addSignatureMultipleInputsPartiallyValid() throws Exception { } // Sign with two valid signatures and one invalid signature - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); bridgeSupport.save(); // Sign with two valid signatures and one malformed signature @@ -512,16 +512,16 @@ void addSignatureMultipleInputsPartiallyValid() throws Exception { malformedSignature[i] = (byte) i; } derEncodedSigsFirstFed.set(2, malformedSignature); - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); bridgeSupport.save(); // Sign with fully valid signatures for same federator derEncodedSigsFirstFed.set(2, lastSig.encodeToDER()); - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeyOfFirstFed), derEncodedSigsFirstFed, keccak256.getBytes()); bridgeSupport.save(); // Sign with second federation - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeyOfSecondFed), derEncodedSigsSecondFed, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeyOfSecondFed), derEncodedSigsSecondFed, keccak256.getBytes()); bridgeSupport.save(); provider = new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstantsRegtest, activationsBeforeForks); @@ -608,7 +608,7 @@ private void addSignatureFromValidFederator(List privateKeysToSignWith for (int i = 0; i < numberOfInputsToSign; i++) { derEncodedSigs.add(derEncodedSig); } - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeysToSignWith.get(0)), derEncodedSigs, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(0)), derEncodedSigs, keccak256.getBytes()); if (signTwice) { // Create another valid signature with the same private key ECDSASigner signer = new ECDSASigner(); @@ -620,7 +620,7 @@ private void addSignatureFromValidFederator(List privateKeysToSignWith BtcECKey.ECDSASignature sig2 = new BtcECKey.ECDSASignature(components[0], components[1]).toCanonicalised(); List list = new ArrayList<>(); list.add(sig2.encodeToDER()); - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeysToSignWith.get(0)), list, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(0)), list, keccak256.getBytes()); } if (privateKeysToSignWith.size() > 1) { BtcECKey.ECDSASignature sig2 = privateKeysToSignWith.get(1).sign(sighash); @@ -629,7 +629,7 @@ private void addSignatureFromValidFederator(List privateKeysToSignWith for (int i = 0; i < numberOfInputsToSign; i++) { derEncodedSigs2.add(derEncodedSig2); } - bridgeSupport.addSignature(findPublicKeySignedBy(federation.getMembersPublicKeys(), privateKeysToSignWith.get(1)), derEncodedSigs2, keccak256.getBytes()); + bridgeSupport.addSignature(findPublicKeySignedBy(federation.getBtcPublicKeys(), privateKeysToSignWith.get(1)), derEncodedSigs2, keccak256.getBytes()); } bridgeSupport.save(); track.commit(); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java index 54c54dd914c..386560080f5 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java @@ -1301,17 +1301,17 @@ void registerBtcTransactionReleaseTx() throws BlockStoreException, AddressFormat // Create tx input base script sig Script scriptSig = PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(federation); // Create sighash - Script redeemScript = ScriptBuilder.createRedeemScript(federation.getNumberOfSignaturesRequired(), federation.getMembersPublicKeys()); + Script redeemScript = ScriptBuilder.createRedeemScript(federation.getNumberOfSignaturesRequired(), federation.getBtcPublicKeys()); Sha256Hash sighash = tx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false); // Sign by federator 0 BtcECKey.ECDSASignature sig0 = BridgeRegTestConstants.REGTEST_FEDERATION_PRIVATE_KEYS.get(0).sign(sighash); TransactionSignature txSig0 = new TransactionSignature(sig0, BtcTransaction.SigHash.ALL, false); - int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, federation.getMembersPublicKeys().get(0)); + int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, federation.getBtcPublicKeys().get(0)); scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig0.encodeToBitcoin(), sigIndex0, 1, 1); // Sign by federator 1 BtcECKey.ECDSASignature sig1 = BridgeRegTestConstants.REGTEST_FEDERATION_PRIVATE_KEYS.get(1).sign(sighash); TransactionSignature txSig1 = new TransactionSignature(sig1, BtcTransaction.SigHash.ALL, false); - int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, federation.getMembersPublicKeys().get(1)); + int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, federation.getBtcPublicKeys().get(1)); scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig1.encodeToBitcoin(), sigIndex1, 1, 1); // Set scipt sign to tx input tx.getInput(0).setScriptSig(scriptSig); @@ -1417,17 +1417,17 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm // Create tx input base script sig Script scriptSig = PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation(retiringFederation); // Create sighash - Script redeemScript = ScriptBuilder.createRedeemScript(retiringFederation.getNumberOfSignaturesRequired(), retiringFederation.getMembersPublicKeys()); + Script redeemScript = ScriptBuilder.createRedeemScript(retiringFederation.getNumberOfSignaturesRequired(), retiringFederation.getBtcPublicKeys()); Sha256Hash sighash = tx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false); // Sign by federator 0 BtcECKey.ECDSASignature sig0 = retiringFederationKeys.get(0).sign(sighash); TransactionSignature txSig0 = new TransactionSignature(sig0, BtcTransaction.SigHash.ALL, false); - int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getMembersPublicKeys().get(0)); + int sigIndex0 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getBtcPublicKeys().get(0)); scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig0.encodeToBitcoin(), sigIndex0, 1, 1); // Sign by federator 1 BtcECKey.ECDSASignature sig1 = retiringFederationKeys.get(1).sign(sighash); TransactionSignature txSig1 = new TransactionSignature(sig1, BtcTransaction.SigHash.ALL, false); - int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getMembersPublicKeys().get(1)); + int sigIndex1 = scriptSig.getSigInsertionIndex(sighash, retiringFederation.getBtcPublicKeys().get(1)); scriptSig = ScriptBuilder.updateScriptWithSignature(scriptSig, txSig1.encodeToBitcoin(), sigIndex1, 1, 1); // Set scipt sign to tx input tx.getInput(0).setScriptSig(scriptSig); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index 76bf6f798a8..477eb393199 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -1617,7 +1617,7 @@ private void signWithNKeys( int numberOfSignatures) { Script scriptPubKey = federation.getP2SHScript(); - RedeemData redeemData = RedeemData.of(federation.getMembersPublicKeys(), federationRedeemScript); + RedeemData redeemData = RedeemData.of(federation.getBtcPublicKeys(), federationRedeemScript); Script inputScript = scriptPubKey.createEmptyInputScript(redeemData.keys.get(0), redeemData.redeemScript); txIn.setScriptSig(inputScript); @@ -1643,7 +1643,7 @@ private Script signWithOneKey( int federatorIndex) { BtcECKey federatorPrivKey = privateKeys.get(federatorIndex); - BtcECKey federatorPublicKey = federation.getMembersPublicKeys().get(federatorIndex); + BtcECKey federatorPublicKey = federation.getBtcPublicKeys().get(federatorIndex); BtcECKey.ECDSASignature sig = federatorPrivKey.sign(sighash); TransactionSignature txSig = new TransactionSignature(sig, BtcTransaction.SigHash.ALL, false); diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index a2b0b887397..b6fcad879cd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -1,8 +1,9 @@ package co.rsk.peg; -import static co.rsk.peg.ErpRedeemScriptBuilderCreationException.Reason.*; +import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; +import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; -import static co.rsk.peg.bitcoin.Standardness.MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -111,8 +112,8 @@ private ErpFederation createDefaultLegacyErpFederation() { @Test void createInvalidLegacyErpFederation_nullErpKeys() { emergencyKeys = null; - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, this::createDefaultLegacyErpFederation + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, this::createDefaultLegacyErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -120,8 +121,8 @@ void createInvalidLegacyErpFederation_nullErpKeys() { @Test void createInvalidLegacyErpFederation_emptyErpKeys() { emergencyKeys = new ArrayList<>(); - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, this::createDefaultLegacyErpFederation + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, this::createDefaultLegacyErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -135,8 +136,8 @@ void createValidLegacyErpFederation_oneErpKey() { void createInvalidLegacyErpFederation_negativeCsvValue() { activationDelayValue = -100L; ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); @@ -146,8 +147,8 @@ void createInvalidLegacyErpFederation_negativeCsvValue() { void createInvalidLegacyErpFederation_zeroCsvValue() { activationDelayValue = 0L; ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); @@ -157,8 +158,8 @@ void createInvalidLegacyErpFederation_zeroCsvValue() { void createInvalidLegacyErpFederation_aboveMaxCsvValue() { activationDelayValue = MAX_CSV_VALUE + 1; ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); @@ -173,7 +174,7 @@ void createValidLegacyErpFederation_exactMaxCsvValue() { @Test void createInvalidNonStandardBuilder_aboveMaxScriptSigSize() { // add one member to exceed redeem script size limit - List newStandardKeys = federation.getMembersPublicKeys(); + List newStandardKeys = federation.getBtcPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( Hex.decode("02550cc87fa9061162b1dd395a16662529c9d8094c0feca17905a3244713d65fe8") ); @@ -263,7 +264,7 @@ void testEquals_differentNetworkParameters() { @Test void testEquals_differentNumberOfMembers() { // remove federator9 - List newStandardKeys = federation.getMembersPublicKeys(); + List newStandardKeys = federation.getBtcPublicKeys(); newStandardKeys.remove(newStandardKeys.size() - 1); standardKeys = newStandardKeys; @@ -277,7 +278,7 @@ void testEquals_differentMembers() { BtcECKey federator9PublicKey = BtcECKey.fromPublicOnly( Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea") ); - List newStandardKeys = federation.getMembersPublicKeys(); + List newStandardKeys = federation.getBtcPublicKeys(); newStandardKeys.remove(8); newStandardKeys.add(federator9PublicKey); standardKeys = newStandardKeys; @@ -454,7 +455,7 @@ void getRedeemScript_before_RSKIP_284_testnet() { emergencyKeys, activationDelayValue, activations, - new NonStandardErpRedeemScriptBuilderHardcoaded() + new NonStandardErpRedeemScriptBuilderHardcoded() ); assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, erpFederation.getRedeemScript()); @@ -571,7 +572,7 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { List federationMembersWithBtcKeys = FederationTestUtils.getFederationMembersWithBtcKeys(standardMultisigKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); - assertThrows(ErpRedeemScriptBuilderCreationException.class, () -> new ErpFederation( + assertThrows(ErpFederationCreationException.class, () -> new ErpFederation( federationMembersWithBtcKeys, creationTime, 1, diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index 03867476e22..852ad1e5af4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -1,8 +1,9 @@ package co.rsk.peg; -import static co.rsk.peg.ErpRedeemScriptBuilderCreationException.Reason.*; +import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; +import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; -import static co.rsk.peg.bitcoin.Standardness.MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; @@ -100,8 +101,8 @@ private ErpFederation createDefaultP2shErpFederation() { @Test void createInvalidP2shErpFederation_nullErpKeys() { emergencyKeys = null; - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, this::createDefaultP2shErpFederation + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, this::createDefaultP2shErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -109,8 +110,8 @@ void createInvalidP2shErpFederation_nullErpKeys() { @Test void createInvalidP2shErpFederation_emptyErpKeys() { emergencyKeys = new ArrayList<>(); - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, this::createDefaultP2shErpFederation + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, this::createDefaultP2shErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -126,8 +127,8 @@ void createInvalidP2shErpFederation_negativeCsvValue() { activationDelayValue = -100L; ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); @@ -137,8 +138,8 @@ void createInvalidP2shErpFederation_negativeCsvValue() { void createInvalidP2shErpFederation_zeroCsvValue() { activationDelayValue = 0L; ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); @@ -148,8 +149,8 @@ void createInvalidP2shErpFederation_zeroCsvValue() { void createInvalidP2shErpFederation_aboveMaxCsvValue() { activationDelayValue = MAX_CSV_VALUE + 1; ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); - ErpRedeemScriptBuilderCreationException exception = assertThrows( - ErpRedeemScriptBuilderCreationException.class, + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); @@ -164,7 +165,7 @@ void createValidP2shErpFederation_exactMaxCsvValue() { @Test void createInvalidFederation_aboveMaxScriptSigSize() { // add one member to exceed redeem script size limit - List newStandardKeys = federation.getMembersPublicKeys(); + List newStandardKeys = federation.getBtcPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( Hex.decode("02550cc87fa9061162b1dd395a16662529c9d8094c0feca17905a3244713d65fe8") ); @@ -218,7 +219,7 @@ void testEquals_same() { @Test void testEquals_differentNumberOfMembers() { // remove federator9 - List newStandardKeys = federation.getMembersPublicKeys(); + List newStandardKeys = federation.getBtcPublicKeys(); newStandardKeys.remove(9); standardKeys = newStandardKeys; @@ -240,7 +241,7 @@ void testEquals_differentMembers() { Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea") ); // replace federator8 with federator9 - List newStandardKeys = federation.getMembersPublicKeys(); + List newStandardKeys = federation.getBtcPublicKeys(); newStandardKeys.remove(8); newStandardKeys.add(federator9PublicKey); standardKeys = newStandardKeys; @@ -256,7 +257,7 @@ void getRedeemScript(BridgeConstants bridgeConstants) { // should add this case because adding erp to mainnet genesis federation // throws a validation error, so in that case we use the one set up before each test. // if using testnet constants, we can add them with no errors - standardKeys = bridgeConstants.getGenesisFederation().getMembersPublicKeys(); + standardKeys = bridgeConstants.getGenesisFederation().getBtcPublicKeys(); } emergencyKeys = bridgeConstants.getErpFedPubKeysList(); diff --git a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java index 7120d8f117a..936a5c9c804 100644 --- a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java @@ -58,7 +58,7 @@ void setUp() { networkParameters = bridgeConstants.getBtcParams(); federation = bridgeConstants.getGenesisFederation(); - keys = federation.getMembersPublicKeys(); + keys = federation.getBtcPublicKeys(); sortedPublicKeys = keys.stream() .sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); @@ -73,7 +73,7 @@ void setUp() { @Test void createInvalidFederation_aboveMaxScriptSigSize() { - List newKeys = federation.getMembersPublicKeys(); + List newKeys = federation.getBtcPublicKeys(); BtcECKey federator15PublicKey = BtcECKey.fromPublicOnly( Hex.decode("03b65684ccccda83cbb1e56b31308acd08e993114c33f66a456b627c2c1c68bed6") ); @@ -169,7 +169,7 @@ void testEquals_differentNetworkParameters() { @Test void testEquals_differentNumberOfMembers() { // remove federator14 - List newKeys = federation.getMembersPublicKeys(); + List newKeys = federation.getBtcPublicKeys(); newKeys.remove(14); List newMembers = FederationTestUtils.getFederationMembersWithKeys(newKeys); @@ -189,7 +189,7 @@ void testEquals_differentMembers() { BtcECKey anotherPublicKey = BtcECKey.fromPublicOnly( Hex.decode("03b65694ccccda83cbb1e56b31308acd08e993114c33f66a456b627c2c1c68bed7") ); - List newKeys = federation.getMembersPublicKeys(); + List newKeys = federation.getBtcPublicKeys(); newKeys.remove(14); newKeys.add(anotherPublicKey); List differentMembers = FederationTestUtils.getFederationMembersWithKeys(newKeys); @@ -247,7 +247,7 @@ void getRedeemScript() { @Test void getBtcPublicKeyIndex() { - for (int i = 0; i < federation.getMembersPublicKeys().size(); i++) { + for (int i = 0; i < federation.getBtcPublicKeys().size(); i++) { Optional index = federation.getBtcPublicKeyIndex(sortedPublicKeys.get(i)); assertTrue(index.isPresent()); assertEquals(i, index.get().intValue()); @@ -257,7 +257,7 @@ void getBtcPublicKeyIndex() { @Test void hasBtcPublicKey() { - for (int i = 0; i < federation.getMembersPublicKeys().size(); i++) { + for (int i = 0; i < federation.getBtcPublicKeys().size(); i++) { assertTrue(federation.hasBtcPublicKey(sortedPublicKeys.get(i))); } assertFalse(federation.hasBtcPublicKey(BtcECKey.fromPrivate(BigInteger.valueOf(1234)))); @@ -265,7 +265,7 @@ void hasBtcPublicKey() { @Test void hasMemberWithRskAddress() { - for (int i = 0; i < federation.getMembersPublicKeys().size(); i++) { + for (int i = 0; i < federation.getBtcPublicKeys().size(); i++) { assertTrue(federation.hasMemberWithRskAddress(rskAddresses.get(i))); } diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java index a98a33a8dea..96b4a111779 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java @@ -75,7 +75,7 @@ void getFederationCreationBlockNumber() throws IOException, VMException { @Test void getFederatorPublicKey() throws IOException, VMException { ExecutionStats stats = new ExecutionStats("getFederatorPublicKey"); - ABIEncoder abiEncoder = (int executionIndex) -> Bridge.GET_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, federation.getMembersPublicKeys().size()-1)}); + ABIEncoder abiEncoder = (int executionIndex) -> Bridge.GET_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, federation.getBtcPublicKeys().size()-1)}); executeTestCaseSection(abiEncoder, "getFederatorPublicKey", true,50, stats); executeTestCaseSection(abiEncoder, "getFederatorPublicKey", false,500, stats); diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java index e15535b3046..0d5c580939c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java @@ -47,7 +47,7 @@ void getPendingFederationSize() throws VMException { void getPendingFederatorPublicKey() throws VMException { ExecutionStats stats = new ExecutionStats("getPendingFederatorPublicKey"); ABIEncoder abiEncoder; - abiEncoder = (int executionIndex) -> Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, pendingFederation.getMembersPublicKeys().size()-1)}); + abiEncoder = (int executionIndex) -> Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, pendingFederation.getBtcPublicKeys().size()-1)}); executeTestCaseSection(abiEncoder, "getPendingFederatorPublicKey", true,200, stats); abiEncoder = (int executionIndex) -> Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, 10)}); executeTestCaseSection(abiEncoder, "getPendingFederatorPublicKey", false,200, stats); diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java index a15d6e460e6..227f4d13f5a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java @@ -66,7 +66,7 @@ void getRetiringFederationCreationBlockNumber() throws VMException { void getRetiringFederatorPublicKey() throws VMException { ExecutionStats stats = new ExecutionStats("getRetiringFederatorPublicKey"); ABIEncoder abiEncoder; - abiEncoder = (int executionIndex) -> Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, retiringFederation.getMembersPublicKeys().size()-1)}); + abiEncoder = (int executionIndex) -> Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, retiringFederation.getBtcPublicKeys().size()-1)}); executeTestCaseSection(abiEncoder, "getRetiringFederatorPublicKey", true,50, stats); abiEncoder = (int executionIndex) -> Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY.encode(new Object[]{Helper.randomInRange(0, 10)}); executeTestCaseSection(abiEncoder, "getRetiringFederatorPublicKey", false,500, stats); diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index 638b8f4f553..369dc1898bd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -251,9 +251,9 @@ void logCommitFederation(boolean isRSKIP383Active) { assertTopics(1, eventLogs); // Assert log data - byte[] oldFederationFlatPubKeys = flatKeysAsByteArray(oldFederation.getMembersPublicKeys()); + byte[] oldFederationFlatPubKeys = flatKeysAsByteArray(oldFederation.getBtcPublicKeys()); String oldFederationBtcAddress = oldFederation.getAddress().toBase58(); - byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getMembersPublicKeys()); + byte[] newFederationFlatPubKeys = flatKeysAsByteArray(newFederation.getBtcPublicKeys()); String newFederationBtcAddress = newFederation.getAddress().toBase58(); long newFedActivationBlockNumber = executionBlock.getNumber() + CONSTANTS.getFederationActivationAge(activations); diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java index e9b0201b9ad..dfc52e60c63 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java @@ -255,7 +255,7 @@ void testLogCommitFederationBeforeRskip146() { RLPList oldFedPubKeys = (RLPList) oldFedData.get(1); Assertions.assertEquals(4, oldFedPubKeys.size()); for (int i = 0; i < 4; i++) { - Assertions.assertEquals(oldFederation.getMembersPublicKeys().get(i), BtcECKey.fromPublicOnly(oldFedPubKeys.get(i).getRLPData())); + Assertions.assertEquals(oldFederation.getBtcPublicKeys().get(i), BtcECKey.fromPublicOnly(oldFedPubKeys.get(i).getRLPData())); } // Assert new federation data @@ -266,7 +266,7 @@ void testLogCommitFederationBeforeRskip146() { RLPList newFedPubKeys = (RLPList) newFedData.get(1); Assertions.assertEquals(3, newFedPubKeys.size()); for (int i = 0; i < 3; i++) { - Assertions.assertEquals(newFederation.getMembersPublicKeys().get(i), BtcECKey.fromPublicOnly(newFedPubKeys.get(i).getRLPData())); + Assertions.assertEquals(newFederation.getBtcPublicKeys().get(i), BtcECKey.fromPublicOnly(newFedPubKeys.get(i).getRLPData())); } // Assert new federation activation block number From 4b21c2dbce3032df2118cf7dd24e5b3134a8e6ca Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 23 Nov 2023 10:58:31 -0300 Subject: [PATCH 026/137] Create getRedeemScriptParser method in ErpFederation --- rskj-core/src/main/java/co/rsk/peg/ErpFederation.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java index 04e1cb3cbf8..8408ec164f3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java @@ -2,9 +2,11 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.bitcoinj.script.RedeemScriptParser; import co.rsk.bitcoinj.script.RedeemScriptParserFactory; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.bitcoinj.script.ScriptChunk; import co.rsk.peg.utils.EcKeyUtils; import java.time.Instant; import java.util.Collections; @@ -64,7 +66,7 @@ public long getActivationDelay() { public Script getDefaultRedeemScript() { if (defaultRedeemScript == null) { - defaultRedeemScript = RedeemScriptParserFactory.get(getRedeemScript().getChunks()) + defaultRedeemScript = getRedeemScriptParser(redeemScript) .extractStandardRedeemScript(); } return defaultRedeemScript; @@ -84,6 +86,11 @@ public Script getRedeemScript() { return redeemScript; } + private RedeemScriptParser getRedeemScriptParser(Script redeemScript) { + List chunks = redeemScript.getChunks(); + return RedeemScriptParserFactory.get(chunks); + } + public Script getDefaultP2SHScript() { if (defaultP2SHScript == null) { defaultP2SHScript = ScriptBuilder.createP2SHOutputScript(getDefaultRedeemScript()); From 11d2de963edfa05a029ceb9cde058f16889fb2af Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 23 Nov 2023 11:01:21 -0300 Subject: [PATCH 027/137] Create CSV_BYTES_NEEDED_LENGTH constant --- .../NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java index 993b007a391..2ffcb370101 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java @@ -14,6 +14,7 @@ public class NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE implements ErpRedeemScriptBuilder { private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.class); + private static final int CSV_BYTES_NEEDED_LENGTH = 2; @Override public Script createRedeemScriptFromKeys(List defaultPublicKeys, @@ -26,8 +27,8 @@ public Script createRedeemScriptFromKeys(List defaultPublicKeys, Script emergencyRedeemScript = ScriptBuilder.createRedeemScript(emergencyThreshold, emergencyPublicKeys); ErpRedeemScriptBuilderUtils.validateRedeemScriptValues(defaultRedeemScript, emergencyRedeemScript, csvValue); - - byte[] serializedCsvValue = Utils.unsignedLongToByteArrayBE(csvValue, 2); + + byte[] serializedCsvValue = Utils.unsignedLongToByteArrayBE(csvValue, CSV_BYTES_NEEDED_LENGTH); logger.debug("[createRedeemScriptFromKeys] Creating the redeem script from the scripts"); Script redeemScript = createRedeemScriptFromScripts(defaultRedeemScript, emergencyRedeemScript, serializedCsvValue); From 91b0b9aba51a778db10418328e7a67cb9543318a Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 23 Nov 2023 11:04:20 -0300 Subject: [PATCH 028/137] Make MAX_CSV_VALUE field public and use it when needed instead of defining it again --- .../main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java | 2 +- .../src/test/java/co/rsk/peg/LegacyErpFederationTest.java | 5 ++--- .../src/test/java/co/rsk/peg/P2shErpFederationTest.java | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java index 2aee931d2fd..1b86a390533 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java @@ -11,8 +11,8 @@ import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; public class ErpRedeemScriptBuilderUtils { - private static final long MAX_CSV_VALUE = 65535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value private static final Logger logger = LoggerFactory.getLogger(ErpRedeemScriptBuilderUtils.class); + public static final long MAX_CSV_VALUE = 65535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value private ErpRedeemScriptBuilderUtils() { } diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index b6fcad879cd..edf04ff8be6 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -47,7 +47,6 @@ import org.junit.jupiter.api.Test; class LegacyErpFederationTest { - public static long MAX_CSV_VALUE = 65535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value private ErpFederation federation; private NetworkParameters networkParameters; private List standardKeys; @@ -156,7 +155,7 @@ void createInvalidLegacyErpFederation_zeroCsvValue() { @Test void createInvalidLegacyErpFederation_aboveMaxCsvValue() { - activationDelayValue = MAX_CSV_VALUE + 1; + activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1; ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); ErpFederationCreationException exception = assertThrows( ErpFederationCreationException.class, @@ -167,7 +166,7 @@ void createInvalidLegacyErpFederation_aboveMaxCsvValue() { @Test void createValidLegacyErpFederation_exactMaxCsvValue() { - activationDelayValue = MAX_CSV_VALUE; + activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE; assertDoesNotThrow(this::createDefaultLegacyErpFederation); } diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index 852ad1e5af4..dc558bf278a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -41,7 +41,6 @@ import org.junit.jupiter.params.provider.MethodSource; class P2shErpFederationTest { - public static long MAX_CSV_VALUE = 65535L; // 2^16 - 1, since bitcoin will interpret up to 16 bits as the CSV value private ErpFederation federation; private NetworkParameters networkParameters; private List standardKeys; @@ -147,7 +146,7 @@ void createInvalidP2shErpFederation_zeroCsvValue() { @Test void createInvalidP2shErpFederation_aboveMaxCsvValue() { - activationDelayValue = MAX_CSV_VALUE + 1; + activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1; ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); ErpFederationCreationException exception = assertThrows( ErpFederationCreationException.class, @@ -158,7 +157,7 @@ void createInvalidP2shErpFederation_aboveMaxCsvValue() { @Test void createValidP2shErpFederation_exactMaxCsvValue() { - activationDelayValue = MAX_CSV_VALUE; + activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE; assertDoesNotThrow(this::createDefaultP2shErpFederation); } From e27f68db1558d70d772185f98aa89aaa8aaf423a Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 23 Nov 2023 11:05:55 -0300 Subject: [PATCH 029/137] Rename defineNonStandardErpRedeemScriptBuilder to getNonStandardErpRedeemScriptBuilder --- .../co/rsk/peg/BridgeSerializationUtils.java | 2 +- .../main/java/co/rsk/peg/ErpFederation.java | 2 +- ...StandardErpRedeemScriptBuilderFactory.java | 2 +- .../java/co/rsk/peg/PendingFederation.java | 2 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 2 +- .../BridgeStorageProviderFederationTests.java | 2 +- .../co/rsk/peg/BridgeStorageProviderTest.java | 314 +++++++++--------- .../co/rsk/peg/LegacyErpFederationTest.java | 2 +- .../co/rsk/peg/PendingFederationTest.java | 2 +- .../java/co/rsk/peg/PowpegMigrationTest.java | 3 +- 10 files changed, 167 insertions(+), 166 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index d21f6abf1a8..474797da1e9 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -326,7 +326,7 @@ public static ErpFederation deserializeLegacyErpFederation( ); ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); return new ErpFederation( federation.getMembers(), diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java index 8408ec164f3..e2b3e8722fd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java @@ -66,7 +66,7 @@ public long getActivationDelay() { public Script getDefaultRedeemScript() { if (defaultRedeemScript == null) { - defaultRedeemScript = getRedeemScriptParser(redeemScript) + defaultRedeemScript = getRedeemScriptParser(getRedeemScript()) .extractStandardRedeemScript(); } return defaultRedeemScript; diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java index da8b40ae7d1..190b071fdc4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java @@ -9,7 +9,7 @@ public class NonStandardErpRedeemScriptBuilderFactory { private NonStandardErpRedeemScriptBuilderFactory() { } - public static ErpRedeemScriptBuilder defineNonStandardErpRedeemScriptBuilder( + public static ErpRedeemScriptBuilder getNonStandardErpRedeemScriptBuilder( ActivationConfig.ForBlock activations, NetworkParameters networkParameters) { diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java index 472f33dee7f..779bac905dd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java @@ -122,7 +122,7 @@ public Federation buildFederation( logger.info("[buildFederation] Going to create an ERP Federation"); ErpRedeemScriptBuilder erpRedeemScriptBuilder - = NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); return new ErpFederation( members, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index b8838b08e9c..5bd4ce214de 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -1240,7 +1240,7 @@ private void testSerializeAndDeserializeFederation( when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(isRskip353Active); ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); for (int i = 0; i < NUM_CASES; i++) { int numMembers = randomInRange(2, 14); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index 7800614f9df..b2a964169b7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -616,7 +616,7 @@ private Federation createFederation(int version) { ); case LEGACY_ERP_FEDERATION_FORMAT_VERSION: ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstantsRegtest.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstantsRegtest.getBtcParams()); return new ErpFederation( members, Instant.now(), diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 80e3e0ea0d8..3e279125e45 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -87,7 +87,8 @@ class BridgeStorageProviderTest { private final TestSystemProperties config = new TestSystemProperties(); private final ActivationConfig.ForBlock activationsBeforeFork = ActivationConfigsForTest.genesis().forBlock(0L); private final ActivationConfig.ForBlock activationsAllForks = ActivationConfigsForTest.all().forBlock(0); - private final NetworkParameters networkParameters = BridgeTestNetConstants.getInstance().getBtcParams(); + private final BridgeTestNetConstants bridgeTestnetInstance = BridgeTestNetConstants.getInstance(); + private final NetworkParameters networkParameters = bridgeTestnetInstance.getBtcParams(); private int transactionOffset; @@ -97,7 +98,7 @@ void createInstance() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -130,7 +131,7 @@ void createSaveAndRecreateInstance() throws IOException { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); provider0.getReleaseRequestQueue(); @@ -155,7 +156,7 @@ void createSaveAndRecreateInstance() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -196,7 +197,7 @@ void createSaveAndRecreateInstanceWithProcessedHashes() throws IOException { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); provider0.setHeightBtcTxhashAlreadyProcessed(hash1, 1L); @@ -209,7 +210,7 @@ void createSaveAndRecreateInstanceWithProcessedHashes() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -232,7 +233,7 @@ void createSaveAndRecreateInstanceWithTxsWaitingForSignatures() throws IOExcepti BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); provider0.getPegoutsWaitingForSignatures().put(hash1, tx1); @@ -247,7 +248,7 @@ void createSaveAndRecreateInstanceWithTxsWaitingForSignatures() throws IOExcepti BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -272,14 +273,14 @@ void createSaveAndRecreateInstanceWithUTXOS() throws IOException { Repository repository = createRepository(); Repository track = repository.startTracking(); - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; // Federation is the genesis federation ATM Federation federation = bridgeConstants.getGenesisFederation(); BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); provider0.getNewFederationBtcUTXOs().add(new UTXO(hash1, 1, Coin.COIN, 0, false, ScriptBuilder.createOutputScript(federation.getAddress()))); @@ -292,7 +293,7 @@ void createSaveAndRecreateInstanceWithUTXOS() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -311,7 +312,7 @@ void getNewFederation_initialVersion() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -338,11 +339,11 @@ void getNewFederation_initialVersion() { bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.deserializeStandardMultisigFederationOnlyBtcKeys(any(byte[].class), any(NetworkParameters.class))).then((InvocationOnMock invocation) -> { deserializeCalls.add(0); byte[] data = invocation.getArgument(0); - NetworkParameters networkParameters = invocation.getArgument(1); + NetworkParameters networkParametersReceived = invocation.getArgument(1); // Make sure we're deserializing what just came from the repo with the correct BTC context assertArrayEquals(new byte[]{(byte) 0xaa}, data); - Assertions.assertEquals(networkParameters, BridgeTestNetConstants.getInstance().getBtcParams()); + Assertions.assertEquals(networkParametersReceived, networkParameters); return newFederation; }); @@ -361,7 +362,7 @@ void getNewFederation_initialVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -401,7 +402,7 @@ void getNewFederation_multiKeyVersion() { @Test void getNewFederation_erp_fed() { - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); ErpFederation erpFederation = new ErpFederation( newFederation.getMembers(), @@ -425,8 +426,8 @@ void getNewFederation_p2sh_erp_fed() { newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), - BridgeTestNetConstants.getInstance().getErpFedPubKeysList(), - BridgeTestNetConstants.getInstance().getErpFedActivationDelay(), + bridgeTestnetInstance.getErpFedPubKeysList(), + bridgeTestnetInstance.getErpFedActivationDelay(), mock(ActivationConfig.ForBlock.class), new P2shErpRedeemScriptBuilder() ); @@ -442,7 +443,7 @@ void getNewFederation_multiKeyVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -494,7 +495,7 @@ void saveNewFederation_preMultikey() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -546,7 +547,7 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); ErpFederation erpFederation = new ErpFederation( @@ -569,7 +570,7 @@ void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(true); - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); ErpFederation p2shErpFederation = new ErpFederation( @@ -595,7 +596,7 @@ void getOldFederation_initialVersion() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -622,10 +623,11 @@ void getOldFederation_initialVersion() { bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.deserializeStandardMultisigFederationOnlyBtcKeys(any(byte[].class), any(NetworkParameters.class))).then((InvocationOnMock invocation) -> { deserializeCalls.add(0); byte[] data = invocation.getArgument(0); - NetworkParameters networkParameters = invocation.getArgument(1); + NetworkParameters networkParametersReceived = invocation.getArgument(1); + // Make sure we're deserializing what just came from the repo with the correct BTC context assertArrayEquals(new byte[]{(byte) 0xaa}, data); - assertEquals(networkParameters, BridgeTestNetConstants.getInstance().getBtcParams()); + assertEquals(networkParametersReceived, networkParameters); return oldFederation; }); @@ -643,7 +645,7 @@ void getOldFederation_initialVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -684,7 +686,7 @@ void getOldFederation_multiKeyVersion() { @Test void getOldFederation_nonStandardHardcoaded_fed() { - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -707,7 +709,7 @@ void getOldFederation_nonStandardHardcoaded_fed() { @Test void getOldFederation_nonStandardWithUnsignedBE_fed() { - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -731,7 +733,7 @@ void getOldFederation_nonStandardWithUnsignedBE_fed() { @Test void getOldFederation_nonStandard_fed() { - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -756,7 +758,7 @@ void getOldFederation_nonStandard_fed() { @Test void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -782,7 +784,7 @@ void getOldFederation_multiKeyVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -831,7 +833,7 @@ void saveOldFederation_preMultikey() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -881,7 +883,7 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); ErpFederation erpFederation = new ErpFederation( oldFederation.getMembers(), @@ -902,7 +904,7 @@ void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); ErpFederation p2shErpFederation = new ErpFederation( oldFederation.getMembers(), @@ -923,7 +925,7 @@ void saveOldFederation_preMultikey_setToNull() { try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { List storageBytesCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); Mockito.doAnswer((InvocationOnMock invocation) -> { storageBytesCalls.add(0); @@ -958,7 +960,7 @@ void saveOldFederation_postMultikey_setToNull() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -1001,7 +1003,7 @@ void getPendingFederation_initialVersion() { List deserializeCalls = new ArrayList<>(); PendingFederation pendingFederation = buildMockPendingFederation(100, 200, 300); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { storageCalls.add(0); @@ -1043,7 +1045,7 @@ void getPendingFederation_initialVersion_nullBytes() { List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { storageCalls.add(0); @@ -1077,7 +1079,7 @@ void getPendingFederation_multiKeyVersion() { List deserializeCalls = new ArrayList<>(); PendingFederation pendingFederation = buildMockPendingFederation(100, 200, 300); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { storageCalls.add(0); @@ -1121,7 +1123,7 @@ void getPendingFederation_multiKeyVersion_nullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -1156,7 +1158,7 @@ void savePendingFederation_preMultikey() { List storageBytesCalls = new ArrayList<>(); List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(any(PendingFederation.class))).then((InvocationOnMock invocation) -> { @@ -1194,7 +1196,7 @@ void savePendingFederation_preMultikey_setToNull() { try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { List storageBytesCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); Mockito.doAnswer((InvocationOnMock invocation) -> { storageBytesCalls.add(0); @@ -1226,7 +1228,7 @@ void savePendingFederation_postMultikey() { List storageBytesCalls = new ArrayList<>(); List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsAllForks); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsAllForks); try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class, Mockito.CALLS_REAL_METHODS)) { bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializePendingFederation(any(PendingFederation.class))).then((InvocationOnMock invocation) -> { @@ -1272,7 +1274,7 @@ void savePendingFederation_postMultikey_setToNull() { try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class, Mockito.CALLS_REAL_METHODS)) { List storageBytesCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsAllForks); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsAllForks); Mockito.doAnswer((InvocationOnMock invocation) -> { storageBytesCalls.add(0); @@ -1312,7 +1314,7 @@ void getFederationElection_nonNullBytes() { AddressBasedAuthorizer authorizerMock = mock(AddressBasedAuthorizer.class); ABICallElection electionMock = mock(ABICallElection.class); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { calls.add(0); @@ -1345,7 +1347,7 @@ void getFederationElection_nullBytes() { List calls = new ArrayList<>(); AddressBasedAuthorizer authorizerMock = mock(AddressBasedAuthorizer.class); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))).then((InvocationOnMock invocation) -> { calls.add(0); @@ -1376,7 +1378,7 @@ void saveFederationElection() { List storageBytesCalls = new ArrayList<>(); List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializeElection(any(ABICallElection.class))).then((InvocationOnMock invocation) -> { @@ -1422,7 +1424,7 @@ void getLockWhitelist_nonNullBytes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -1483,7 +1485,7 @@ void getLockWhitelist_nonNullBytes() { void getLockWhitelist_nullBytes() { List calls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsAllForks); when(repositoryMock.getStorageBytes(any(RskAddress.class), any(DataWord.class))) @@ -1525,7 +1527,7 @@ void saveLockWhitelist() { List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); // Overriding activation to make sure it serializes the unlimited whitelist data - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsAllForks); try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { @@ -1595,7 +1597,7 @@ void saveLockWhiteListAfterGetWithData() { storageCalled.set(Boolean.FALSE); Repository repositoryMock = mock(Repository.class); OneOffWhiteListEntry oneOffEntry = new OneOffWhiteListEntry(getBtcAddress("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), Coin.COIN); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, config.getActivationConfig().forBlock(500L)); when(repositoryMock.getStorageBytes(any(RskAddress.class), eq(LOCK_ONE_OFF_WHITELIST_KEY.getKey()))) @@ -1632,7 +1634,7 @@ void saveLockWhiteListAfterGetWithData() { @Test void getReleaseRequestQueue_before_rskip_146_activation() throws IOException { Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); List oldEntriesList = new ArrayList<>(Collections.singletonList( new ReleaseRequestQueue.Entry( @@ -1671,7 +1673,7 @@ void getReleaseRequestQueue_after_rskip_146_activation() throws IOException { when(repositoryMock.getStorageBytes(any(),eq(RELEASE_REQUEST_QUEUE.getKey()))). thenReturn(BridgeSerializationUtils.serializeReleaseRequestQueue(new ReleaseRequestQueue(new ArrayList<>(Arrays.asList(oldEntry))))); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activations); ReleaseRequestQueue releaseRequestQueue = storageProvider.getReleaseRequestQueue(); @@ -1690,7 +1692,7 @@ void getReleaseRequestQueue_after_rskip_146_activation() throws IOException { @Test void saveReleaseRequestQueue_before_rskip_146_activation() throws IOException { Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); List oldEntriesList = new ArrayList<>(Collections.singletonList( new ReleaseRequestQueue.Entry( @@ -1735,7 +1737,7 @@ void saveReleaseRequestQueue_after_rskip_146_activation() throws IOException { when(repositoryMock.getStorageBytes(any(),eq(RELEASE_REQUEST_QUEUE.getKey()))). thenReturn(BridgeSerializationUtils.serializeReleaseRequestQueue(new ReleaseRequestQueue(new ArrayList<>(Arrays.asList(oldEntry))))); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activations); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activations); ReleaseRequestQueue releaseRequestQueue = storageProvider.getReleaseRequestQueue(); releaseRequestQueue.add(Address.fromBase58(BridgeRegTestConstants.getInstance().getBtcParams(), "mseEsMLuzaEdGbyAv9c9VRL9qGcb49qnxB"), @@ -1766,10 +1768,10 @@ void saveReleaseRequestQueue_after_rskip_146_activation() throws IOException { void getPegoutsWaitingForConfirmations_before_rskip_146_activation() throws IOException { Repository repositoryMock = mock(Repository.class); BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), activationsBeforeFork); + bridgeTestnetInstance, activationsBeforeFork); Set oldEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(networkParameters), 1L) )); when(repositoryMock.getStorageBytes(any(RskAddress.class), eq(PEGOUTS_WAITING_FOR_CONFIRMATIONS.getKey()))) @@ -1790,11 +1792,11 @@ void getPegoutsWaitingForConfirmations_after_rskip_146_activation() throws IOExc when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); Set oldEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(networkParameters), 1L) )); Set newEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(networkParameters), 1L, PegTestUtils.createHash3(0) ))); @@ -1805,11 +1807,11 @@ void getPegoutsWaitingForConfirmations_after_rskip_146_activation() throws IOExc .thenReturn(BridgeSerializationUtils.serializePegoutsWaitingForConfirmations(new PegoutsWaitingForConfirmations(oldEntriesSet))); BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), activations); + bridgeTestnetInstance, activations); PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations = storageProvider.getPegoutsWaitingForConfirmations(); - pegoutsWaitingForConfirmations.add(new SimpleBtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams(), PegTestUtils.createHash(0)), + pegoutsWaitingForConfirmations.add(new SimpleBtcTransaction(networkParameters, PegTestUtils.createHash(0)), 1L, PegTestUtils.createHash3(0)); @@ -1821,14 +1823,14 @@ void getPegoutsWaitingForConfirmations_after_rskip_146_activation() throws IOExc @Test void savePegoutsWaitingForConfirmations_before_rskip_146_activations() throws IOException { Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activationsBeforeFork); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); Set oldEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(networkParameters), 1L) )); PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations = storageProvider.getPegoutsWaitingForConfirmations(); - pegoutsWaitingForConfirmations.add(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L); + pegoutsWaitingForConfirmations.add(new BtcTransaction(networkParameters), 1L); doAnswer((i) -> { Set entries = BridgeSerializationUtils.deserializePegoutsWaitingForConfirmations(i.getArgument(2), networkParameters).getEntries(); @@ -1848,11 +1850,11 @@ void savePegoutsWaitingForConfirmations_after_rskip_146_activations() throws IOE when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); Set newEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L, PegTestUtils.createHash3(0)) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(networkParameters), 1L, PegTestUtils.createHash3(0)) )); Set oldEntriesSet = new HashSet<>(Collections.singletonList( - new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams()), 1L) + new PegoutsWaitingForConfirmations.Entry(new BtcTransaction(networkParameters), 1L) )); Repository repositoryMock = mock(Repository.class); @@ -1860,10 +1862,10 @@ void savePegoutsWaitingForConfirmations_after_rskip_146_activations() throws IOE when(repositoryMock.getStorageBytes(any(),eq(PEGOUTS_WAITING_FOR_CONFIRMATIONS.getKey()))). thenReturn(BridgeSerializationUtils.serializePegoutsWaitingForConfirmations(new PegoutsWaitingForConfirmations(oldEntriesSet))); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), BridgeTestNetConstants.getInstance(), activations); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activations); PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations = storageProvider.getPegoutsWaitingForConfirmations(); - pegoutsWaitingForConfirmations.add(new SimpleBtcTransaction(BridgeTestNetConstants.getInstance().getBtcParams(), PegTestUtils.createHash(1)), + pegoutsWaitingForConfirmations.add(new SimpleBtcTransaction(networkParameters, PegTestUtils.createHash(1)), 1L, PegTestUtils.createHash3(0)); @@ -1901,7 +1903,7 @@ void getReleaseTransaction_after_rskip_146_activations() throws IOException { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -1917,7 +1919,7 @@ void getReleaseTransaction_after_rskip_146_activations() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -1933,7 +1935,7 @@ void setFeePerKb_savedAndRecreated() { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -1947,7 +1949,7 @@ void setFeePerKb_savedAndRecreated() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -1961,7 +1963,7 @@ void getFeePerKbElection_emptyVotes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -1987,7 +1989,7 @@ void getFeePerKbElection_withVotes() { BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2016,7 +2018,7 @@ void setLockingCap_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); provider0.setLockingCap(Coin.ZERO); @@ -2033,7 +2035,7 @@ void setLockingCap_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2055,7 +2057,7 @@ void getLockingCap_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2074,7 +2076,7 @@ void getLockingCap_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2092,7 +2094,7 @@ void setLockingCapAndGetLockingCap() { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2108,7 +2110,7 @@ void setLockingCapAndGetLockingCap() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2132,7 +2134,7 @@ void getHeightIfBtcTxhashIsAlreadyProcessed_before_RSKIP134_does_not_use_new_sto BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2167,7 +2169,7 @@ void getHeightIfBtcTxhashIsAlreadyProcessed_after_RSKIP134_uses_new_storage() BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2208,7 +2210,7 @@ void setHeightBtcTxhashAlreadyProcessed_before_RSKIP134_does_not_use_new_storage BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2231,7 +2233,7 @@ void setHeightBtcTxhashAlreadyProcessed_before_RSKIP134_uses_new_storage() throw BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2254,7 +2256,7 @@ void saveHeightBtcTxHashAlreadyProcessed() throws IOException { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2279,7 +2281,7 @@ void getCoinBaseInformation_before_RSKIP143() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2302,7 +2304,7 @@ void getCoinBaseInformation_after_RSKIP143() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2319,7 +2321,7 @@ void setCoinBaseInformation_before_RSKIP143() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2340,7 +2342,7 @@ void setCoinBaseInformation_after_RSKIP143() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2361,7 +2363,7 @@ void saveCoinBaseInformation_before_RSKIP143() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2390,7 +2392,7 @@ void saveCoinBaseInformation_after_RSKIP143() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2418,7 +2420,7 @@ void getBtcBestBlockHashByHeight_beforeRskip199() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2435,7 +2437,7 @@ void getBtcBestBlockHashByHeight_afterRskip199_hashNotFound() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2456,7 +2458,7 @@ void getBtcBestBlockHashByHeight_afterRskip199() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2479,7 +2481,7 @@ void saveBtcBlocksIndex_beforeRskip199() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2506,7 +2508,7 @@ void saveBtcBlocksIndex_afterRskip199() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2527,7 +2529,7 @@ void getActiveFederationCreationBlockHeight_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -2545,7 +2547,7 @@ void getActiveFederationCreationBlockHeight_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); assertEquals(Optional.of(1L), provider0.getActiveFederationCreationBlockHeight()); @@ -2561,7 +2563,7 @@ void setActiveFederationCreationBlockHeightAndGetActiveFederationCreationBlockHe BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); // We store the value @@ -2573,7 +2575,7 @@ void setActiveFederationCreationBlockHeightAndGetActiveFederationCreationBlockHe BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); // And then we get it back @@ -2587,7 +2589,7 @@ void saveActiveFederationCreationBlockHeight_after_RSKIP186() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2608,7 +2610,7 @@ void saveActiveFederationCreationBlockHeight_before_RSKIP186() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); provider0.setActiveFederationCreationBlockHeight(10L); @@ -2628,7 +2630,7 @@ void getNextFederationCreationBlockHeight_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); assertEquals(Optional.empty(), provider0.getNextFederationCreationBlockHeight()); @@ -2645,7 +2647,7 @@ void getNextFederationCreationBlockHeight_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); assertEquals(Optional.of(1L), provider0.getNextFederationCreationBlockHeight()); @@ -2661,7 +2663,7 @@ void setNextFederationCreationBlockHeightAndGetNextFederationCreationBlockHeight BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); // We store the value @@ -2673,7 +2675,7 @@ void setNextFederationCreationBlockHeightAndGetNextFederationCreationBlockHeight BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); // And then we get it back @@ -2686,7 +2688,7 @@ void saveNextFederationCreationBlockHeight_after_RSKIP186() { BridgeStorageProvider provider1 = new BridgeStorageProvider( repository1, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); provider1.setNextFederationCreationBlockHeight(10L); @@ -2703,7 +2705,7 @@ void saveNextFederationCreationBlockHeight_after_RSKIP186() { BridgeStorageProvider provider2 = new BridgeStorageProvider( repository2, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); provider2.clearNextFederationCreationBlockHeight(); @@ -2735,7 +2737,7 @@ void isFlyoverFederationDerivationHashUsed_afterRSKIP176_returnTrue() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -2756,7 +2758,7 @@ void isFlyoverFederationDerivationHashUsed_beforeRSKIP176_returnFalse() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -2782,7 +2784,7 @@ void isFlyoverFederationDerivationHashUsed_storageReturnsNull_returnFalse() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -2808,7 +2810,7 @@ void isFlyoverFederationDerivationHashUsed_storageReturnsEmpty_returnFalse() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -2834,7 +2836,7 @@ void isFlyoverFederationDerivationHashUsed_storageReturnsWrongValue_returnFalse( BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -2848,7 +2850,7 @@ void saveNextFederationCreationBlockHeight_before_RSKIP186() { BridgeStorageProvider provider1 = new BridgeStorageProvider( repository1, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); provider1.setNextFederationCreationBlockHeight(10L); @@ -2865,7 +2867,7 @@ void saveNextFederationCreationBlockHeight_before_RSKIP186() { BridgeStorageProvider provider2 = new BridgeStorageProvider( repository2, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); provider2.clearNextFederationCreationBlockHeight(); @@ -2885,7 +2887,7 @@ void getLastRetiredFederationP2SHScript_before_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); assertEquals(Optional.empty(), provider0.getLastRetiredFederationP2SHScript()); @@ -2904,7 +2906,7 @@ void getLastRetiredFederationP2SHScript_after_fork() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); assertEquals(Optional.of(script), provider0.getLastRetiredFederationP2SHScript()); @@ -2921,7 +2923,7 @@ void setLastRetiredFederationP2SHScriptAndGetLastRetiredFederationP2SHScript() { BridgeStorageProvider provider0 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); // We store the value @@ -2933,7 +2935,7 @@ void setLastRetiredFederationP2SHScriptAndGetLastRetiredFederationP2SHScript() { BridgeStorageProvider provider = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); // And then we get it back @@ -2947,7 +2949,7 @@ void saveLastRetiredFederationP2SHScript_after_RSKIP186() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsAllForks ); @@ -2971,7 +2973,7 @@ void saveLastRetiredFederationP2SHScript_before_RSKIP186() { BridgeStorageProvider provider0 = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activationsBeforeFork ); @@ -3001,7 +3003,7 @@ void saveDerivationArgumentsScriptHash_afterRSKIP176_ok() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3028,7 +3030,7 @@ void saveDerivationArgumentsScriptHash_afterRSKIP176_nullBtcTxHash_notSaved() th BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3052,7 +3054,7 @@ void saveDerivationArgumentsScriptHash_afterRSKIP176_nullDerivationHash_notSaved BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3076,7 +3078,7 @@ void saveDerivationArgumentsScriptHash_beforeRSKIP176_ok() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3115,7 +3117,7 @@ void getFlyoverFederationInformation_afterRSKIP176_ok() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3151,7 +3153,7 @@ void getFlyoverFederationInformation_beforeRSKIP176_ok() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3176,7 +3178,7 @@ void getFlyoverFederationInformation_notFound() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3194,7 +3196,7 @@ void getFlyoverFederationInformation_nullParameter_returnEmpty() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3212,7 +3214,7 @@ void getFlyoverFederationInformation_arrayEmpty_returnEmpty() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3239,7 +3241,7 @@ void saveFlyoverFederationInformation_afterRSKIP176_ok() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3272,7 +3274,7 @@ void saveFlyoverFederationInformation_beforeRSKIP176_ok() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3305,7 +3307,7 @@ void saveFlyoverFederationInformation_alreadySet_dont_set_again() throws IOExcep BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3328,7 +3330,7 @@ void getReceiveHeadersLastTimestamp_before_RSKIP200() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); assertFalse(provider.getReceiveHeadersLastTimestamp().isPresent()); @@ -3345,7 +3347,7 @@ void getReceiveHeadersLastTimestamp_after_RSKIP200() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); Optional result = provider.getReceiveHeadersLastTimestamp(); @@ -3360,7 +3362,7 @@ void getReceiveHeadersLastTimestamp_not_in_repository() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); assertFalse(provider.getReceiveHeadersLastTimestamp().isPresent()); @@ -3372,7 +3374,7 @@ void saveReceiveHeadersLastTimestamp_before_RSKIP200() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); provider.setReceiveHeadersLastTimestamp(System.currentTimeMillis()); @@ -3391,7 +3393,7 @@ void saveReceiveHeadersLastTimestamp_after_RSKIP200() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); Long timeInMillis = System.currentTimeMillis(); @@ -3411,7 +3413,7 @@ void saveReceiveHeadersLastTimestamp_not_set() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); provider.save(); @@ -3428,7 +3430,7 @@ void getNextPegoutHeight_before_RSKIP271_activation() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); assertEquals(Optional.empty(), provider.getNextPegoutHeight()); @@ -3444,7 +3446,7 @@ void getNextPegoutHeight_after_RSKIP271_activation() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); assertEquals(Optional.of(1L), provider.getNextPegoutHeight()); @@ -3459,7 +3461,7 @@ void setNextPegoutHeightAndGetNextPegoutHeight_after_RSKIP271_activation() { BridgeStorageProvider provider1 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); provider1.setNextPegoutHeight(1L); @@ -3470,7 +3472,7 @@ void setNextPegoutHeightAndGetNextPegoutHeight_after_RSKIP271_activation() { BridgeStorageProvider provider2 = new BridgeStorageProvider( track, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); MatcherAssert.assertThat(provider2.getNextPegoutHeight(), is(Optional.of(1L))); @@ -3482,7 +3484,7 @@ void saveNextPegoutHeight_before_RSKIP271() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsBeforeFork + bridgeTestnetInstance, activationsBeforeFork ); provider.setNextPegoutHeight(10L); @@ -3501,7 +3503,7 @@ void saveNextPegoutHeight_after_RSKIP271() { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); provider.setNextPegoutHeight(10L); @@ -3563,7 +3565,7 @@ void saveNewFederationBtcUTXOs_no_data() throws IOException { BridgeStorageProvider provider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3602,7 +3604,7 @@ void getReleaseRequestQueueSize_when_releaseRequestQueue_is_null() throws IOExce BridgeStorageProvider storageProvider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); Assertions.assertEquals(0, storageProvider.getReleaseRequestQueueSize()); @@ -3614,7 +3616,7 @@ void getReleaseRequestQueueSize_when_releaseRequestQueue_is_not_null() throws IO BridgeStorageProvider storageProvider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - BridgeTestNetConstants.getInstance(), activationsAllForks + bridgeTestnetInstance, activationsAllForks ); ReleaseRequestQueue releaseRequestQueue = storageProvider.getReleaseRequestQueue(); @@ -3631,7 +3633,7 @@ void getReleaseRequestQueueSize_when_releaseRequestQueue_is_not_null() throws IO } private void testGetOldFederation(Federation oldFederation, ActivationConfig.ForBlock activations) { - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); BridgeStorageProvider storageProvider = new BridgeStorageProvider( @@ -3672,7 +3674,7 @@ private void testSaveOldFederation(Federation oldFederation, int version, Activa BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3721,7 +3723,7 @@ private void testSaveOldFederation(Federation oldFederation, int version, Activa private void testGetNewFederationPostMultiKey(Federation federation) { List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); - BridgeConstants bridgeConstants = BridgeTestNetConstants.getInstance(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), @@ -3763,7 +3765,7 @@ private void testSaveNewFederationPostMultiKey(Federation newFederation, int ver BridgeStorageProvider storageProvider = new BridgeStorageProvider( repositoryMock, mockAddress("aabbccdd"), - BridgeTestNetConstants.getInstance(), + bridgeTestnetInstance, activations ); @@ -3816,7 +3818,7 @@ private void testGetNewFederationBtcUTXOs(boolean isRskip284Active, boolean isRs BridgeConstants bridgeConstants = networkId.equals(NetworkParameters.ID_MAINNET) ? BridgeMainNetConstants.getInstance() : - BridgeTestNetConstants.getInstance(); + bridgeTestnetInstance; Repository repository = mock(Repository.class); List federationUtxos = Arrays.asList( @@ -3873,7 +3875,7 @@ private void testSaveNewFederationBtcUTXOs(boolean isRskip284Active, String netw BridgeConstants bridgeConstants = networkId.equals(NetworkParameters.ID_MAINNET) ? BridgeMainNetConstants.getInstance() : - BridgeTestNetConstants.getInstance(); + bridgeTestnetInstance; Repository repository = mock(Repository.class); List federationUtxos = Arrays.asList( @@ -3944,7 +3946,7 @@ private RskAddress mockAddress(String addr) { } private Address getBtcAddress(String addr) { - return new Address(BridgeTestNetConstants.getInstance().getBtcParams(), Hex.decode(addr)); + return new Address(networkParameters, Hex.decode(addr)); } private Federation buildMockFederation(Integer... pks) { @@ -3952,7 +3954,7 @@ private Federation buildMockFederation(Integer... pks) { FederationTestUtils.getFederationMembersFromPks(pks), Instant.ofEpochMilli(1000), 1, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + networkParameters ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index edf04ff8be6..f60bc1364d4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -94,7 +94,7 @@ private ErpFederation createDefaultLegacyErpFederation() { Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, networkParameters); + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); return new ErpFederation( standardMembers, diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index 25fea177902..c8fe619bf74 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -300,7 +300,7 @@ private void testBuildFederation( ); } else if (isRskip201Active) { ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); expectedFederation = new ErpFederation( FederationTestUtils.getFederationMembersFromPks(privateKeys), creationTime, diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index ce15fc262a4..9ef18fe3a71 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -136,8 +136,7 @@ private void testChangePowpeg( Federation originalPowpeg; switch (oldPowPegFederationType) { case legacyErp: - ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.defineNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); + ErpRedeemScriptBuilder erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); originalPowpeg = new ErpFederation( originalPowpegMembers, Instant.now(), From 398cdf6ec7b9a86dbe93a08d4cb86d99654b72b3 Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 23 Nov 2023 13:35:08 -0300 Subject: [PATCH 030/137] Add builders check to PowpegMigrationTest. Create getFederationDefaultP2SHScript and getFederationDefaultRedeemScript methods to avoid repetition --- .../java/co/rsk/peg/PowpegMigrationTest.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index 9ef18fe3a71..ba7e6374fa8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -204,16 +204,17 @@ private void testChangePowpeg( argumentCaptor.capture() ); - // TODO check this. maybe adding the FedType to the constructor solves it // Verify new powpeg information Federation newPowPeg = argumentCaptor.getValue(); assertEquals(newPowPegAddress, newPowPeg.getAddress()); switch (newPowPegFederationType) { case legacyErp: assertSame(ErpFederation.class, newPowPeg.getClass()); + assertTrue(((ErpFederation) newPowPeg).getErpRedeemScriptBuilder() instanceof NonStandardErpRedeemScriptBuilder); break; case p2shErp: assertSame(ErpFederation.class, newPowPeg.getClass()); + assertTrue(((ErpFederation) newPowPeg).getErpRedeemScriptBuilder() instanceof P2shErpRedeemScriptBuilder); // TODO: CHECK REDEEMSCRIPT break; default: @@ -606,14 +607,14 @@ private void testChangePowpeg( if (oldPowPegFederationType == FederationType.legacyErp || oldPowPegFederationType == FederationType.p2shErp){ assertNotEquals(lastRetiredFederationP2SHScript, originalPowpeg.getP2SHScript()); } - assertEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getDefaultP2SHScript() : originalPowpeg.getP2SHScript()); + assertEquals(lastRetiredFederationP2SHScript, getFederationDefaultP2SHScript(originalPowpeg)); } else { if (oldPowPegFederationType == FederationType.legacyErp || oldPowPegFederationType == FederationType.p2shErp){ assertEquals(lastRetiredFederationP2SHScript, originalPowpeg.getP2SHScript()); - assertNotEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getDefaultP2SHScript() : originalPowpeg.getP2SHScript()); + assertNotEquals(lastRetiredFederationP2SHScript, getFederationDefaultP2SHScript(originalPowpeg)); } else { assertEquals(lastRetiredFederationP2SHScript, originalPowpeg.getP2SHScript()); - assertEquals(lastRetiredFederationP2SHScript, originalPowpeg instanceof ErpFederation ? ((ErpFederation) originalPowpeg).getDefaultP2SHScript() : originalPowpeg.getP2SHScript()); + assertEquals(lastRetiredFederationP2SHScript, getFederationDefaultP2SHScript(originalPowpeg)); } } } @@ -645,10 +646,10 @@ private void verifyPegouts(BridgeStorageProvider bridgeStorageProvider) throws I Script inputStandardRedeemScript = RedeemScriptParserFactory.get(result.getChunks()).extractStandardRedeemScript(); Optional spendingFederationOptional = Optional.empty(); - if (inputStandardRedeemScript.equals(activeFederation instanceof ErpFederation ? ((ErpFederation) activeFederation).getDefaultRedeemScript() : activeFederation.getRedeemScript())) { + if (inputStandardRedeemScript.equals(getFederationDefaultRedeemScript(activeFederation))) { spendingFederationOptional = Optional.of(activeFederation); } else if (retiringFederation != null && - inputStandardRedeemScript.equals(retiringFederation instanceof ErpFederation ? ((ErpFederation) retiringFederation).getDefaultRedeemScript() : retiringFederation.getRedeemScript()) ) { + inputStandardRedeemScript.equals(getFederationDefaultRedeemScript(retiringFederation))) { spendingFederationOptional = Optional.of(retiringFederation); } else { fail("pegout scriptsig does not match any Federation"); @@ -1611,4 +1612,16 @@ private enum FederationType { p2shErp, standardMultisig } + + private static Script getFederationDefaultRedeemScript(Federation federation) { + return federation instanceof ErpFederation ? + ((ErpFederation) federation).getDefaultRedeemScript() : + federation.getRedeemScript(); + } + + private static Script getFederationDefaultP2SHScript(Federation federation) { + return federation instanceof ErpFederation ? + ((ErpFederation) federation).getDefaultP2SHScript() : + federation.getP2SHScript(); + } } From d1f59189690401e52b439e4495857a7fa114eea6 Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 24 Nov 2023 10:36:01 -0300 Subject: [PATCH 031/137] Modify getRedeemScriptParser method to not receive arguments. Refactor methods to make them cleaner. Make fields private in Legacy and P2sh tests. Remove TODO comment --- .../co/rsk/peg/BridgeSerializationUtils.java | 5 +---- .../java/co/rsk/peg/BridgeStorageProvider.java | 3 +-- .../src/main/java/co/rsk/peg/ErpFederation.java | 14 ++++++-------- .../main/java/co/rsk/peg/PendingFederation.java | 2 -- .../rsk/peg/BridgeSerializationUtilsTest.java | 6 +----- .../BridgeStorageProviderFederationTests.java | 2 -- .../co/rsk/peg/BridgeStorageProviderTest.java | 10 ---------- .../test/java/co/rsk/peg/BridgeSupportTest.java | 3 --- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 3 --- ...yoverCompatibleBtcWalletWithStorageTest.java | 5 ----- ...ompatibleBtcWallextWithSingleScriptTest.java | 6 ------ .../co/rsk/peg/LegacyErpFederationTest.java | 17 ++++++----------- .../java/co/rsk/peg/P2shErpFederationTest.java | 9 ++------- .../java/co/rsk/peg/PendingFederationTest.java | 2 -- .../java/co/rsk/peg/PowpegMigrationTest.java | 2 -- .../rsk/peg/ReleaseTransactionBuilderTest.java | 1 - 16 files changed, 17 insertions(+), 73 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 474797da1e9..5b082805570 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -335,15 +335,13 @@ public static ErpFederation deserializeLegacyErpFederation( federation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, erpRedeemScriptBuilder ); } public static ErpFederation deserializeP2shErpFederation( byte[] data, - BridgeConstants bridgeConstants, - ActivationConfig.ForBlock activations + BridgeConstants bridgeConstants ) { Federation federation = deserializeStandardMultisigFederationWithDeserializer( data, @@ -357,7 +355,6 @@ public static ErpFederation deserializeP2shErpFederation( federation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index b00e0f10aeb..d6350a056f1 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -1098,8 +1098,7 @@ private Federation deserializeFederationAccordingToVersion( case P2SH_ERP_FEDERATION_FORMAT_VERSION: return BridgeSerializationUtils.deserializeP2shErpFederation( data, - bridgeConstants, - activations + bridgeConstants ); case STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION: return BridgeSerializationUtils.deserializeStandardMultisigFederation( diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java index e2b3e8722fd..04a1e2be7b8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java @@ -11,14 +11,12 @@ import java.time.Instant; import java.util.Collections; import java.util.List; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; public class ErpFederation extends Federation { private final List erpPubKeys; private final long activationDelay; - private final ActivationConfig.ForBlock activations; private Script defaultRedeemScript; private Script defaultP2SHScript; private ErpRedeemScriptBuilder erpRedeemScriptBuilder; @@ -30,7 +28,6 @@ protected ErpFederation( NetworkParameters btcParams, List erpPubKeys, long activationDelay, - ActivationConfig.ForBlock activations, ErpRedeemScriptBuilder erpRedeemScriptBuilder) { super(members, creationTime, creationBlockNumber, btcParams); @@ -38,7 +35,6 @@ protected ErpFederation( this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpPubKeys); this.activationDelay = activationDelay; - this.activations = activations; this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; } @@ -66,8 +62,8 @@ public long getActivationDelay() { public Script getDefaultRedeemScript() { if (defaultRedeemScript == null) { - defaultRedeemScript = getRedeemScriptParser(getRedeemScript()) - .extractStandardRedeemScript(); + RedeemScriptParser redeemScriptParser = getRedeemScriptParser(); + defaultRedeemScript = redeemScriptParser.extractStandardRedeemScript(); } return defaultRedeemScript; } @@ -86,14 +82,16 @@ public Script getRedeemScript() { return redeemScript; } - private RedeemScriptParser getRedeemScriptParser(Script redeemScript) { + private RedeemScriptParser getRedeemScriptParser() { + Script redeemScript = getRedeemScript(); List chunks = redeemScript.getChunks(); return RedeemScriptParserFactory.get(chunks); } public Script getDefaultP2SHScript() { if (defaultP2SHScript == null) { - defaultP2SHScript = ScriptBuilder.createP2SHOutputScript(getDefaultRedeemScript()); + defaultP2SHScript = ScriptBuilder + .createP2SHOutputScript(getDefaultRedeemScript()); } return defaultP2SHScript; diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java index 779bac905dd..49d49fdc532 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java @@ -113,7 +113,6 @@ public Federation buildFederation( bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); } @@ -131,7 +130,6 @@ public Federation buildFederation( bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, erpRedeemScriptBuilder ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 5bd4ce214de..e27168946c7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -1220,7 +1220,6 @@ void deserializeCoinbaseInformation_dataIsValid_returnsValidCoinbaseInformation( Assertions.assertEquals(witnessRoot, BridgeSerializationUtils.deserializeCoinbaseInformation(serializedCoinbaseInformation).getWitnessMerkleRoot()); } - // TODO split this test? private void testSerializeAndDeserializeFederation( boolean isRskip284Active, boolean isRskip353Active, @@ -1270,7 +1269,6 @@ private void testSerializeAndDeserializeFederation( bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, erpRedeemScriptBuilder ); byte[] serializedTestErpFederation = BridgeSerializationUtils.serializeFederation(testErpFederation); @@ -1298,15 +1296,13 @@ private void testSerializeAndDeserializeFederation( bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); byte[] serializedTestP2shErpFederation = BridgeSerializationUtils.serializeFederation(testP2shErpFederation); Federation deserializedTestP2shErpFederation = BridgeSerializationUtils.deserializeP2shErpFederation( serializedTestP2shErpFederation, - bridgeConstants, - activations + bridgeConstants ); assertEquals(testP2shErpFederation, deserializedTestP2shErpFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index b2a964169b7..d0e06bf29f5 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -611,7 +611,6 @@ private Federation createFederation(int version) { bridgeConstantsRegtest.getBtcParams(), bridgeConstantsRegtest.getErpFedPubKeysList(), bridgeConstantsRegtest.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); case LEGACY_ERP_FEDERATION_FORMAT_VERSION: @@ -624,7 +623,6 @@ private Federation createFederation(int version) { bridgeConstantsRegtest.getBtcParams(), bridgeConstantsRegtest.getErpFedPubKeysList(), bridgeConstantsRegtest.getErpFedActivationDelay(), - activations, erpRedeemScriptBuilder ); default: diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 3e279125e45..e4fd0fc4082 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -411,7 +411,6 @@ void getNewFederation_erp_fed() { newFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - mock(ActivationConfig.ForBlock.class), new NonStandardErpRedeemScriptBuilderHardcoded() ); @@ -428,7 +427,6 @@ void getNewFederation_p2sh_erp_fed() { newFederation.getBtcParams(), bridgeTestnetInstance.getErpFedPubKeysList(), bridgeTestnetInstance.getErpFedActivationDelay(), - mock(ActivationConfig.ForBlock.class), new P2shErpRedeemScriptBuilder() ); @@ -557,7 +555,6 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { newFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new NonStandardErpRedeemScriptBuilder() ); @@ -580,7 +577,6 @@ void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { newFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); @@ -700,7 +696,6 @@ void getOldFederation_nonStandardHardcoaded_fed() { oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new NonStandardErpRedeemScriptBuilderHardcoded() ); @@ -724,7 +719,6 @@ void getOldFederation_nonStandardWithUnsignedBE_fed() { oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() ); @@ -749,7 +743,6 @@ void getOldFederation_nonStandard_fed() { oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new NonStandardErpRedeemScriptBuilder() ); @@ -769,7 +762,6 @@ void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); @@ -892,7 +884,6 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new NonStandardErpRedeemScriptBuilder() ); @@ -913,7 +904,6 @@ void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); 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 82c8f720411..f3e89396d04 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -6569,7 +6569,6 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - preRSKIP271_activations, new P2shErpRedeemScriptBuilder() ); @@ -6638,7 +6637,6 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - preRSKIP385_activations, new P2shErpRedeemScriptBuilder() ); @@ -6706,7 +6704,6 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - postRSKIP385_activations, new P2shErpRedeemScriptBuilder() ); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index 477eb393199..a91e3488e8f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -1053,7 +1053,6 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs_erpFederation() { networkParameters, erpFederationPublicKeys, 500L, - activations, new NonStandardErpRedeemScriptBuilder() ); @@ -1098,7 +1097,6 @@ void testCalculatePegoutTxSize_100Inputs_50Outputs_erpFederation() { networkParameters, erpFederationPublicKeys, 500L, - activations, new NonStandardErpRedeemScriptBuilder() ); @@ -1430,7 +1428,6 @@ private ErpFederation createErpFederation() { genesisFederation.getBtcParams(), bridgeConstantsRegtest.getErpFedPubKeysList(), bridgeConstantsRegtest.getErpFedActivationDelay(), - activations, new NonStandardErpRedeemScriptBuilder() ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java index 25b1fbab413..c4db256196b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java @@ -22,8 +22,6 @@ import java.util.Optional; import java.util.stream.Collectors; import org.bouncycastle.util.encoders.Hex; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -42,8 +40,6 @@ class FlyoverCompatibleBtcWalletWithStorageTest { @BeforeEach void setup() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); federation = new StandardMultisigFederation( FederationTestUtils.getFederationMembers(3), @@ -59,7 +55,6 @@ void setup() { NetworkParameters.fromID(NetworkParameters.ID_REGTEST), erpFedKeys, 5063, - activations, new NonStandardErpRedeemScriptBuilder() ); diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java index 956b9933efd..6dbae5d118c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java @@ -1,7 +1,6 @@ package co.rsk.peg; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Context; @@ -18,8 +17,6 @@ import java.util.List; import java.util.stream.Collectors; import org.bouncycastle.util.encoders.Hex; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -38,8 +35,6 @@ class FlyoverCompatibleBtcWallextWithSingleScriptTest { @BeforeEach void setup() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); federation = new StandardMultisigFederation( FederationTestUtils.getFederationMembers(3), @@ -55,7 +50,6 @@ void setup() { NetworkParameters.fromID(NetworkParameters.ID_REGTEST), erpFedKeys, 5063, - activations, new NonStandardErpRedeemScriptBuilder() ); diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index f60bc1364d4..a823178f372 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -50,9 +50,9 @@ class LegacyErpFederationTest { private ErpFederation federation; private NetworkParameters networkParameters; private List standardKeys; - int defaultThreshold; + private int defaultThreshold; private List emergencyKeys; - int emergencyThreshold; + private int emergencyThreshold; private long activationDelayValue; private ActivationConfig.ForBlock activations; private ErpRedeemScriptBuilder erpRedeemScriptBuilder; @@ -103,7 +103,6 @@ private ErpFederation createDefaultLegacyErpFederation() { networkParameters, emergencyKeys, activationDelayValue, - activations, erpRedeemScriptBuilder ); } @@ -216,7 +215,7 @@ void testEquals_same() { federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - activations, + erpRedeemScriptBuilder ); assertEquals(federation, otherFederation); @@ -231,7 +230,7 @@ void testEquals_differentCreationTime() { federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - activations, + erpRedeemScriptBuilder ); assertEquals(federation, otherFederation); @@ -246,7 +245,7 @@ void testEquals_differentCreationBlockNumber() { federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - activations, + erpRedeemScriptBuilder ); assertEquals(federation, otherFederation); @@ -367,7 +366,7 @@ void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { NetworkParameters.fromID(NetworkParameters.ID_TESTNET), generatedScript.emergencyFed, generatedScript.timelock, - activations, + erpRedeemScriptBuilder ); @@ -453,7 +452,6 @@ void getRedeemScript_before_RSKIP_284_testnet() { NetworkParameters.fromID(NetworkParameters.ID_TESTNET), emergencyKeys, activationDelayValue, - activations, new NonStandardErpRedeemScriptBuilderHardcoded() ); @@ -484,7 +482,6 @@ void getRedeemScript_after_RSKIP_284_testnet() { NetworkParameters.fromID(NetworkParameters.ID_TESTNET), emergencyKeys, activationDelayValue, - activations, new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() ); @@ -505,7 +502,6 @@ void getRedeemScript_after_RSKIP_284_mainnet() { NetworkParameters.fromID(NetworkParameters.ID_MAINNET), emergencyKeys, activationDelayValue, - activations, new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() ); @@ -578,7 +574,6 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { btcParams, emergencyMultisigKeys, activationDelay, - activations, new NonStandardErpRedeemScriptBuilder() )); } diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index dc558bf278a..a67393b6ff7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -44,9 +44,9 @@ class P2shErpFederationTest { private ErpFederation federation; private NetworkParameters networkParameters; private List standardKeys; - int defaultThreshold; + private int defaultThreshold; private List emergencyKeys; - int emergencyThreshold; + private int emergencyThreshold; private long activationDelayValue; private ActivationConfig.ForBlock activations; @@ -92,7 +92,6 @@ private ErpFederation createDefaultP2shErpFederation() { networkParameters, emergencyKeys, activationDelayValue, - activations, new P2shErpRedeemScriptBuilder() ); } @@ -208,7 +207,6 @@ void testEquals_same() { federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - activations, p2shErpRedeemScriptBuilder ); @@ -296,7 +294,6 @@ void getStandardRedeemScript() { btcParams, Arrays.asList(new BtcECKey(), new BtcECKey()), 10_000, - activations, new P2shErpRedeemScriptBuilder() ); @@ -413,7 +410,6 @@ void getErpRedeemScript_compareOtherImplementation_P2SHERPFederation() throws IO NetworkParameters.fromID(NetworkParameters.ID_TESTNET), generatedScript.emergencyFed, generatedScript.timelock, - activations, new P2shErpRedeemScriptBuilder() ); @@ -448,7 +444,6 @@ void spendFromP2shErpFed( networkParameters, emergencyKeys, activationDelay, - mock(ActivationConfig.ForBlock.class), new P2shErpRedeemScriptBuilder() ); diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index c8fe619bf74..d8f7ddc1e8d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -295,7 +295,6 @@ private void testBuildFederation( bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); } else if (isRskip201Active) { @@ -308,7 +307,6 @@ private void testBuildFederation( bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, erpRedeemScriptBuilder ); } else { diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index ba7e6374fa8..30f107fa36c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -144,7 +144,6 @@ private void testChangePowpeg( bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, erpRedeemScriptBuilder ); break; @@ -156,7 +155,6 @@ private void testChangePowpeg( bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new P2shErpRedeemScriptBuilder() ); // TODO: CHECK REDEEMSCRIPT diff --git a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java index 17057a002a2..5618def0c6a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java @@ -175,7 +175,6 @@ void build_pegout_tx_from_erp_federation() { bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - activations, new NonStandardErpRedeemScriptBuilder() ); From 4555c9ababdfff1bb003a974e23532877e79448d Mon Sep 17 00:00:00 2001 From: julia zack Date: Mon, 27 Nov 2023 17:16:52 -0300 Subject: [PATCH 032/137] Add tests for erp redeem script builder utils. Replace isSentToMultiSig check for isSentToStandardMultiSig in builder utils. --- .../rsk/peg/ErpRedeemScriptBuilderUtils.java | 2 +- .../peg/ErpRedeemScriptBuilderUtilsTest.java | 260 ++++++++++++++++++ 2 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 rskj-core/src/test/java/co/rsk/peg/ErpRedeemScriptBuilderUtilsTest.java diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java index 1b86a390533..ce37dd2fd9e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java @@ -26,7 +26,7 @@ public static void validateRedeemScriptValues( Script erpFederationRedeemScript, Long csvValue ) { - if (!defaultFederationRedeemScript.isSentToMultiSig() || !erpFederationRedeemScript.isSentToMultiSig()) { + if (!defaultFederationRedeemScript.isSentToStandardMultiSig() || !erpFederationRedeemScript.isSentToStandardMultiSig()) { String message = "Provided redeem scripts have an invalid structure, not standard"; logger.debug( diff --git a/rskj-core/src/test/java/co/rsk/peg/ErpRedeemScriptBuilderUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/ErpRedeemScriptBuilderUtilsTest.java new file mode 100644 index 00000000000..bd1fd7eaad8 --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/peg/ErpRedeemScriptBuilderUtilsTest.java @@ -0,0 +1,260 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.script.Script; +import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.bitcoinj.script.ScriptChunk; +import co.rsk.config.BridgeConstants; +import co.rsk.config.BridgeMainNetConstants; +import org.bouncycastle.util.encoders.Hex; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.Arrays; +import java.util.List; + +import static co.rsk.bitcoinj.script.ScriptOpCodes.OP_CHECKMULTISIG; +import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; +import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_INTERNAL_REDEEM_SCRIPTS; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ErpRedeemScriptBuilderUtilsTest { + private List defaultKeys; + private int defaultThreshold; + private List emergencyKeys; + private int emergencyThreshold; + private long activationDelayValue; + @BeforeEach + void setup() { + BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); + + BtcECKey federator0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("03b53899c390573471ba30e5054f78376c5f797fda26dde7a760789f02908cbad2")); + BtcECKey federator1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("027319afb15481dbeb3c426bcc37f9a30e7f51ceff586936d85548d9395bcc2344")); + BtcECKey federator2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0355a2e9bf100c00fc0a214afd1bf272647c7824eb9cb055480962f0c382596a70")); + BtcECKey federator3PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02566d5ded7c7db1aa7ee4ef6f76989fb42527fcfdcddcd447d6793b7d869e46f7")); + BtcECKey federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0294c817150f78607566e961b3c71df53a22022a80acbb982f83c0c8baac040adc")); + defaultKeys = Arrays.asList( + federator0PublicKey, federator1PublicKey, federator2PublicKey, + federator3PublicKey, federator4PublicKey + ); + defaultThreshold = defaultKeys.size() / 2 + 1; + emergencyKeys = bridgeConstants.getErpFedPubKeysList(); + emergencyThreshold = emergencyKeys.size() / 2 + 1; + activationDelayValue = bridgeConstants.getErpFedActivationDelay(); + } + + @Test + void removeOpCheckMultiSig() { + Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); + List defaultScriptWithOpCheckMultiSigRemovedChunks = ErpRedeemScriptBuilderUtils.removeOpCheckMultisig(defaultScript); + + Script defaultScriptWithoutOpCheckMultiSig = createMultiSigScriptWithoutOpCheckMultisig(defaultKeys, defaultThreshold); + List defaultScriptWithoutOpCheckMultiSigChunks = defaultScriptWithoutOpCheckMultiSig.getChunks(); + + assertEquals(defaultScriptWithOpCheckMultiSigRemovedChunks, defaultScriptWithoutOpCheckMultiSigChunks); + } + + @ParameterizedTest + @ValueSource(longs = {-100L, 0L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1}) + void createInvalidErpFederation_invalidCsvValues(long csvValue) { + activationDelayValue = csvValue; + + Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); + Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_CSV_VALUE, exception.getReason()); + } + + @Test + void createValidErpFederation_exactMaxCsvValue() { + Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); + Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); + + activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE; + assertDoesNotThrow( + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + } + + @Test + void createInvalidErpFederation_invalidDefaultRedeemScript_withoutThreshold() { + Script defaultScript = createMultiSigScriptWithoutThreshold(defaultKeys); + Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); + } + + @Test + void createInvalidErpFederation_invalidEmergencyRedeemScript_withoutThreshold() { + Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); + Script emergencyScript = createMultiSigScriptWithoutThreshold(emergencyKeys); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); + } + + @Test + void createInvalidErpFederation_invalidDefaultRedeemScript_withZeroThreshold() { + Script defaultScript = createMultiSigScript(defaultKeys, 0); + Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); + } + + @Test + void createInvalidErpFederation_invalidEmergencyRedeemScript_withZeroThreshold() { + Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); + Script emergencyScript = createMultiSigScript(emergencyKeys, 0); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); + } + + @Test + void createInvalidErpFederation_invalidDefaultRedeemScript_withoutKeysSize() { + Script defaultScript = createMultiSigScriptWithoutKeysSize(defaultKeys, defaultThreshold); + Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); + } + + @Test + void createInvalidErpFederation_invalidEmergencyRedeemScript_withoutKeysSize() { + Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); + Script emergencyScript = createMultiSigScriptWithoutKeysSize(emergencyKeys, emergencyThreshold); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); + } + + @Test + void createInvalidErpFederation_invalidDefaultRedeemScript_withoutOpCheckMultisig() { + Script defaultScript = createMultiSigScriptWithoutOpCheckMultisig(defaultKeys, defaultThreshold); + Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); + } + + @Test + void createInvalidErpFederation_invalidEmergencyRedeemScript_withoutOpCheckMultisig() { + Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); + Script emergencyScript = createMultiSigScriptWithoutOpCheckMultisig(emergencyKeys, emergencyThreshold); + + ErpFederationCreationException exception = assertThrows( + ErpFederationCreationException.class, + () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( + defaultScript, + emergencyScript, + activationDelayValue) + ); + assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); + } + + private Script createMultiSigScript(List keys, + int threshold) { + ScriptBuilder scriptBuilder = new ScriptBuilder(); + scriptBuilder.smallNum(threshold); + for (BtcECKey key : keys) { + scriptBuilder.data(key.getPubKey()); + } + scriptBuilder.smallNum(keys.size()); + scriptBuilder.op(OP_CHECKMULTISIG); + + return scriptBuilder.build(); + } + + private Script createMultiSigScriptWithoutThreshold(List keys) { + ScriptBuilder scriptBuilder = new ScriptBuilder(); + for (BtcECKey key : keys) { + scriptBuilder.data(key.getPubKey()); + } + scriptBuilder.smallNum(keys.size()); + scriptBuilder.op(OP_CHECKMULTISIG); + + return scriptBuilder.build(); + } + + private Script createMultiSigScriptWithoutKeysSize(List keys, + int threshold) { + ScriptBuilder scriptBuilder = new ScriptBuilder(); + scriptBuilder.smallNum(threshold); + for (BtcECKey key : keys) { + scriptBuilder.data(key.getPubKey()); + } + scriptBuilder.op(OP_CHECKMULTISIG); + + return scriptBuilder.build(); + } + + private Script createMultiSigScriptWithoutOpCheckMultisig(List keys, + int threshold) { + ScriptBuilder scriptBuilder = new ScriptBuilder(); + scriptBuilder.smallNum(threshold); + for (BtcECKey key : keys) { + scriptBuilder.data(key.getPubKey()); + } + scriptBuilder.smallNum(keys.size()); + + return scriptBuilder.build(); + } +} From cd71f1b29d80de8d18ee1da72627130a749e4e96 Mon Sep 17 00:00:00 2001 From: julia zack Date: Tue, 28 Nov 2023 17:28:57 -0300 Subject: [PATCH 033/137] Move builders related classes to bitcoin package and create RedeemScriptCreationException class to avoid circular dependency with peg package --- .../co/rsk/peg/BridgeSerializationUtils.java | 3 + .../co/rsk/peg/BridgeStorageProvider.java | 2 + .../main/java/co/rsk/peg/ErpFederation.java | 8 +- .../peg/ErpFederationCreationException.java | 4 +- ...StandardErpRedeemScriptBuilderFactory.java | 34 -- .../java/co/rsk/peg/PendingFederation.java | 3 + .../rsk/peg/StandardMultisigFederation.java | 1 + .../{ => bitcoin}/ErpRedeemScriptBuilder.java | 2 +- .../ErpRedeemScriptBuilderUtils.java | 10 +- .../NonStandardErpRedeemScriptBuilder.java | 4 +- ...StandardErpRedeemScriptBuilderFactory.java | 28 ++ ...andardErpRedeemScriptBuilderHardcoded.java | 2 +- ...pRedeemScriptBuilderWithCsvUnsignedBE.java | 4 +- .../P2shErpRedeemScriptBuilder.java | 2 +- .../RedeemScriptCreationException.java | 17 + .../ScriptCreationException.java | 2 +- .../peg/{ => bitcoin}/ScriptValidations.java | 6 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 3 + .../BridgeStorageProviderFederationTests.java | 3 + .../co/rsk/peg/BridgeStorageProviderTest.java | 3 +- .../java/co/rsk/peg/BridgeSupportTest.java | 1 + .../test/java/co/rsk/peg/BridgeUtilsTest.java | 2 + ...verCompatibleBtcWalletWithStorageTest.java | 1 + ...patibleBtcWallextWithSingleScriptTest.java | 1 + ...ava => NonStandardErpFederationsTest.java} | 432 +++++++++++------- .../co/rsk/peg/P2shErpFederationTest.java | 223 +++++---- .../co/rsk/peg/PendingFederationTest.java | 3 + .../java/co/rsk/peg/PowpegMigrationTest.java | 11 +- .../peg/ReleaseTransactionBuilderTest.java | 2 + .../peg/StandardMultisigFederationTest.java | 3 +- 30 files changed, 507 insertions(+), 313 deletions(-) delete mode 100644 rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java rename rskj-core/src/main/java/co/rsk/peg/{ => bitcoin}/ErpRedeemScriptBuilder.java (93%) rename rskj-core/src/main/java/co/rsk/peg/{ => bitcoin}/ErpRedeemScriptBuilderUtils.java (80%) rename rskj-core/src/main/java/co/rsk/peg/{ => bitcoin}/NonStandardErpRedeemScriptBuilder.java (95%) create mode 100644 rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java rename rskj-core/src/main/java/co/rsk/peg/{ => bitcoin}/NonStandardErpRedeemScriptBuilderHardcoded.java (98%) rename rskj-core/src/main/java/co/rsk/peg/{ => bitcoin}/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java (95%) rename rskj-core/src/main/java/co/rsk/peg/{ => bitcoin}/P2shErpRedeemScriptBuilder.java (98%) create mode 100644 rskj-core/src/main/java/co/rsk/peg/bitcoin/RedeemScriptCreationException.java rename rskj-core/src/main/java/co/rsk/peg/{ => bitcoin}/ScriptCreationException.java (94%) rename rskj-core/src/main/java/co/rsk/peg/{ => bitcoin}/ScriptValidations.java (81%) rename rskj-core/src/test/java/co/rsk/peg/{LegacyErpFederationTest.java => NonStandardErpFederationsTest.java} (64%) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 5b082805570..c0f39c45d98 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -24,6 +24,9 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.CoinbaseInformation; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.whitelist.OneOffWhiteListEntry; import co.rsk.peg.whitelist.UnlimitedWhiteListEntry; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index d6350a056f1..9c203405054 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -24,6 +24,8 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.CoinbaseInformation; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.whitelist.LockWhitelist; import co.rsk.peg.whitelist.LockWhitelistEntry; diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java index 04a1e2be7b8..08c0509acfd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java @@ -7,12 +7,15 @@ import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.script.ScriptChunk; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.RedeemScriptCreationException; import co.rsk.peg.utils.EcKeyUtils; import java.time.Instant; import java.util.Collections; import java.util.List; import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; +import static co.rsk.peg.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; public class ErpFederation extends Federation { private final List erpPubKeys; @@ -51,7 +54,6 @@ public List getErpPubKeys() { return Collections.unmodifiableList(erpPubKeys); } - public int getNumberOfEmergencySignaturesRequired() { return erpPubKeys.size() / 2 + 1; } @@ -71,6 +73,7 @@ public Script getDefaultRedeemScript() { @Override public Script getRedeemScript() { if (redeemScript == null) { + try { redeemScript = erpRedeemScriptBuilder.createRedeemScriptFromKeys( getBtcPublicKeys(), getNumberOfSignaturesRequired(), @@ -78,6 +81,9 @@ public Script getRedeemScript() { getNumberOfEmergencySignaturesRequired(), activationDelay ); + } catch (RedeemScriptCreationException e) { + throw new ErpFederationCreationException(e.getMessage(), e, REDEEM_SCRIPT_CREATION_FAILED); + } } return redeemScript; } diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java b/rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java index 9ae499a02eb..ce40ccbf24b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java +++ b/rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java @@ -9,9 +9,7 @@ public class ErpFederationCreationException extends RuntimeException { public enum Reason { NULL_OR_EMPTY_EMERGENCY_KEYS, - INVALID_INTERNAL_REDEEM_SCRIPTS, - INVALID_CSV_VALUE, - HARDCODED_LEGACY_ERP_TESTNET_REDEEM_SCRIPT + REDEEM_SCRIPT_CREATION_FAILED } public ErpFederationCreationException(String s, Reason reason) { diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java b/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java deleted file mode 100644 index 190b071fdc4..00000000000 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactory.java +++ /dev/null @@ -1,34 +0,0 @@ -package co.rsk.peg; - -import co.rsk.bitcoinj.core.NetworkParameters; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; - -public class NonStandardErpRedeemScriptBuilderFactory { - - private NonStandardErpRedeemScriptBuilderFactory() { - } - - public static ErpRedeemScriptBuilder getNonStandardErpRedeemScriptBuilder( - ActivationConfig.ForBlock activations, - NetworkParameters networkParameters) { - - ErpRedeemScriptBuilder erpRedeemScriptBuilder; - - boolean networkIsTestnet = checkIfNetworkIsTestnet(networkParameters); - - if(!activations.isActive(ConsensusRule.RSKIP284) && networkIsTestnet) { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderHardcoded(); - } else if (!activations.isActive(ConsensusRule.RSKIP293)) { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); - } else { - erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); - } - - return erpRedeemScriptBuilder; - } - - private static boolean checkIfNetworkIsTestnet(NetworkParameters networkParameters) { - return networkParameters.getId().equals(NetworkParameters.ID_TESTNET); - } -} diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java index 49d49fdc532..89e51da2436 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java @@ -21,6 +21,9 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.config.BridgeConstants; import co.rsk.crypto.Keccak256; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.crypto.HashUtil; diff --git a/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java b/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java index c628d3bd0dc..3ccb9f2a28e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java @@ -21,6 +21,7 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.peg.bitcoin.ScriptValidations; import java.time.Instant; import java.util.List; diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilder.java similarity index 93% rename from rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java rename to rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilder.java index 2e938e60be2..cc15f0bd9a9 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilder.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.bitcoin; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.script.Script; diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilderUtils.java similarity index 80% rename from rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java rename to rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilderUtils.java index ce37dd2fd9e..8fbbf096a57 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpRedeemScriptBuilderUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilderUtils.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.bitcoin; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptChunk; @@ -7,8 +7,8 @@ import java.util.List; -import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_INTERNAL_REDEEM_SCRIPTS; -import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; +import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_CSV_VALUE; +import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_INTERNAL_REDEEM_SCRIPTS; public class ErpRedeemScriptBuilderUtils { private static final Logger logger = LoggerFactory.getLogger(ErpRedeemScriptBuilderUtils.class); @@ -35,7 +35,7 @@ public static void validateRedeemScriptValues( defaultFederationRedeemScript, erpFederationRedeemScript ); - throw new ErpFederationCreationException(message, INVALID_INTERNAL_REDEEM_SCRIPTS); + throw new RedeemScriptCreationException(message, INVALID_INTERNAL_REDEEM_SCRIPTS); } if (csvValue <= 0 || csvValue > MAX_CSV_VALUE) { @@ -45,7 +45,7 @@ public static void validateRedeemScriptValues( MAX_CSV_VALUE ); logger.warn("[validateRedeemScriptValues] {}", message); - throw new ErpFederationCreationException(message, INVALID_CSV_VALUE); + throw new RedeemScriptCreationException(message, INVALID_CSV_VALUE); } } } diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilder.java similarity index 95% rename from rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java rename to rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilder.java index 778acc62d06..8079926dfb7 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilder.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.bitcoin; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Utils; @@ -8,7 +8,7 @@ import java.util.List; -import static co.rsk.peg.ErpRedeemScriptBuilderUtils.removeOpCheckMultisig; +import static co.rsk.peg.bitcoin.ErpRedeemScriptBuilderUtils.removeOpCheckMultisig; public class NonStandardErpRedeemScriptBuilder implements ErpRedeemScriptBuilder { private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilder.class); diff --git a/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java new file mode 100644 index 00000000000..bd8e197b1e4 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java @@ -0,0 +1,28 @@ +package co.rsk.peg.bitcoin; + +import co.rsk.bitcoinj.core.NetworkParameters; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; + +public class NonStandardErpRedeemScriptBuilderFactory { + + private NonStandardErpRedeemScriptBuilderFactory() { + } + + public static ErpRedeemScriptBuilder getNonStandardErpRedeemScriptBuilder( + ActivationConfig.ForBlock activations, + NetworkParameters networkParameters) { + + if (networkIsTestnet(networkParameters) && !activations.isActive(ConsensusRule.RSKIP284)) { + return new NonStandardErpRedeemScriptBuilderHardcoded(); + } + if (!activations.isActive(ConsensusRule.RSKIP293)) { + return new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); + } + return new NonStandardErpRedeemScriptBuilder(); + } + + private static boolean networkIsTestnet(NetworkParameters networkParameters) { + return networkParameters.getId().equals(NetworkParameters.ID_TESTNET); + } +} \ No newline at end of file diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoded.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderHardcoded.java similarity index 98% rename from rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoded.java rename to rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderHardcoded.java index cd636e77c94..7e2f517f51b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderHardcoded.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderHardcoded.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.bitcoin; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.script.Script; diff --git a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java similarity index 95% rename from rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java rename to rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java index 2ffcb370101..c70d9c25c6a 100644 --- a/rskj-core/src/main/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.bitcoin; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Utils; @@ -10,7 +10,7 @@ import java.util.List; -import static co.rsk.peg.ErpRedeemScriptBuilderUtils.removeOpCheckMultisig; +import static co.rsk.peg.bitcoin.ErpRedeemScriptBuilderUtils.removeOpCheckMultisig; public class NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE implements ErpRedeemScriptBuilder { private static final Logger logger = LoggerFactory.getLogger(NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE.class); diff --git a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/P2shErpRedeemScriptBuilder.java similarity index 98% rename from rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java rename to rskj-core/src/main/java/co/rsk/peg/bitcoin/P2shErpRedeemScriptBuilder.java index efc21bfd744..42c3bf6ad7c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/P2shErpRedeemScriptBuilder.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/P2shErpRedeemScriptBuilder.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.bitcoin; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Utils; diff --git a/rskj-core/src/main/java/co/rsk/peg/bitcoin/RedeemScriptCreationException.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/RedeemScriptCreationException.java new file mode 100644 index 00000000000..ba90caa3a5e --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/RedeemScriptCreationException.java @@ -0,0 +1,17 @@ +package co.rsk.peg.bitcoin; + +public class RedeemScriptCreationException extends RuntimeException { + private final Reason reason; + + public enum Reason { + INVALID_INTERNAL_REDEEM_SCRIPTS, + INVALID_CSV_VALUE + } + + public RedeemScriptCreationException(String s, Reason reason) { + super(s); + this.reason = reason; + } + + public Reason getReason() { return reason; } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/ScriptCreationException.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ScriptCreationException.java similarity index 94% rename from rskj-core/src/main/java/co/rsk/peg/ScriptCreationException.java rename to rskj-core/src/main/java/co/rsk/peg/bitcoin/ScriptCreationException.java index ba0fc2d8d43..16bffeae159 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ScriptCreationException.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ScriptCreationException.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.bitcoin; public class ScriptCreationException extends RuntimeException { private final Reason reason; diff --git a/rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ScriptValidations.java similarity index 81% rename from rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java rename to rskj-core/src/main/java/co/rsk/peg/bitcoin/ScriptValidations.java index dfe16068133..83164e9a687 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ScriptValidations.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ScriptValidations.java @@ -1,13 +1,13 @@ -package co.rsk.peg; +package co.rsk.peg.bitcoin; import co.rsk.bitcoinj.script.Script; -import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; public class ScriptValidations { private ScriptValidations() { } - public static void validateScriptSize(Script script) throws ErpFederationCreationException { + public static void validateScriptSize(Script script) throws ScriptCreationException { // Check if the size of the script does not exceed the maximum size allowed int bytesFromScript = script.getProgram().length; if (bytesFromScript > Script.MAX_SCRIPT_ELEMENT_SIZE) { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index e27168946c7..32dd0f5ae49 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -26,6 +26,9 @@ import co.rsk.config.BridgeTestNetConstants; import co.rsk.core.RskAddress; import co.rsk.peg.bitcoin.CoinbaseInformation; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.resources.TestConstants; import co.rsk.peg.utils.MerkleTreeUtils; import co.rsk.peg.flyover.FlyoverFederationInformation; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index d0e06bf29f5..df79d3aed22 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -14,6 +14,9 @@ import java.time.Instant; import java.util.List; import co.rsk.config.BridgeRegTestConstants; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.config.blockchain.upgrades.ConsensusRule; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index e4fd0fc4082..ee8ff1bdf87 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -27,8 +27,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; -import co.rsk.peg.bitcoin.CoinbaseInformation; -import co.rsk.peg.bitcoin.SimpleBtcTransaction; +import co.rsk.peg.bitcoin.*; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.whitelist.LockWhitelist; import co.rsk.peg.whitelist.LockWhitelistEntry; 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 f3e89396d04..83fa47cab8b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -33,6 +33,7 @@ import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.bitcoin.CoinbaseInformation; import co.rsk.peg.bitcoin.MerkleBranch; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.btcLockSender.BtcLockSender; import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index a91e3488e8f..bad859cbba4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -33,6 +33,8 @@ import co.rsk.crypto.Keccak256; import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.trie.Trie; diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java index c4db256196b..fa0f5f3d935 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java @@ -14,6 +14,7 @@ import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.wallet.RedeemData; import co.rsk.crypto.Keccak256; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; import co.rsk.peg.flyover.FlyoverFederationInformation; import java.time.Instant; import java.util.Arrays; diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java index 6dbae5d118c..d5348114524 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java @@ -10,6 +10,7 @@ import co.rsk.bitcoinj.script.FastBridgeRedeemScriptParser; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.wallet.RedeemData; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; import co.rsk.peg.flyover.FlyoverFederationInformation; import java.time.Instant; import java.util.Arrays; diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java similarity index 64% rename from rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java rename to rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java index a823178f372..c6b0179bf6f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java @@ -1,9 +1,10 @@ package co.rsk.peg; import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; -import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; -import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; +import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_CSV_VALUE; +import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -20,7 +21,7 @@ import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; -import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.peg.bitcoin.*; import co.rsk.peg.resources.TestConstants; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -45,12 +46,14 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; -class LegacyErpFederationTest { +class NonStandardErpFederationsTest { private ErpFederation federation; private NetworkParameters networkParameters; - private List standardKeys; private int defaultThreshold; + private List defaultKeys; private List emergencyKeys; private int emergencyThreshold; private long activationDelayValue; @@ -71,26 +74,25 @@ void setup() { BtcECKey federator7PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02ac1901b6fba2c1dbd47d894d2bd76c8ba1d296d65f6ab47f1c6b22afb53e73eb")); BtcECKey federator8PublicKey = BtcECKey.fromPublicOnly(Hex.decode("031aabbeb9b27258f98c2bf21f36677ae7bae09eb2d8c958ef41a20a6e88626d26")); BtcECKey federator9PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea")); - standardKeys = Arrays.asList( + defaultKeys = Arrays.asList( federator0PublicKey, federator1PublicKey, federator2PublicKey, federator3PublicKey, federator4PublicKey, federator5PublicKey, federator6PublicKey, federator7PublicKey, federator8PublicKey, federator9PublicKey ); - defaultThreshold = standardKeys.size() / 2 + 1; + defaultThreshold = defaultKeys.size() / 2 + 1; emergencyKeys = bridgeConstants.getErpFedPubKeysList(); emergencyThreshold = emergencyKeys.size() / 2 + 1; activationDelayValue = bridgeConstants.getErpFedActivationDelay(); networkParameters = bridgeConstants.getBtcParams(); activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - federation = createDefaultLegacyErpFederation(); + federation = createDefaultNonStandardErpFederation(); } - private ErpFederation createDefaultLegacyErpFederation() { - List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys); + private ErpFederation createDefaultNonStandardErpFederation() { + List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(defaultKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; erpRedeemScriptBuilder = @@ -111,7 +113,7 @@ private ErpFederation createDefaultLegacyErpFederation() { void createInvalidLegacyErpFederation_nullErpKeys() { emergencyKeys = null; ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, this::createDefaultLegacyErpFederation + ErpFederationCreationException.class, this::createDefaultNonStandardErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -120,7 +122,7 @@ void createInvalidLegacyErpFederation_nullErpKeys() { void createInvalidLegacyErpFederation_emptyErpKeys() { emergencyKeys = new ArrayList<>(); ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, this::createDefaultLegacyErpFederation + ErpFederationCreationException.class, this::createDefaultNonStandardErpFederation ); assertEquals(NULL_OR_EMPTY_EMERGENCY_KEYS, exception.getReason()); } @@ -128,61 +130,83 @@ void createInvalidLegacyErpFederation_emptyErpKeys() { @Test void createValidLegacyErpFederation_oneErpKey() { emergencyKeys = Collections.singletonList(emergencyKeys.get(0)); - assertDoesNotThrow(this::createDefaultLegacyErpFederation); - } - @Test - void createInvalidLegacyErpFederation_negativeCsvValue() { - activationDelayValue = -100L; + emergencyThreshold = emergencyKeys.size() / 2 + 1; + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, - () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) - ); - assertEquals(INVALID_CSV_VALUE, exception.getReason()); + assertDoesNotThrow(() -> builder + .createRedeemScriptFromKeys( + defaultKeys, defaultThreshold, + emergencyKeys, emergencyThreshold, + activationDelayValue)); } - @Test - void createInvalidLegacyErpFederation_zeroCsvValue() { - activationDelayValue = 0L; - ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, - () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) - ); - assertEquals(INVALID_CSV_VALUE, exception.getReason()); + @ParameterizedTest + @ValueSource(longs = { 130L, 500L, 33_000L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE}) + void createValidNonStandardErpFederation_csvValues_post_RSKIP293(long csvValue) { + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + + activationDelayValue = csvValue; + + createAndValidateFederation(); + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + assertTrue(builder instanceof NonStandardErpRedeemScriptBuilder); } @Test - void createInvalidLegacyErpFederation_aboveMaxCsvValue() { - activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1; - ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); - ErpFederationCreationException exception = assertThrows( + void createErpRedeemScriptWithCsvUnsignedBE_csvValueOneByteLong_post_RSKIP284_pre_RSKIP293() { + // should create the redeem script with NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + + // For a value that only uses 1 byte it should add leading zeroes to complete 2 bytes + activationDelayValue = 20L; + + createAndValidateFederation(); + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + assertTrue(builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE); + } + + @ParameterizedTest + @ValueSource(longs = {-100L, 0L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1, 100_000L, 8_400_000L }) + void createInvalidNonStandardErpFederation_csvValues_post_RSKIP293(long csvValue) { + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + + activationDelayValue = csvValue; + + federation = createDefaultNonStandardErpFederation(); + ErpFederationCreationException fedException = assertThrows( ErpFederationCreationException.class, - () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) + () -> federation.getRedeemScript()); + assertEquals(REDEEM_SCRIPT_CREATION_FAILED, fedException.getReason()); + + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, + () -> builder.createRedeemScriptFromKeys( + defaultKeys, defaultThreshold, + emergencyKeys, emergencyThreshold, + activationDelayValue) ); assertEquals(INVALID_CSV_VALUE, exception.getReason()); } @Test - void createValidLegacyErpFederation_exactMaxCsvValue() { - activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE; - assertDoesNotThrow(this::createDefaultLegacyErpFederation); - } - - @Test - void createInvalidNonStandardBuilder_aboveMaxScriptSigSize() { + void createInvalidNonStandardBuilder_aboveMaxRedeemScriptSize() { // add one member to exceed redeem script size limit - List newStandardKeys = federation.getBtcPublicKeys(); + List newDefaultKeys = federation.getBtcPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( Hex.decode("02550cc87fa9061162b1dd395a16662529c9d8094c0feca17905a3244713d65fe8") ); - newStandardKeys.add(federator10PublicKey); - standardKeys = newStandardKeys; + newDefaultKeys.add(federator10PublicKey); + defaultKeys = newDefaultKeys; ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); ScriptCreationException exception = assertThrows( ScriptCreationException.class, - () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) + () -> builder.createRedeemScriptFromKeys(defaultKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) ); assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); } @@ -215,7 +239,6 @@ void testEquals_same() { federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - erpRedeemScriptBuilder ); assertEquals(federation, otherFederation); @@ -230,7 +253,6 @@ void testEquals_differentCreationTime() { federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - erpRedeemScriptBuilder ); assertEquals(federation, otherFederation); @@ -245,7 +267,6 @@ void testEquals_differentCreationBlockNumber() { federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - erpRedeemScriptBuilder ); assertEquals(federation, otherFederation); @@ -255,18 +276,18 @@ void testEquals_differentCreationBlockNumber() { void testEquals_differentNetworkParameters() { networkParameters = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); - ErpFederation otherFederation = createDefaultLegacyErpFederation(); + ErpFederation otherFederation = createDefaultNonStandardErpFederation(); Assertions.assertNotEquals(federation, otherFederation); } @Test void testEquals_differentNumberOfMembers() { // remove federator9 - List newStandardKeys = federation.getBtcPublicKeys(); - newStandardKeys.remove(newStandardKeys.size() - 1); - standardKeys = newStandardKeys; + List newDefaultKeys = federation.getBtcPublicKeys(); + newDefaultKeys.remove(newDefaultKeys.size() - 1); + defaultKeys = newDefaultKeys; - ErpFederation otherFederation = createDefaultLegacyErpFederation(); + ErpFederation otherFederation = createDefaultNonStandardErpFederation(); Assertions.assertNotEquals(federation, otherFederation); } @@ -276,24 +297,106 @@ void testEquals_differentMembers() { BtcECKey federator9PublicKey = BtcECKey.fromPublicOnly( Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea") ); - List newStandardKeys = federation.getBtcPublicKeys(); - newStandardKeys.remove(8); - newStandardKeys.add(federator9PublicKey); - standardKeys = newStandardKeys; + List newDefaultKeys = federation.getBtcPublicKeys(); + newDefaultKeys.remove(8); + newDefaultKeys.add(federator9PublicKey); + defaultKeys = newDefaultKeys; - ErpFederation otherFederation = createDefaultLegacyErpFederation(); + ErpFederation otherFederation = createDefaultNonStandardErpFederation(); Assertions.assertNotEquals(federation, otherFederation); } + @Test + void createLegacyErpRedeemScript_fromNonStandardErpBuilders() { + ErpRedeemScriptBuilder builder; + Script obtainedRedeemScript; + byte[] expectedRedeemScriptProgram; + + // the emergency keys and csvValue are the same for all non-standard feds + BtcECKey emergency0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3")); + BtcECKey emergency1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f14")); + BtcECKey emergency2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f")); + emergencyKeys = Arrays.asList( + emergency0PublicKey, emergency1PublicKey, emergency2PublicKey + ); + emergencyThreshold = emergencyKeys.size() / 2 + 1; + activationDelayValue = 52_560L; + + // test NonStandardErpRedeemScriptBuilderHardcoded + expectedRedeemScriptProgram = // this is the redeem script program from fed non-standard hardcoded + Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f42102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da210344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a0921039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb955670300cd50b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); + + BtcECKey federator0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce")); + BtcECKey federator1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f4")); + BtcECKey federator2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed6")); + BtcECKey federator3PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da")); + BtcECKey federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9")); + defaultKeys = Arrays.asList( + federator0PublicKey, federator1PublicKey, federator2PublicKey, + federator3PublicKey, federator4PublicKey + ); + defaultThreshold = defaultKeys.size() / 2 + 1; + + federation = createDefaultNonStandardErpFederation(); + builder = new NonStandardErpRedeemScriptBuilderHardcoded(); + obtainedRedeemScript = builder + .createRedeemScriptFromKeys(defaultKeys, defaultThreshold, + emergencyKeys, emergencyThreshold, + activationDelayValue + ); + assertArrayEquals(expectedRedeemScriptProgram, obtainedRedeemScript.getProgram()); + + + // test NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE + expectedRedeemScriptProgram = // this is the redeem script program from fed non-standard with unsigned csv + Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f421025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed62102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da210344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a09556702cd50b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); + federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a09")); + defaultKeys = Arrays.asList( + federator0PublicKey, federator1PublicKey, federator2PublicKey, + federator3PublicKey, federator4PublicKey + ); + + federation = createDefaultNonStandardErpFederation(); + builder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); + obtainedRedeemScript = builder + .createRedeemScriptFromKeys(defaultKeys, defaultThreshold, + emergencyKeys, emergencyThreshold, + activationDelayValue + ); + assertArrayEquals(expectedRedeemScriptProgram, obtainedRedeemScript.getProgram()); + + + // test NonStandardErpRedeemScriptBuilder + expectedRedeemScriptProgram = // this is the redeem script program from fed non-standard + Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f421025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed62102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da2103fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce858155670350cd00b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); + + federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("03fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce8581")); + defaultKeys = Arrays.asList( + federator0PublicKey, federator1PublicKey, federator2PublicKey, + federator3PublicKey, federator4PublicKey + ); + federation = createDefaultNonStandardErpFederation(); + + builder = new NonStandardErpRedeemScriptBuilder(); + obtainedRedeemScript = builder + .createRedeemScriptFromKeys(defaultKeys, defaultThreshold, + emergencyKeys, emergencyThreshold, + activationDelayValue + ); + assertArrayEquals(expectedRedeemScriptProgram, obtainedRedeemScript.getProgram()); + } + @Test void getP2SHScriptAndAddress() { // standard and emergency keys from last real non-standard erp fed in testnet + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); BridgeConstants bridgeTestNetConstants = BridgeTestNetConstants.getInstance(); networkParameters = bridgeTestNetConstants.getBtcParams(); emergencyKeys = bridgeTestNetConstants.getErpFedPubKeysList(); activationDelayValue = bridgeTestNetConstants.getErpFedActivationDelay(); - standardKeys = Arrays.asList( + defaultKeys = Arrays.asList( BtcECKey.fromPublicOnly( Hex.decode("0208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce") ), @@ -311,7 +414,7 @@ void getP2SHScriptAndAddress() { ) ); - ErpFederation realLegacyErpFederation = createDefaultLegacyErpFederation(); + ErpFederation realLegacyErpFederation = createDefaultNonStandardErpFederation(); Script p2shScript = realLegacyErpFederation.getP2SHScript(); Address address = realLegacyErpFederation.getAddress(); @@ -339,12 +442,13 @@ void getErpPubKeys_uncompressed_public_keys() { .collect(Collectors.toList()); // Recreate federation - ErpFederation federationWithUncompressedKeys = createDefaultLegacyErpFederation(); + ErpFederation federationWithUncompressedKeys = createDefaultNonStandardErpFederation(); assertEquals(emergencyKeys, federationWithUncompressedKeys.getErpPubKeys()); } @Test void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); byte[] rawRedeemScripts; @@ -359,18 +463,13 @@ void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { for (RawGeneratedRedeemScript generatedScript : generatedScripts) { // Skip test cases with invalid redeem script that exceed the maximum size if (generatedScript.script.getProgram().length <= MAX_SCRIPT_ELEMENT_SIZE) { - Federation erpFederation = new ErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(generatedScript.mainFed), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 1, - NetworkParameters.fromID(NetworkParameters.ID_TESTNET), - generatedScript.emergencyFed, - generatedScript.timelock, - - erpRedeemScriptBuilder - ); - - Script rskjScript = erpFederation.getRedeemScript(); + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + defaultKeys = generatedScript.mainFed; + emergencyKeys = generatedScript.emergencyFed; + activationDelayValue = generatedScript.timelock; + + federation = createDefaultNonStandardErpFederation(); + Script rskjScript = federation.getRedeemScript(); Script alternativeScript = generatedScript.script; assertEquals(alternativeScript, rskjScript); @@ -381,36 +480,38 @@ void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { @Test void getRedeemScript_before_RSKIP293() { when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - federation = createDefaultLegacyErpFederation(); + federation = createDefaultNonStandardErpFederation(); Script redeemScript = federation.getRedeemScript(); validateErpRedeemScript( redeemScript, - activationDelayValue, - false + activationDelayValue ); } @Test void getRedeemScript_after_RSKIP293() { when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - federation = createDefaultLegacyErpFederation(); + federation = createDefaultNonStandardErpFederation(); Script redeemScript = federation.getRedeemScript(); validateErpRedeemScript( redeemScript, - activationDelayValue, - true + activationDelayValue ); } @Test - void getRedeemScript_changes_after_RSKIP293() { + void getRedeemScript_changes_related_to_RSKIP293_testnet() { + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - federation = createDefaultLegacyErpFederation(); + + federation = createDefaultNonStandardErpFederation(); Script preRskip293RedeemScript = federation.getRedeemScript(); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - federation = createDefaultLegacyErpFederation(); + federation = createDefaultNonStandardErpFederation(); Script postRskip293RedeemScript = federation.getRedeemScript(); Assertions.assertNotEquals(preRskip293RedeemScript, postRskip293RedeemScript); @@ -419,124 +520,113 @@ void getRedeemScript_changes_after_RSKIP293() { @Test void createErpFederation_testnet_constants_before_RSKIP293() { networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - createErpFederation(false); + createAndValidateFederation(); } @Test void createErpFederation_testnet_constants_after_RSKIP293() { networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); - createErpFederation(true); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + createAndValidateFederation(); } @Test void createErpFederation_mainnet_constants_before_RSKIP293() { - networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET); - createErpFederation(false); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + createAndValidateFederation(); } @Test void createErpFederation_mainnet_constants_after_RSKIP293() { networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET); - createErpFederation(true); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + createAndValidateFederation(); } @Test void getRedeemScript_before_RSKIP_284_testnet() { + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); - Federation erpFederation = new ErpFederation( - FederationTestUtils.getFederationMembersFromPks(100, 200, 300), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 1, - NetworkParameters.fromID(NetworkParameters.ID_TESTNET), - emergencyKeys, - activationDelayValue, - new NonStandardErpRedeemScriptBuilderHardcoded() - ); + federation = createDefaultNonStandardErpFederation(); - assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, erpFederation.getRedeemScript()); + assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); } @Test void getRedeemScript_before_RSKIP_284_mainnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET); - federation = createDefaultLegacyErpFederation(); + //when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + federation = createDefaultNonStandardErpFederation(); Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); validateErpRedeemScript( federation.getRedeemScript(), - activationDelayValue, - false + activationDelayValue ); } @Test void getRedeemScript_after_RSKIP_284_testnet() { - Federation erpFederation = new ErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 1, - NetworkParameters.fromID(NetworkParameters.ID_TESTNET), - emergencyKeys, - activationDelayValue, - new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() - ); + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); + federation = createDefaultNonStandardErpFederation(); + + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + assertTrue(builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE); + Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); - Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, erpFederation.getRedeemScript()); validateErpRedeemScript( - erpFederation.getRedeemScript(), - activationDelayValue, - false + federation.getRedeemScript(), + activationDelayValue ); } @Test - void getRedeemScript_after_RSKIP_284_mainnet() { - Federation erpFederation = new ErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 1, - NetworkParameters.fromID(NetworkParameters.ID_MAINNET), - emergencyKeys, - activationDelayValue, - new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() - ); + void getRedeemScript_after_RSKIP_201_before_RSKIP_293_mainnet() { + ErpRedeemScriptBuilder builder; + + // check the hardcoded fed didnt exist on mainnet after rskip201 + federation = createDefaultNonStandardErpFederation(); + builder = federation.getErpRedeemScriptBuilder(); + Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); + assertFalse(builder instanceof NonStandardErpRedeemScriptBuilderHardcoded); + + // check the hardcoded fed didnt exist on mainnet after rskip284 + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + federation = createDefaultNonStandardErpFederation(); + builder = federation.getErpRedeemScriptBuilder(); + assertFalse(builder instanceof NonStandardErpRedeemScriptBuilderHardcoded); - Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, erpFederation.getRedeemScript()); validateErpRedeemScript( - erpFederation.getRedeemScript(), - activationDelayValue, - false + federation.getRedeemScript(), + activationDelayValue ); } @Test void testEquals_differentRedeemScript() { - ActivationConfig.ForBlock activationsPre = mock(ActivationConfig.ForBlock.class); - when(activationsPre.isActive(ConsensusRule.RSKIP284)).thenReturn(false); - - ActivationConfig.ForBlock activationsPost = mock(ActivationConfig.ForBlock.class); - when(activationsPost.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); // Both federations created before RSKIP284 with the same data, should have the same redeem script - activations = activationsPre; - - Federation erpFederation = createDefaultLegacyErpFederation(); - Federation otherErpFederation = createDefaultLegacyErpFederation(); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); + Federation erpFederation = createDefaultNonStandardErpFederation(); + Federation otherErpFederation = createDefaultNonStandardErpFederation(); assertEquals(erpFederation, otherErpFederation); - activations = activationsPost; // One federation created after RSKIP284 with the same data, should have different redeem script - otherErpFederation = createDefaultLegacyErpFederation(); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + otherErpFederation = createDefaultNonStandardErpFederation(); assertNotEquals(erpFederation, otherErpFederation); // The other federation created after RSKIP284 with the same data, should have same redeem script - erpFederation = createDefaultLegacyErpFederation(); + erpFederation = createDefaultNonStandardErpFederation(); assertEquals(erpFederation, otherErpFederation); } @@ -640,14 +730,13 @@ void spendFromErpFed_before_RSKIP293_mainnet_using_erp_multisig_can_spend() { @Test void spendFromErpFed_before_RSKIP293_mainnet_using_erp_multisig_cant_spend() { - BridgeConstants constants = BridgeMainNetConstants.getInstance(); - // Should fail due to the wrong encoding of the CSV value // In this case, the value 300 when encoded as BE and decoded as LE results in a larger number // This causes the validation to fail - NetworkParameters btcParams = constants.getBtcParams(); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); assertThrows(ScriptException.class, () -> spendFromErpFed( - btcParams, + networkParameters, 300, false, true @@ -717,16 +806,15 @@ void spendFromErpFed_after_RSKIP293_mainnet_using_standard_multisig() { )); } - private void createErpFederation(boolean isRskip293Active) { - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(isRskip293Active); - federation = createDefaultLegacyErpFederation(); + private void createAndValidateFederation() { + + federation = createDefaultNonStandardErpFederation(); validateErpRedeemScript( federation.getRedeemScript(), - standardKeys, + defaultKeys, emergencyKeys, - activationDelayValue, - isRskip293Active + activationDelayValue ); } @@ -736,7 +824,7 @@ private void spendFromErpFed( boolean isRskip293Active, boolean signWithEmergencyMultisig) { - standardKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( + defaultKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fed1", "fed2", "fed3", "fed4", "fed5", "fed6", "fed7", "fed8", "fed9", "fed10"}, true ); @@ -753,7 +841,7 @@ private void spendFromErpFed( Collections.singletonList(ConsensusRule.RSKIP293); activations = ActivationConfigsForTest.hop400(except).forBlock(0); - federation = createDefaultLegacyErpFederation(); + federation = createDefaultNonStandardErpFederation(); Coin value = Coin.valueOf(1_000_000); Coin fee = Coin.valueOf(10_000); @@ -768,7 +856,7 @@ private void spendFromErpFed( FederationTestUtils.spendFromErpFed( networkParameters, federation, - signWithEmergencyMultisig ? emergencyKeys : standardKeys, + signWithEmergencyMultisig ? emergencyKeys : defaultKeys, fundTx.getHash(), 0, destinationAddress, @@ -779,15 +867,13 @@ private void spendFromErpFed( private void validateErpRedeemScript( Script erpRedeemScript, - Long csvValue, - boolean isRskip293Active) { + Long csvValue) { validateErpRedeemScript( erpRedeemScript, - standardKeys, + defaultKeys, emergencyKeys, - csvValue, - isRskip293Active + csvValue ); } @@ -795,15 +881,17 @@ private void validateErpRedeemScript( Script erpRedeemScript, List defaultMultisigKeys, List emergencyMultisigKeys, - Long csvValue, - boolean isRskip293Active) { + Long csvValue) { // Keys are sorted when added to the redeem script, so we need them sorted in order to validate defaultMultisigKeys.sort(BtcECKey.PUBKEY_COMPARATOR); emergencyMultisigKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - int expectedCsvValueLength = isRskip293Active ? BigInteger.valueOf(csvValue).toByteArray().length : 2; - byte[] serializedCsvValue = isRskip293Active ? + int expectedCsvValueLength = activations.isActive(ConsensusRule.RSKIP293) ? + BigInteger.valueOf(csvValue).toByteArray().length + : 2; + + byte[] serializedCsvValue = activations.isActive(ConsensusRule.RSKIP293) ? Utils.signedLongToByteArrayLE(csvValue) : Utils.unsignedLongToByteArrayBE(csvValue, expectedCsvValueLength); @@ -874,9 +962,9 @@ private static class RawGeneratedRedeemScript { @JsonCreator public RawGeneratedRedeemScript(@JsonProperty("mainFed") List mainFed, - @JsonProperty("emergencyFed") List emergencyFed, - @JsonProperty("timelock") Long timelock, - @JsonProperty("script") String script) { + @JsonProperty("emergencyFed") List emergencyFed, + @JsonProperty("timelock") Long timelock, + @JsonProperty("script") String script) { this.mainFed = parseFed(mainFed); this.emergencyFed = parseFed(emergencyFed); this.timelock = timelock; @@ -887,4 +975,4 @@ private List parseFed(List fed) { return fed.stream().map(Hex::decode).map(BtcECKey::fromPublicOnly).collect(Collectors.toList()); } } -} +} \ No newline at end of file diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index a67393b6ff7..7709e212fd0 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -1,9 +1,10 @@ package co.rsk.peg; import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; -import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; -import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; +import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_CSV_VALUE; +import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; @@ -13,7 +14,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; import co.rsk.config.BridgeTestNetConstants; -import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.peg.bitcoin.*; import java.io.IOException; import java.nio.file.Files; @@ -39,12 +40,13 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; class P2shErpFederationTest { private ErpFederation federation; private NetworkParameters networkParameters; - private List standardKeys; private int defaultThreshold; + private List defaultKeys; private List emergencyKeys; private int emergencyThreshold; private long activationDelayValue; @@ -64,12 +66,12 @@ void setup() { BtcECKey federator7PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02ac1901b6fba2c1dbd47d894d2bd76c8ba1d296d65f6ab47f1c6b22afb53e73eb")); BtcECKey federator8PublicKey = BtcECKey.fromPublicOnly(Hex.decode("031aabbeb9b27258f98c2bf21f36677ae7bae09eb2d8c958ef41a20a6e88626d26")); BtcECKey federator9PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea")); - standardKeys = Arrays.asList( + defaultKeys = Arrays.asList( federator0PublicKey, federator1PublicKey, federator2PublicKey, federator3PublicKey, federator4PublicKey, federator5PublicKey, federator6PublicKey, federator7PublicKey, federator8PublicKey, federator9PublicKey ); - defaultThreshold = standardKeys.size() / 2 + 1; + defaultThreshold = defaultKeys.size() / 2 + 1; emergencyKeys = bridgeConstants.getErpFedPubKeysList(); emergencyThreshold = emergencyKeys.size() / 2 + 1; activationDelayValue = bridgeConstants.getErpFedActivationDelay(); @@ -81,7 +83,7 @@ void setup() { } private ErpFederation createDefaultP2shErpFederation() { - List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys); + List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(defaultKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; @@ -96,9 +98,21 @@ private ErpFederation createDefaultP2shErpFederation() { ); } + private void createAndValidateFederation() { + federation = createDefaultP2shErpFederation(); + + validateP2shErpRedeemScript( + federation.getRedeemScript(), + defaultKeys, + emergencyKeys, + activationDelayValue + ); + } + @Test void createInvalidP2shErpFederation_nullErpKeys() { emergencyKeys = null; + ErpFederationCreationException exception = assertThrows( ErpFederationCreationException.class, this::createDefaultP2shErpFederation ); @@ -108,6 +122,7 @@ void createInvalidP2shErpFederation_nullErpKeys() { @Test void createInvalidP2shErpFederation_emptyErpKeys() { emergencyKeys = new ArrayList<>(); + ErpFederationCreationException exception = assertThrows( ErpFederationCreationException.class, this::createDefaultP2shErpFederation ); @@ -117,64 +132,57 @@ void createInvalidP2shErpFederation_emptyErpKeys() { @Test void createValidP2shErpFederation_oneErpKey() { emergencyKeys = Collections.singletonList(emergencyKeys.get(0)); - assertDoesNotThrow(this::createDefaultP2shErpFederation); + createAndValidateFederation(); } - @Test - void createInvalidP2shErpFederation_negativeCsvValue() { - activationDelayValue = -100L; + @ParameterizedTest + @ValueSource(longs = {20L, 130L, 500L, 33_000L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE}) + void createValidP2shErpFederation_csvValues(long csvValue) { + activationDelayValue = csvValue; - ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, - () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) - ); - assertEquals(INVALID_CSV_VALUE, exception.getReason()); + createAndValidateFederation(); } - @Test - void createInvalidP2shErpFederation_zeroCsvValue() { - activationDelayValue = 0L; - ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, - () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) - ); - assertEquals(INVALID_CSV_VALUE, exception.getReason()); - } + @ParameterizedTest + @ValueSource(longs = {-100L, 0L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1, 100_000L, 8_400_000L}) + void createInvalidP2shErpFederation_invalidCsvValues(long csvValue) { + activationDelayValue = csvValue; - @Test - void createInvalidP2shErpFederation_aboveMaxCsvValue() { - activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1; - ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); - ErpFederationCreationException exception = assertThrows( + federation = createDefaultP2shErpFederation(); + ErpFederationCreationException fedException = assertThrows( ErpFederationCreationException.class, - () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) - ); - assertEquals(INVALID_CSV_VALUE, exception.getReason()); - } + () -> federation.getRedeemScript()); + assertEquals(REDEEM_SCRIPT_CREATION_FAILED, fedException.getReason()); - @Test - void createValidP2shErpFederation_exactMaxCsvValue() { - activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE; - assertDoesNotThrow(this::createDefaultP2shErpFederation); + ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + RedeemScriptCreationException builderException = assertThrows( + RedeemScriptCreationException.class, + () -> builder.createRedeemScriptFromKeys( + defaultKeys, defaultThreshold, + emergencyKeys, emergencyThreshold, + activationDelayValue + )); + assertEquals(INVALID_CSV_VALUE, builderException.getReason()); } @Test - void createInvalidFederation_aboveMaxScriptSigSize() { + void createInvalidFederation_aboveMaxRedeemScriptSize() { // add one member to exceed redeem script size limit - List newStandardKeys = federation.getBtcPublicKeys(); + List newDefaultKeys = federation.getBtcPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( Hex.decode("02550cc87fa9061162b1dd395a16662529c9d8094c0feca17905a3244713d65fe8") ); - newStandardKeys.add(federator10PublicKey); - standardKeys = newStandardKeys; + newDefaultKeys.add(federator10PublicKey); + defaultKeys = newDefaultKeys; ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); ScriptCreationException exception = assertThrows( ScriptCreationException.class, - () -> builder.createRedeemScriptFromKeys(standardKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue) - ); + () -> builder.createRedeemScriptFromKeys( + defaultKeys, defaultThreshold, + emergencyKeys, emergencyThreshold, + activationDelayValue + )); assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); } @@ -216,9 +224,9 @@ void testEquals_same() { @Test void testEquals_differentNumberOfMembers() { // remove federator9 - List newStandardKeys = federation.getBtcPublicKeys(); - newStandardKeys.remove(9); - standardKeys = newStandardKeys; + List newDefaultKeys = federation.getBtcPublicKeys(); + newDefaultKeys.remove(9); + defaultKeys = newDefaultKeys; ErpFederation otherFederation = createDefaultP2shErpFederation(); Assertions.assertNotEquals(federation, otherFederation); @@ -238,15 +246,57 @@ void testEquals_differentMembers() { Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea") ); // replace federator8 with federator9 - List newStandardKeys = federation.getBtcPublicKeys(); - newStandardKeys.remove(8); - newStandardKeys.add(federator9PublicKey); - standardKeys = newStandardKeys; + List newDefaultKeys = federation.getBtcPublicKeys(); + newDefaultKeys.remove(8); + newDefaultKeys.add(federator9PublicKey); + defaultKeys = newDefaultKeys; ErpFederation otherFederation = createDefaultP2shErpFederation(); Assertions.assertNotEquals(federation, otherFederation); } + @Test + void createP2shRedeemScript_fromP2shErpBuilder() { + + // this is a known redeem script program + byte[] redeemScriptProgram = Hex.decode("64542102099fd69cf6a350679a05593c3ff814bfaa281eb6dde505c953cf2875979b120921022a159227df514c7b7808ee182ae07d71770b67eda1e5ee668272761eefb2c24c210233bc8c1a994a921d7818f93e57a559373133ba531928843bf84c59c15e47eab02102937df9948c6f18359e473beeee0a19c27dd4f6d4114e5809aa862671bb765b5b2102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da2103db2ebad883823cefe8b2336c03b8d9c6afee4cbac77c7e935bc8c51ec20b26632103fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce858157ae670350cd00b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f53ae68"); + + BtcECKey federator0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02099fd69cf6a350679a05593c3ff814bfaa281eb6dde505c953cf2875979b1209")); + BtcECKey federator1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("022a159227df514c7b7808ee182ae07d71770b67eda1e5ee668272761eefb2c24c")); + BtcECKey federator2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0233bc8c1a994a921d7818f93e57a559373133ba531928843bf84c59c15e47eab0")); + BtcECKey federator3PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02937df9948c6f18359e473beeee0a19c27dd4f6d4114e5809aa862671bb765b5b")); + BtcECKey federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da")); + BtcECKey federator5PublicKey = BtcECKey.fromPublicOnly(Hex.decode("03db2ebad883823cefe8b2336c03b8d9c6afee4cbac77c7e935bc8c51ec20b2663")); + BtcECKey federator6PublicKey = BtcECKey.fromPublicOnly(Hex.decode("03fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce8581")); + defaultKeys = Arrays.asList( + federator0PublicKey, federator1PublicKey, federator2PublicKey, + federator3PublicKey, federator4PublicKey, federator5PublicKey, + federator6PublicKey + ); + defaultThreshold = defaultKeys.size() / 2 + 1; + + BtcECKey emergency0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3")); + BtcECKey emergency1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f14")); + BtcECKey emergency2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f")); + emergencyKeys = Arrays.asList( + emergency0PublicKey, emergency1PublicKey, emergency2PublicKey + ); + emergencyThreshold = emergencyKeys.size() / 2 + 1; + + activationDelayValue = 52_560L; + + createAndValidateFederation(); + + ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + Script obtainedRedeemScript = + builder.createRedeemScriptFromKeys( + defaultKeys, defaultThreshold, + emergencyKeys, emergencyThreshold, + activationDelayValue + ); + assertArrayEquals(redeemScriptProgram, obtainedRedeemScript.getProgram()); + } + @ParameterizedTest @MethodSource("getRedeemScriptArgsProvider") void getRedeemScript(BridgeConstants bridgeConstants) { @@ -254,7 +304,7 @@ void getRedeemScript(BridgeConstants bridgeConstants) { // should add this case because adding erp to mainnet genesis federation // throws a validation error, so in that case we use the one set up before each test. // if using testnet constants, we can add them with no errors - standardKeys = bridgeConstants.getGenesisFederation().getBtcPublicKeys(); + defaultKeys = bridgeConstants.getGenesisFederation().getBtcPublicKeys(); } emergencyKeys = bridgeConstants.getErpFedPubKeysList(); @@ -263,7 +313,7 @@ void getRedeemScript(BridgeConstants bridgeConstants) { ErpFederation p2shErpFederation = createDefaultP2shErpFederation(); validateP2shErpRedeemScript( p2shErpFederation.getRedeemScript(), - standardKeys, + defaultKeys, emergencyKeys, activationDelayValue ); @@ -282,10 +332,10 @@ void getStandardRedeemScript() { // Create a legacy powpeg and then a p2sh valid one. Both of them should produce the same standard redeem script StandardMultisigFederation legacyFed = new StandardMultisigFederation( - members, - creationTime, - creationBlock, - btcParams + members, + creationTime, + creationBlock, + btcParams ); ErpFederation p2shFed = new ErpFederation( members, @@ -308,7 +358,7 @@ void getPowPegAddressAndP2shScript_testnet() { emergencyKeys = bridgeTestNetConstants.getErpFedPubKeysList(); activationDelayValue = bridgeTestNetConstants.getErpFedActivationDelay(); - standardKeys = Arrays.stream(new String[]{ + defaultKeys = Arrays.stream(new String[]{ "02099fd69cf6a350679a05593c3ff814bfaa281eb6dde505c953cf2875979b1209", "022a159227df514c7b7808ee182ae07d71770b67eda1e5ee668272761eefb2c24c", "0233bc8c1a994a921d7818f93e57a559373133ba531928843bf84c59c15e47eab0", @@ -344,7 +394,7 @@ void getPowPegAddressAndP2shScript_mainnet() { emergencyKeys = bridgeMainNetConstants.getErpFedPubKeysList(); activationDelayValue = bridgeMainNetConstants.getErpFedActivationDelay(); - standardKeys = Arrays.stream(new String[]{ + defaultKeys = Arrays.stream(new String[]{ "020ace50bab1230f8002a0bfe619482af74b338cc9e4c956add228df47e6adae1c", "0275d473555de2733c47125f9702b0f870df1d817379f5587f09b6c40ed2c6c949", "025093f439fb8006fd29ab56605ffec9cdc840d16d2361004e1337a2f86d8bd2db", @@ -427,7 +477,7 @@ void spendFromP2shErpFed( long activationDelay, boolean signWithEmergencyMultisig) { - List standardKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( + List defaultKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fed1", "fed2", "fed3", "fed4", "fed5", "fed6", "fed7", "fed8", "fed9", "fed10"}, true ); @@ -438,7 +488,7 @@ void spendFromP2shErpFed( ); ErpFederation p2shErpFed = new ErpFederation( - FederationMember.getFederationMembersFromKeys(standardKeys), + FederationMember.getFederationMembersFromKeys(defaultKeys), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 0L, networkParameters, @@ -460,7 +510,7 @@ void spendFromP2shErpFed( assertDoesNotThrow(() -> FederationTestUtils.spendFromErpFed( networkParameters, p2shErpFed, - signWithEmergencyMultisig ? emergencyKeys : standardKeys, + signWithEmergencyMultisig ? emergencyKeys : defaultKeys, fundTx.getHash(), 0, destinationAddress, @@ -470,18 +520,37 @@ void spendFromP2shErpFed( } private void validateP2shErpRedeemScript( - Script erpRedeemScript, - List defaultMultisigKeys, - List emergencyMultisigKeys, + Script redeemScript, + List defaultKeys, + List emergencyKeys, Long csvValue) { + /*** + * Expected structure: + * OP_NOTIF + * OP_M + * PUBKEYS...N + * OP_N + * OP_CHECKMULTISIG + * OP_ELSE + * OP_PUSHBYTES + * CSV_VALUE + * OP_CHECKSEQUENCEVERIFY + * OP_DROP + * OP_M + * PUBKEYS...N + * OP_N + * OP_CHECKMULTISIG + * OP_ENDIF + */ + // Keys are sorted when added to the redeem script, so we need them sorted in order to validate - defaultMultisigKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - emergencyMultisigKeys.sort(BtcECKey.PUBKEY_COMPARATOR); + defaultKeys.sort(BtcECKey.PUBKEY_COMPARATOR); + emergencyKeys.sort(BtcECKey.PUBKEY_COMPARATOR); byte[] serializedCsvValue = Utils.signedLongToByteArrayLE(csvValue); - byte[] script = erpRedeemScript.getProgram(); + byte[] script = redeemScript.getProgram(); Assertions.assertTrue(script.length > 0); int index = 0; @@ -490,11 +559,11 @@ private void validateP2shErpRedeemScript( assertEquals(ScriptOpCodes.OP_NOTIF, script[index++]); // Next byte should equal M, from an M/N multisig - int m = defaultMultisigKeys.size() / 2 + 1; + int m = defaultKeys.size() / 2 + 1; assertEquals(ScriptOpCodes.getOpCode(String.valueOf(m)), script[index++]); // Assert public keys - for (BtcECKey key: defaultMultisigKeys) { + for (BtcECKey key: defaultKeys) { byte[] pubkey = key.getPubKey(); assertEquals(pubkey.length, script[index++]); for (byte b : pubkey) { @@ -503,7 +572,7 @@ private void validateP2shErpRedeemScript( } // Next byte should equal N, from an M/N multisig - int n = defaultMultisigKeys.size(); + int n = defaultKeys.size(); assertEquals(ScriptOpCodes.getOpCode(String.valueOf(n)), script[index++]); // Next byte should equal OP_CHECKMULTISIG @@ -524,10 +593,10 @@ private void validateP2shErpRedeemScript( assertEquals(ScriptOpCodes.OP_DROP, script[index++]); // Next byte should equal M, from an M/N multisig - m = emergencyMultisigKeys.size() / 2 + 1; + m = emergencyKeys.size() / 2 + 1; assertEquals(ScriptOpCodes.getOpCode(String.valueOf(m)), script[index++]); - for (BtcECKey key: emergencyMultisigKeys) { + for (BtcECKey key: emergencyKeys) { byte[] pubkey = key.getPubKey(); assertEquals(Integer.valueOf(pubkey.length).byteValue(), script[index++]); for (byte b : pubkey) { @@ -536,7 +605,7 @@ private void validateP2shErpRedeemScript( } // Next byte should equal N, from an M/N multisig - n = emergencyMultisigKeys.size(); + n = emergencyKeys.size(); assertEquals(ScriptOpCodes.getOpCode(String.valueOf(n)), script[index++]); // Next byte should equal OP_CHECKMULTISIG @@ -601,4 +670,4 @@ private List parseFed(List fed) { return fed.stream().map(Hex::decode).map(BtcECKey::fromPublicOnly).collect(Collectors.toList()); } } -} +} \ No newline at end of file diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index d8f7ddc1e8d..b52550c1793 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -24,6 +24,9 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.crypto.Keccak256; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.resources.TestConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index 30f107fa36c..15b6f1a62ce 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -11,6 +11,9 @@ import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; import co.rsk.peg.bitcoin.BitcoinUtils; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.test.builders.BridgeSupportBuilder; @@ -47,13 +50,7 @@ import static co.rsk.peg.PegTestUtils.BTC_TX_LEGACY_VERSION; import static co.rsk.peg.ReleaseTransactionBuilder.BTC_TX_VERSION_2; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertSame; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; diff --git a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java index 5618def0c6a..5a3e446f6de 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java @@ -52,6 +52,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; + +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.junit.jupiter.api.Assertions; diff --git a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java index 936a5c9c804..cdc787066bb 100644 --- a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java @@ -18,7 +18,7 @@ package co.rsk.peg; -import static co.rsk.peg.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; import co.rsk.bitcoinj.core.Address; @@ -35,6 +35,7 @@ import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; +import co.rsk.peg.bitcoin.ScriptCreationException; import org.bouncycastle.util.encoders.Hex; import org.ethereum.TestUtils; import org.ethereum.crypto.ECKey; From dc3eb8d0a532f4e533337de3e8d30fe8be03f123 Mon Sep 17 00:00:00 2001 From: julia zack Date: Tue, 28 Nov 2023 17:51:36 -0300 Subject: [PATCH 034/137] Add NonStandardErpRedeemScriptBuilderFactoryTest and ErpRedeemScriptBuilderUtilsTest. #Fix tests after rebase --- .../main/java/co/rsk/peg/PegUtilsLegacy.java | 4 +- .../bitcoin/ErpRedeemScriptBuilderUtils.java | 2 +- ...StandardErpRedeemScriptBuilderFactory.java | 2 +- ...idgeSupportRegisterBtcTransactionTest.java | 9 +- .../peg/ErpRedeemScriptBuilderUtilsTest.java | 96 ++++----- .../peg/NonStandardErpFederationsTest.java | 190 +++++++++++------- ...dardErpRedeemScriptBuilderFactoryTest.java | 77 +++++++ .../co/rsk/peg/P2shErpFederationTest.java | 68 +++---- .../test/java/co/rsk/peg/PegTestUtils.java | 7 +- .../peg/PegUtilsGetTransactionTypeTest.java | 4 +- .../PegUtilsLegacyGetTransactionTypeTest.java | 14 +- .../java/co/rsk/peg/PegUtilsLegacyTest.java | 73 ++++--- .../test/java/co/rsk/peg/PegUtilsTest.java | 9 +- .../rsk/peg/{bitcoin => }/PocSighashTest.java | 35 ++-- 14 files changed, 357 insertions(+), 233 deletions(-) create mode 100644 rskj-core/src/test/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactoryTest.java rename rskj-core/src/test/java/co/rsk/peg/{bitcoin => }/PocSighashTest.java (98%) diff --git a/rskj-core/src/main/java/co/rsk/peg/PegUtilsLegacy.java b/rskj-core/src/main/java/co/rsk/peg/PegUtilsLegacy.java index 527a435eb61..2aca294e977 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PegUtilsLegacy.java +++ b/rskj-core/src/main/java/co/rsk/peg/PegUtilsLegacy.java @@ -388,13 +388,13 @@ protected static boolean isAnyUTXOAmountBelowMinimum( private static Script getFederationStandardRedeemScript(Federation federation) { return federation instanceof ErpFederation ? - ((ErpFederation) federation).getStandardRedeemScript() : + ((ErpFederation) federation).getDefaultRedeemScript() : federation.getRedeemScript(); } private static Script getFederationStandardP2SHScript(Federation federation) { return federation instanceof ErpFederation ? - ((ErpFederation) federation).getStandardP2SHScript() : + ((ErpFederation) federation).getDefaultP2SHScript() : federation.getP2SHScript(); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilderUtils.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilderUtils.java index 8fbbf096a57..0264868a975 100644 --- a/rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilderUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/ErpRedeemScriptBuilderUtils.java @@ -26,7 +26,7 @@ public static void validateRedeemScriptValues( Script erpFederationRedeemScript, Long csvValue ) { - if (!defaultFederationRedeemScript.isSentToStandardMultiSig() || !erpFederationRedeemScript.isSentToStandardMultiSig()) { + if (!defaultFederationRedeemScript.isSentToMultiSig() || !erpFederationRedeemScript.isSentToMultiSig()) { String message = "Provided redeem scripts have an invalid structure, not standard"; logger.debug( diff --git a/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java index bd8e197b1e4..3f76d53a456 100644 --- a/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java @@ -25,4 +25,4 @@ public static ErpRedeemScriptBuilder getNonStandardErpRedeemScriptBuilder( private static boolean networkIsTestnet(NetworkParameters networkParameters) { return networkParameters.getId().equals(NetworkParameters.ID_TESTNET); } -} \ No newline at end of file +} diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index 02bc9c65a6f..ffeb00631d7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -21,6 +21,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.bitcoin.CoinbaseInformation; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; import co.rsk.peg.pegin.RejectedPeginReason; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; @@ -381,28 +382,28 @@ void init() throws IOException { ); retiringFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); - retiringFederation = new P2shErpFederation( + retiringFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedSigners), Instant.ofEpochMilli(1000L), 1, bridgeMainnetConstants.getBtcParams(), bridgeMainnetConstants.getErpFedPubKeysList(), bridgeMainnetConstants.getErpFedActivationDelay(), - arrowhead600Activations + new P2shErpRedeemScriptBuilder() ); activeFedSigners = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa07", "fa08", "fa09", "fa10", "fa11"}, true ); activeFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); - activeFederation = new P2shErpFederation( + activeFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFedSigners), Instant.ofEpochMilli(1000L), 2L, bridgeMainnetConstants.getBtcParams(), bridgeMainnetConstants.getErpFedPubKeysList(), bridgeMainnetConstants.getErpFedActivationDelay(), - arrowhead600Activations + new P2shErpRedeemScriptBuilder() ); mockFactory = mock(BtcBlockStoreWithCache.Factory.class); diff --git a/rskj-core/src/test/java/co/rsk/peg/ErpRedeemScriptBuilderUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/ErpRedeemScriptBuilderUtilsTest.java index bd1fd7eaad8..cd12c50da2c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ErpRedeemScriptBuilderUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ErpRedeemScriptBuilderUtilsTest.java @@ -6,6 +6,8 @@ import co.rsk.bitcoinj.script.ScriptChunk; import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilderUtils; +import co.rsk.peg.bitcoin.RedeemScriptCreationException; import org.bouncycastle.util.encoders.Hex; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -16,8 +18,8 @@ import java.util.List; import static co.rsk.bitcoinj.script.ScriptOpCodes.OP_CHECKMULTISIG; -import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_CSV_VALUE; -import static co.rsk.peg.ErpFederationCreationException.Reason.INVALID_INTERNAL_REDEEM_SCRIPTS; +import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_CSV_VALUE; +import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_INTERNAL_REDEEM_SCRIPTS; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -66,8 +68,8 @@ void createInvalidErpFederation_invalidCsvValues(long csvValue) { Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( defaultScript, emergencyScript, @@ -84,9 +86,9 @@ void createValidErpFederation_exactMaxCsvValue() { activationDelayValue = ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE; assertDoesNotThrow( () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( - defaultScript, - emergencyScript, - activationDelayValue) + defaultScript, + emergencyScript, + activationDelayValue) ); } @@ -95,12 +97,12 @@ void createInvalidErpFederation_invalidDefaultRedeemScript_withoutThreshold() { Script defaultScript = createMultiSigScriptWithoutThreshold(defaultKeys); Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( - defaultScript, - emergencyScript, - activationDelayValue) + defaultScript, + emergencyScript, + activationDelayValue) ); assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); } @@ -110,12 +112,12 @@ void createInvalidErpFederation_invalidEmergencyRedeemScript_withoutThreshold() Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); Script emergencyScript = createMultiSigScriptWithoutThreshold(emergencyKeys); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( - defaultScript, - emergencyScript, - activationDelayValue) + defaultScript, + emergencyScript, + activationDelayValue) ); assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); } @@ -125,8 +127,8 @@ void createInvalidErpFederation_invalidDefaultRedeemScript_withZeroThreshold() { Script defaultScript = createMultiSigScript(defaultKeys, 0); Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( defaultScript, emergencyScript, @@ -140,8 +142,8 @@ void createInvalidErpFederation_invalidEmergencyRedeemScript_withZeroThreshold() Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); Script emergencyScript = createMultiSigScript(emergencyKeys, 0); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( defaultScript, emergencyScript, @@ -155,8 +157,8 @@ void createInvalidErpFederation_invalidDefaultRedeemScript_withoutKeysSize() { Script defaultScript = createMultiSigScriptWithoutKeysSize(defaultKeys, defaultThreshold); Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( defaultScript, emergencyScript, @@ -170,8 +172,8 @@ void createInvalidErpFederation_invalidEmergencyRedeemScript_withoutKeysSize() { Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); Script emergencyScript = createMultiSigScriptWithoutKeysSize(emergencyKeys, emergencyThreshold); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( defaultScript, emergencyScript, @@ -185,12 +187,12 @@ void createInvalidErpFederation_invalidDefaultRedeemScript_withoutOpCheckMultisi Script defaultScript = createMultiSigScriptWithoutOpCheckMultisig(defaultKeys, defaultThreshold); Script emergencyScript = createMultiSigScript(emergencyKeys, emergencyThreshold); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( - defaultScript, - emergencyScript, - activationDelayValue) + defaultScript, + emergencyScript, + activationDelayValue) ); assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); } @@ -200,27 +202,27 @@ void createInvalidErpFederation_invalidEmergencyRedeemScript_withoutOpCheckMulti Script defaultScript = createMultiSigScript(defaultKeys, defaultThreshold); Script emergencyScript = createMultiSigScriptWithoutOpCheckMultisig(emergencyKeys, emergencyThreshold); - ErpFederationCreationException exception = assertThrows( - ErpFederationCreationException.class, + RedeemScriptCreationException exception = assertThrows( + RedeemScriptCreationException.class, () -> ErpRedeemScriptBuilderUtils.validateRedeemScriptValues( - defaultScript, - emergencyScript, - activationDelayValue) + defaultScript, + emergencyScript, + activationDelayValue) ); assertEquals(INVALID_INTERNAL_REDEEM_SCRIPTS, exception.getReason()); } private Script createMultiSigScript(List keys, - int threshold) { - ScriptBuilder scriptBuilder = new ScriptBuilder(); - scriptBuilder.smallNum(threshold); - for (BtcECKey key : keys) { - scriptBuilder.data(key.getPubKey()); - } - scriptBuilder.smallNum(keys.size()); - scriptBuilder.op(OP_CHECKMULTISIG); - - return scriptBuilder.build(); + int threshold) { + ScriptBuilder scriptBuilder = new ScriptBuilder(); + scriptBuilder.smallNum(threshold); + for (BtcECKey key : keys) { + scriptBuilder.data(key.getPubKey()); + } + scriptBuilder.smallNum(keys.size()); + scriptBuilder.op(OP_CHECKMULTISIG); + + return scriptBuilder.build(); } private Script createMultiSigScriptWithoutThreshold(List keys) { @@ -235,7 +237,7 @@ private Script createMultiSigScriptWithoutThreshold(List keys) { } private Script createMultiSigScriptWithoutKeysSize(List keys, - int threshold) { + int threshold) { ScriptBuilder scriptBuilder = new ScriptBuilder(); scriptBuilder.smallNum(threshold); for (BtcECKey key : keys) { @@ -257,4 +259,4 @@ private Script createMultiSigScriptWithoutOpCheckMultisig(List keys, return scriptBuilder.build(); } -} +} \ No newline at end of file diff --git a/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java index c6b0179bf6f..678f3487a3e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java @@ -52,8 +52,8 @@ class NonStandardErpFederationsTest { private ErpFederation federation; private NetworkParameters networkParameters; - private int defaultThreshold; private List defaultKeys; + private int defaultThreshold; private List emergencyKeys; private int emergencyThreshold; private long activationDelayValue; @@ -110,7 +110,7 @@ private ErpFederation createDefaultNonStandardErpFederation() { } @Test - void createInvalidLegacyErpFederation_nullErpKeys() { + void createFederation_withNullErpKeys_throwsErpFederationCreationException() { emergencyKeys = null; ErpFederationCreationException exception = assertThrows( ErpFederationCreationException.class, this::createDefaultNonStandardErpFederation @@ -119,7 +119,7 @@ void createInvalidLegacyErpFederation_nullErpKeys() { } @Test - void createInvalidLegacyErpFederation_emptyErpKeys() { + void createFederation_withEmptyErpKeys_throwsErpFederationCreationException() { emergencyKeys = new ArrayList<>(); ErpFederationCreationException exception = assertThrows( ErpFederationCreationException.class, this::createDefaultNonStandardErpFederation @@ -128,7 +128,7 @@ void createInvalidLegacyErpFederation_emptyErpKeys() { } @Test - void createValidLegacyErpFederation_oneErpKey() { + void createFederation_withOneErpKey_valid() { emergencyKeys = Collections.singletonList(emergencyKeys.get(0)); emergencyThreshold = emergencyKeys.size() / 2 + 1; @@ -142,35 +142,37 @@ void createValidLegacyErpFederation_oneErpKey() { @ParameterizedTest @ValueSource(longs = { 130L, 500L, 33_000L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE}) - void createValidNonStandardErpFederation_csvValues_post_RSKIP293(long csvValue) { + void createFederation_postRSKIP293_withValidCsvValues_valid(long csvValue) { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); activationDelayValue = csvValue; createAndValidateFederation(); + + // Also check the builder is the expected one considering the activations ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); assertTrue(builder instanceof NonStandardErpRedeemScriptBuilder); } @Test - void createErpRedeemScriptWithCsvUnsignedBE_csvValueOneByteLong_post_RSKIP284_pre_RSKIP293() { - // should create the redeem script with NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE + void createFederation_postRSKIP284_preRSKIP293_withValidCsvValueOneByteLong_valid() { networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - // For a value that only uses 1 byte it should add leading zeroes to complete 2 bytes activationDelayValue = 20L; - + // For a value that only uses 1 byte it should add leading zeroes to complete 2 bytes createAndValidateFederation(); + + // Also check the builder is the expected one considering the activations ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); assertTrue(builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE); } @ParameterizedTest @ValueSource(longs = {-100L, 0L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1, 100_000L, 8_400_000L }) - void createInvalidNonStandardErpFederation_csvValues_post_RSKIP293(long csvValue) { + void createFederation_postRSKIP293_withInvalidCsvValues_throwsErpFederationCreationException(long csvValue) { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); @@ -182,7 +184,8 @@ void createInvalidNonStandardErpFederation_csvValues_post_RSKIP293(long csvValue () -> federation.getRedeemScript()); assertEquals(REDEEM_SCRIPT_CREATION_FAILED, fedException.getReason()); - ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); + // Check the builder throws the particular expected exception + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); RedeemScriptCreationException exception = assertThrows( RedeemScriptCreationException.class, () -> builder.createRedeemScriptFromKeys( @@ -194,7 +197,7 @@ void createInvalidNonStandardErpFederation_csvValues_post_RSKIP293(long csvValue } @Test - void createInvalidNonStandardBuilder_aboveMaxRedeemScriptSize() { + void createFederation_withRedeemScriptSizeAboveMaximum_throwsScriptCreationException() { // add one member to exceed redeem script size limit List newDefaultKeys = federation.getBtcPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( @@ -307,25 +310,11 @@ void testEquals_differentMembers() { } @Test - void createLegacyErpRedeemScript_fromNonStandardErpBuilders() { - ErpRedeemScriptBuilder builder; - Script obtainedRedeemScript; - byte[] expectedRedeemScriptProgram; - - // the emergency keys and csvValue are the same for all non-standard feds - BtcECKey emergency0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3")); - BtcECKey emergency1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f14")); - BtcECKey emergency2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f")); - emergencyKeys = Arrays.asList( - emergency0PublicKey, emergency1PublicKey, emergency2PublicKey - ); - emergencyThreshold = emergencyKeys.size() / 2 + 1; - activationDelayValue = 52_560L; - - // test NonStandardErpRedeemScriptBuilderHardcoded - expectedRedeemScriptProgram = // this is the redeem script program from fed non-standard hardcoded + void createdRedeemScriptProgramFromNonStandardErpBuilderHardcoded_withRealValues_equalsRealRedeemScriptProgram_testnet() { + byte[] expectedRedeemScriptProgram = // this is the redeem script program from non-standard hardcoded fed Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f42102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da210344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a0921039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb955670300cd50b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); + // these values belong to the non-standard hardcoded fed BtcECKey federator0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce")); BtcECKey federator1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f4")); BtcECKey federator2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed6")); @@ -337,48 +326,107 @@ void createLegacyErpRedeemScript_fromNonStandardErpBuilders() { ); defaultThreshold = defaultKeys.size() / 2 + 1; + BtcECKey emergency0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3")); + BtcECKey emergency1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f14")); + BtcECKey emergency2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f")); + emergencyKeys = Arrays.asList( + emergency0PublicKey, emergency1PublicKey, emergency2PublicKey + ); + emergencyThreshold = emergencyKeys.size() / 2 + 1; + activationDelayValue = 52_560L; + + // we should activate testnet network + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + + // this should create the expected non-standard hardcoded fed federation = createDefaultNonStandardErpFederation(); - builder = new NonStandardErpRedeemScriptBuilderHardcoded(); - obtainedRedeemScript = builder + + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + Script obtainedRedeemScript = builder .createRedeemScriptFromKeys(defaultKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue ); assertArrayEquals(expectedRedeemScriptProgram, obtainedRedeemScript.getProgram()); + } - - // test NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE - expectedRedeemScriptProgram = // this is the redeem script program from fed non-standard with unsigned csv + @Test + void createdRedeemScriptProgramFromNonStandardErpBuilderCsvUnsignedBE_withRealValues_equalsRealRedeemScriptProgram_mainnet() { + byte[] expectedRedeemScriptProgram = // this is the redeem script program from fed non-standard with unsigned csv Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f421025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed62102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da210344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a09556702cd50b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); - federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a09")); + + // these values belong to the non-standard csv unsigned be fed + BtcECKey federator0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce")); + BtcECKey federator1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f4")); + BtcECKey federator2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed6")); + BtcECKey federator3PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da")); + BtcECKey federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a09")); defaultKeys = Arrays.asList( federator0PublicKey, federator1PublicKey, federator2PublicKey, federator3PublicKey, federator4PublicKey ); + defaultThreshold = defaultKeys.size() / 2 + 1; + + BtcECKey emergency0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3")); + BtcECKey emergency1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f14")); + BtcECKey emergency2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f")); + emergencyKeys = Arrays.asList( + emergency0PublicKey, emergency1PublicKey, emergency2PublicKey + ); + emergencyThreshold = emergencyKeys.size() / 2 + 1; + activationDelayValue = 52_560L; + + // we should activate RSKIP284 + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + // this should create the expected non-standard with csv unsigned be fed federation = createDefaultNonStandardErpFederation(); - builder = new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE(); - obtainedRedeemScript = builder - .createRedeemScriptFromKeys(defaultKeys, defaultThreshold, + + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + Script obtainedRedeemScript = builder + .createRedeemScriptFromKeys( + defaultKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue ); assertArrayEquals(expectedRedeemScriptProgram, obtainedRedeemScript.getProgram()); + } - - // test NonStandardErpRedeemScriptBuilder - expectedRedeemScriptProgram = // this is the redeem script program from fed non-standard + @Test + void createdRedeemScriptProgramFromNonStandardErpBuilder_withRealValues_equalsRealRedeemScriptProgram_mainnet() { + byte[] expectedRedeemScriptProgram = // this is the redeem script program from fed non-standard Hex.decode("6453210208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce210225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f421025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed62102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da2103fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce858155670350cd00b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f5368ae"); - federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("03fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce8581")); + // these values belong to the non-standard fed + BtcECKey federator0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce")); + BtcECKey federator1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f4")); + BtcECKey federator2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed6")); + BtcECKey federator3PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da")); + BtcECKey federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("03fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce8581")); defaultKeys = Arrays.asList( federator0PublicKey, federator1PublicKey, federator2PublicKey, federator3PublicKey, federator4PublicKey ); + defaultThreshold = defaultKeys.size() / 2 + 1; + + BtcECKey emergency0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3")); + BtcECKey emergency1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f14")); + BtcECKey emergency2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f")); + emergencyKeys = Arrays.asList( + emergency0PublicKey, emergency1PublicKey, emergency2PublicKey + ); + emergencyThreshold = emergencyKeys.size() / 2 + 1; + activationDelayValue = 52_560L; + + // we should activate RSKIP284 and RSKIP293 + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + + // this should create the expected non-standard fed federation = createDefaultNonStandardErpFederation(); - builder = new NonStandardErpRedeemScriptBuilder(); - obtainedRedeemScript = builder + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + Script obtainedRedeemScript = builder .createRedeemScriptFromKeys(defaultKeys, defaultThreshold, emergencyKeys, emergencyThreshold, activationDelayValue @@ -387,54 +435,38 @@ void createLegacyErpRedeemScript_fromNonStandardErpBuilders() { } @Test - void getP2SHScriptAndAddress() { - // standard and emergency keys from last real non-standard erp fed in testnet - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + void createdFederationInfo_withRealValues_equalsExistingFederationInfo_testnet() { + // values from last real non-standard erp fed in testnet BridgeConstants bridgeTestNetConstants = BridgeTestNetConstants.getInstance(); networkParameters = bridgeTestNetConstants.getBtcParams(); emergencyKeys = bridgeTestNetConstants.getErpFedPubKeysList(); activationDelayValue = bridgeTestNetConstants.getErpFedActivationDelay(); - defaultKeys = Arrays.asList( - BtcECKey.fromPublicOnly( - Hex.decode("0208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce") - ), - BtcECKey.fromPublicOnly( - Hex.decode("0225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f4") - ), - BtcECKey.fromPublicOnly( - Hex.decode("025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed6") - ), - BtcECKey.fromPublicOnly( - Hex.decode("02afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da") - ), - BtcECKey.fromPublicOnly( - Hex.decode("0344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a09") - ) - ); + defaultKeys = Arrays.stream(new String[]{ + "0208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce", + "0225e892391625854128c5c4ea4340de0c2a70570f33db53426fc9c746597a03f4", + "025a2f522aea776fab5241ad72f7f05918e8606676461cb6ce38265a52d4ca9ed6", + "02afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da", + "0344a3c38cd59afcba3edcebe143e025574594b001700dec41e59409bdbd0f2a09", + }).map(hex -> BtcECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); + String expectedProgram = "a91412d5d2996618c8abcb1e6fc17be3cd8e2790c25f87"; + Address expectedAddress = Address.fromBase58(networkParameters, "2MtxpJPt2xCa3AyFYUjTT7Aop9Z6gGf4rqA"); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + // this should create the real fed ErpFederation realLegacyErpFederation = createDefaultNonStandardErpFederation(); Script p2shScript = realLegacyErpFederation.getP2SHScript(); Address address = realLegacyErpFederation.getAddress(); - String expectedProgram = "a91412d5d2996618c8abcb1e6fc17be3cd8e2790c25f87"; - Address expectedAddress = Address.fromBase58( - networkParameters, - "2MtxpJPt2xCa3AyFYUjTT7Aop9Z6gGf4rqA" - ); - assertEquals(expectedProgram, Hex.toHexString(p2shScript.getProgram())); assertEquals(3, p2shScript.getChunks().size()); - assertEquals( - address, - p2shScript.getToAddress(networkParameters) - ); + assertEquals(address, p2shScript.getToAddress(networkParameters)); assertEquals(expectedAddress, address); } @Test - void getErpPubKeys_uncompressed_public_keys() { + void getErpPubKeys_fromUncompressedPublicKeys_equals() { // Public keys used for creating federation, but uncompressed format now emergencyKeys = emergencyKeys .stream() @@ -657,6 +689,8 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { List federationMembersWithBtcKeys = FederationTestUtils.getFederationMembersWithBtcKeys(standardMultisigKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); assertThrows(ErpFederationCreationException.class, () -> new ErpFederation( federationMembersWithBtcKeys, creationTime, @@ -664,7 +698,7 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { btcParams, emergencyMultisigKeys, activationDelay, - new NonStandardErpRedeemScriptBuilder() + builder )); } @@ -975,4 +1009,4 @@ private List parseFed(List fed) { return fed.stream().map(Hex::decode).map(BtcECKey::fromPublicOnly).collect(Collectors.toList()); } } -} \ No newline at end of file +} diff --git a/rskj-core/src/test/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactoryTest.java b/rskj-core/src/test/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactoryTest.java new file mode 100644 index 00000000000..6666f53d57e --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/peg/NonStandardErpRedeemScriptBuilderFactoryTest.java @@ -0,0 +1,77 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.peg.bitcoin.*; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ArgumentsSource; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + +import java.util.stream.Stream; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class NonStandardErpRedeemScriptBuilderFactoryTest { + + ActivationConfig.ForBlock activations; + NetworkParameters networkParameters; + + @BeforeEach + void setUp() { + activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + } + + @Test + void preRSKIP284_returns_builderHardcoded_testnet() { + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + + ErpRedeemScriptBuilder builder = + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + + Assertions.assertTrue(builder instanceof NonStandardErpRedeemScriptBuilderHardcoded); + } + + @Test + void preRSKIP284_doesnt_return_builderHardcoded_mainnet() { + networkParameters = NetworkParameters.fromID(NetworkParameters.ID_MAINNET); + + ErpRedeemScriptBuilder builder = + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + + Assertions.assertFalse(builder instanceof NonStandardErpRedeemScriptBuilderHardcoded); + } + + @ParameterizedTest + @MethodSource("provideNetworkParameters") + void postRSKIP284_preRSKIP293_returns_builderWithCsvUnsignedBE(NetworkParameters networkParameters) { + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + + ErpRedeemScriptBuilder builder = + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + Assertions.assertTrue(builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE); + } + + @ParameterizedTest + @MethodSource("provideNetworkParameters") + void postRSKIP293_returns_builder(NetworkParameters networkParameters) { + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + + ErpRedeemScriptBuilder builder = + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + Assertions.assertTrue(builder instanceof NonStandardErpRedeemScriptBuilder); + } + + // network parameters provider + private static Stream provideNetworkParameters() { + return Stream.of(NetworkParameters.ID_TESTNET, NetworkParameters.ID_MAINNET) + .map(NetworkParameters::fromID); + } +} diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index 7709e212fd0..14a0dd93d08 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -45,12 +45,11 @@ class P2shErpFederationTest { private ErpFederation federation; private NetworkParameters networkParameters; - private int defaultThreshold; private List defaultKeys; + private int defaultThreshold; private List emergencyKeys; private int emergencyThreshold; private long activationDelayValue; - private ActivationConfig.ForBlock activations; @BeforeEach void setup() { @@ -78,7 +77,6 @@ void setup() { networkParameters = bridgeConstants.getBtcParams(); - activations = mock(ActivationConfig.ForBlock.class); federation = createDefaultP2shErpFederation(); } @@ -110,7 +108,7 @@ private void createAndValidateFederation() { } @Test - void createInvalidP2shErpFederation_nullErpKeys() { + void createFederation_withNullErpKeys_throwsErpFederationCreationException() { emergencyKeys = null; ErpFederationCreationException exception = assertThrows( @@ -120,7 +118,7 @@ void createInvalidP2shErpFederation_nullErpKeys() { } @Test - void createInvalidP2shErpFederation_emptyErpKeys() { + void createFederation_withEmptyErpKeys_throwsErpFederationCreationException() { emergencyKeys = new ArrayList<>(); ErpFederationCreationException exception = assertThrows( @@ -130,14 +128,14 @@ void createInvalidP2shErpFederation_emptyErpKeys() { } @Test - void createValidP2shErpFederation_oneErpKey() { + void createFederation_withOneErpKey_valid() { emergencyKeys = Collections.singletonList(emergencyKeys.get(0)); createAndValidateFederation(); } @ParameterizedTest @ValueSource(longs = {20L, 130L, 500L, 33_000L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE}) - void createValidP2shErpFederation_csvValues(long csvValue) { + void createFederation_withValidCsvValues_valid(long csvValue) { activationDelayValue = csvValue; createAndValidateFederation(); @@ -145,7 +143,7 @@ void createValidP2shErpFederation_csvValues(long csvValue) { @ParameterizedTest @ValueSource(longs = {-100L, 0L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE + 1, 100_000L, 8_400_000L}) - void createInvalidP2shErpFederation_invalidCsvValues(long csvValue) { + void createFederation_invalidCsvValues_throwsErpFederationCreationException(long csvValue) { activationDelayValue = csvValue; federation = createDefaultP2shErpFederation(); @@ -154,7 +152,8 @@ void createInvalidP2shErpFederation_invalidCsvValues(long csvValue) { () -> federation.getRedeemScript()); assertEquals(REDEEM_SCRIPT_CREATION_FAILED, fedException.getReason()); - ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + // Check the builder throws the particular expected exception + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); RedeemScriptCreationException builderException = assertThrows( RedeemScriptCreationException.class, () -> builder.createRedeemScriptFromKeys( @@ -166,7 +165,7 @@ void createInvalidP2shErpFederation_invalidCsvValues(long csvValue) { } @Test - void createInvalidFederation_aboveMaxRedeemScriptSize() { + void createFederation_withRedeemScriptSizeAboveMaximum_throwsScriptCreationException() { // add one member to exceed redeem script size limit List newDefaultKeys = federation.getBtcPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( @@ -175,7 +174,7 @@ void createInvalidFederation_aboveMaxRedeemScriptSize() { newDefaultKeys.add(federator10PublicKey); defaultKeys = newDefaultKeys; - ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); ScriptCreationException exception = assertThrows( ScriptCreationException.class, () -> builder.createRedeemScriptFromKeys( @@ -256,8 +255,7 @@ void testEquals_differentMembers() { } @Test - void createP2shRedeemScript_fromP2shErpBuilder() { - + void createdRedeemScriptProgramFromP2shErpBuilder_withRealValues_equalsRealRedeemScriptProgram() { // this is a known redeem script program byte[] redeemScriptProgram = Hex.decode("64542102099fd69cf6a350679a05593c3ff814bfaa281eb6dde505c953cf2875979b120921022a159227df514c7b7808ee182ae07d71770b67eda1e5ee668272761eefb2c24c210233bc8c1a994a921d7818f93e57a559373133ba531928843bf84c59c15e47eab02102937df9948c6f18359e473beeee0a19c27dd4f6d4114e5809aa862671bb765b5b2102afc230c2d355b1a577682b07bc2646041b5d0177af0f98395a46018da699b6da2103db2ebad883823cefe8b2336c03b8d9c6afee4cbac77c7e935bc8c51ec20b26632103fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce858157ae670350cd00b27552210216c23b2ea8e4f11c3f9e22711addb1d16a93964796913830856b568cc3ea21d3210275562901dd8faae20de0a4166362a4f82188db77dbed4ca887422ea1ec185f1421034db69f2112f4fb1bb6141bf6e2bd6631f0484d0bd95b16767902c9fe219d4a6f53ae68"); @@ -287,7 +285,7 @@ void createP2shRedeemScript_fromP2shErpBuilder() { createAndValidateFederation(); - ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); Script obtainedRedeemScript = builder.createRedeemScriptFromKeys( defaultKeys, defaultThreshold, @@ -352,7 +350,8 @@ void getStandardRedeemScript() { } @Test - void getPowPegAddressAndP2shScript_testnet() { + void createdFederationInfo_withRealValues_equalsExistingFederationInfo_testnet() { + // these values belong to a real federation BridgeConstants bridgeTestNetConstants = BridgeTestNetConstants.getInstance(); networkParameters = bridgeTestNetConstants.getBtcParams(); emergencyKeys = bridgeTestNetConstants.getErpFedPubKeysList(); @@ -367,28 +366,23 @@ void getPowPegAddressAndP2shScript_testnet() { "03db2ebad883823cefe8b2336c03b8d9c6afee4cbac77c7e935bc8c51ec20b2663", "03fb8e1d5d0392d35ca8c3656acb6193dbf392b3e89b9b7b86693f5c80f7ce8581", }).map(hex -> BtcECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); + String expectedProgram = "a914007c29a1d854639220aefca2587cdde07f381f4787"; + Address expectedAddress = Address.fromBase58(networkParameters, "2MsHnjFiAt5srgHJtwnwZTtZQPrKN8yiDqh"); + // this should create the real fed ErpFederation realP2shErpFederation = createDefaultP2shErpFederation(); - Script p2shScript = realP2shErpFederation.getP2SHScript(); - Address address = realP2shErpFederation.getAddress(); - - String expectedProgram = "a914007c29a1d854639220aefca2587cdde07f381f4787"; - Address expectedAddress = Address.fromBase58( - networkParameters, - "2MsHnjFiAt5srgHJtwnwZTtZQPrKN8yiDqh" - ); + Script realP2shScript = realP2shErpFederation.getP2SHScript(); + Address realAddress = realP2shErpFederation.getAddress(); - assertEquals(expectedProgram, Hex.toHexString(p2shScript.getProgram())); - assertEquals(3, p2shScript.getChunks().size()); - assertEquals( - address, - p2shScript.getToAddress(networkParameters) - ); - assertEquals(expectedAddress, address); + assertEquals(expectedProgram, Hex.toHexString(realP2shScript.getProgram())); + assertEquals(3, realP2shScript.getChunks().size()); + assertEquals(realAddress, realP2shScript.getToAddress(networkParameters)); + assertEquals(expectedAddress, realAddress); } @Test - void getPowPegAddressAndP2shScript_mainnet() { + void createdFederationInfo_withRealValues_equalsExistingFederationInfo_mainnet() { + // these values belong to a real federation BridgeConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); networkParameters = bridgeMainNetConstants.getBtcParams(); emergencyKeys = bridgeMainNetConstants.getErpFedPubKeysList(); @@ -405,17 +399,17 @@ void getPowPegAddressAndP2shScript_mainnet() { "03e05bf6002b62651378b1954820539c36ca405cbb778c225395dd9ebff6780299", "03b58a5da144f5abab2e03e414ad044b732300de52fa25c672a7f7b35888771906" }).map(hex -> BtcECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); - - ErpFederation realP2shErpFederation = createDefaultP2shErpFederation(); - Script p2shScript = realP2shErpFederation.getP2SHScript(); - Address address = realP2shErpFederation.getAddress(); - String expectedProgram = "a9142c1bab6ea51fdaf85c8366bd2b1502eaa69b6ae687"; Address expectedAddress = Address.fromBase58( networkParameters, "35iEoWHfDfEXRQ5ZWM5F6eMsY2Uxrc64YK" ); + // this should create the real fed + ErpFederation realP2shErpFederation = createDefaultP2shErpFederation(); + Script p2shScript = realP2shErpFederation.getP2SHScript(); + Address address = realP2shErpFederation.getAddress(); + assertEquals(expectedProgram, Hex.toHexString(p2shScript.getProgram())); assertEquals(3, p2shScript.getChunks().size()); assertEquals( @@ -426,7 +420,7 @@ void getPowPegAddressAndP2shScript_mainnet() { } @Test - void getErpPubKeys_uncompressed_public_keys() { + void getErpPubKeys_fromUncompressedPublicKeys_equals() { // Public keys used for creating federation, but uncompressed format now emergencyKeys = emergencyKeys .stream() diff --git a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java index e9807dce5c2..aaba819daaa 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java @@ -26,6 +26,7 @@ import co.rsk.config.BridgeConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.simples.SimpleRskTransaction; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -308,16 +309,16 @@ public static Federation createFederation(BridgeConstants bridgeConstants, List< ); } - public static P2shErpFederation createP2shErpFederation(BridgeConstants bridgeConstants, List federationKeys) { + public static ErpFederation createP2shErpFederation(BridgeConstants bridgeConstants, List federationKeys) { federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - return new P2shErpFederation( + return new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys), Instant.ofEpochMilli(1000L), 0L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - Mockito.mock(ActivationConfig.ForBlock.class) + new P2shErpRedeemScriptBuilder() ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java index c045e66559b..a6cb23f11b5 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java @@ -56,7 +56,7 @@ class PegUtilsGetTransactionTypeTest { private Address userAddress; private List retiredFedSigners; - private P2shErpFederation retiredFed; + private ErpFederation retiredFed; private List retiringFedSigners; private Federation retiringFederation; @@ -2173,7 +2173,7 @@ void last_retired_fed_to_live_fed( // Arrange BridgeStorageProvider provider = mock(BridgeStorageProvider.class); - when(provider.getLastRetiredFederationP2SHScript()).thenReturn(Optional.of(retiredFed.getStandardP2SHScript())); + when(provider.getLastRetiredFederationP2SHScript()).thenReturn(Optional.of(retiredFed.getDefaultP2SHScript())); BtcTransaction migrationTx = new BtcTransaction(btcMainnetParams); diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java index 3c07ff42ad1..1d09e818f43 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java @@ -22,6 +22,8 @@ import java.util.Collections; import java.util.List; import java.util.stream.Stream; + +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; @@ -69,28 +71,28 @@ void test_sentFromP2SHErpFed() { ); // Arrange - Federation activeFederation = new P2shErpFederation( + Federation activeFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), bridgeMainnetConstants.getGenesisFederation().getCreationTime(), 5L, bridgeMainnetConstants.getGenesisFederation().getBtcParams(), bridgeMainnetConstants.getErpFedPubKeysList(), bridgeMainnetConstants.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); List fedKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - P2shErpFederation p2shRetiringFederation = new P2shErpFederation( + ErpFederation p2shRetiringFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, bridgeMainnetConstants.getErpFedPubKeysList(), bridgeMainnetConstants.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); // Create a migrationTx from the p2sh erp fed @@ -343,14 +345,14 @@ void test_pegin( new String[]{"fa04", "fa05", "fa06"}, true ); - Federation activeFederation = new P2shErpFederation( + Federation activeFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFedKeys), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, erpFedKeys, 100L, - activations + new P2shErpRedeemScriptBuilder() ); BtcTransaction peginTx = new BtcTransaction(btcMainnetParams); diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java index 1f4bef6b3cd..0096e80b33e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java @@ -23,6 +23,9 @@ import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.btcLockSender.BtcLockSender; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -819,14 +822,16 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_beforeRskip ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder + = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - activations + erpRedeemScriptBuilder ); // Create a tx from the retired fast bridge fed to the active fed @@ -882,14 +887,16 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder + = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - activations + erpRedeemScriptBuilder ); // Create a tx from the retired fast bridge fed to the active fed @@ -944,14 +951,16 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder + = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - activations + erpRedeemScriptBuilder ); // Create a tx from the retired erp fed to the active fed @@ -1002,14 +1011,16 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_afterRskip201_notP ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder + = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - activations + erpRedeemScriptBuilder ); // Create a tx from the retired erp fed to the active fed @@ -1251,14 +1262,14 @@ private void testIsValidPegInTx_fromP2shErpScriptSender( List emergencyKeys = PegTestUtils.createRandomBtcECKeys(3); long activationDelay = 256L; - Federation p2shErpFederation = new P2shErpFederation( + Federation p2shErpFederation = new ErpFederation( activeFederation.getMembers(), activeFederation.getCreationTime(), activeFederation.getCreationBlockNumber(), networkParameters, emergencyKeys, activationDelay, - activations + new P2shErpRedeemScriptBuilder() ); Script flyoverP2shErpRedeemScript = FastBridgeP2shErpRedeemScriptParser.createFastBridgeP2shErpRedeemScript( @@ -1318,14 +1329,14 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - P2shErpFederation retiredFederation = new P2shErpFederation( + ErpFederation retiredFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); List activeFederationKeys = Stream.of( @@ -1333,14 +1344,14 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new P2shErpFederation( + Federation activeFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1372,7 +1383,7 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() migrationTx, activeFederation, null, - retiredFederation.getStandardP2SHScript(), + retiredFederation.getDefaultP2SHScript(), federationWallet, bridgeConstantsMainnet.getMinimumPeginTxValue(activations), activations @@ -1390,14 +1401,14 @@ void testIsMigrationTx_sending_funds_from_retiring_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = new P2shErpFederation( + Federation retiringFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFed), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); List activeFederationKeys = Stream.of( @@ -1405,14 +1416,14 @@ void testIsMigrationTx_sending_funds_from_retiring_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new P2shErpFederation( + Federation activeFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1464,14 +1475,14 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_p2sh_fe BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new P2shErpFederation( + Federation activeFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1533,14 +1544,14 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_p2sh_f BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new P2shErpFederation( + Federation activeFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1967,14 +1978,16 @@ void testIsPegOutTx_fromErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - LegacyErpFederation erpFederation = new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder + = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + ErpFederation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - activations + erpRedeemScriptBuilder ); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -2004,7 +2017,7 @@ void testIsPegOutTx_fromErpFederation() { assertFalse(isPegOutTx(pegOutTx1, activations, standardFederation.getP2SHScript())); assertFalse(isPegOutTx(pegOutTx1, Collections.singletonList(erpFederation), activations)); - assertFalse(isPegOutTx(pegOutTx1, activations, erpFederation.getStandardP2SHScript())); + assertFalse(isPegOutTx(pegOutTx1, activations, erpFederation.getDefaultP2SHScript())); // After RSKIP 201 activation when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); @@ -2018,7 +2031,7 @@ void testIsPegOutTx_fromErpFederation() { assertFalse(isPegOutTx(pegOutTx1, activations, standardFederation.getP2SHScript())); assertTrue(isPegOutTx(pegOutTx1, Collections.singletonList(erpFederation), activations)); - assertTrue(isPegOutTx(pegOutTx1, activations, erpFederation.getStandardP2SHScript())); + assertTrue(isPegOutTx(pegOutTx1, activations, erpFederation.getDefaultP2SHScript())); } @Test @@ -2043,14 +2056,16 @@ void testIsPegOutTx_fromFlyoverErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new LegacyErpFederation( + ErpRedeemScriptBuilder erpRedeemScriptBuilder + = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); + Federation erpFederation = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - activations + erpRedeemScriptBuilder ); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); 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 7596212a01f..f8a47a9c66b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java @@ -16,6 +16,7 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.test.builders.BridgeSupportBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -209,14 +210,14 @@ void test_getTransactionType_pegin_output_to_retiring_fed_and_other_addresses() List signers = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - P2shErpFederation activeFed = new P2shErpFederation( + ErpFederation activeFed = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(signers), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, bridgeMainnetConstants.getErpFedPubKeysList(), bridgeMainnetConstants.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); @@ -612,14 +613,14 @@ void test_getTransactionType_flyover_segwit() { List signers = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - P2shErpFederation activeFed = new P2shErpFederation( + ErpFederation activeFed = new ErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(signers), Instant.ofEpochMilli(1000L), 0L, btcTestNetParams, bridgeTestNetConstants.getErpFedPubKeysList(), bridgeTestNetConstants.getErpFedActivationDelay(), - activations + new P2shErpRedeemScriptBuilder() ); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); diff --git a/rskj-core/src/test/java/co/rsk/peg/bitcoin/PocSighashTest.java b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/bitcoin/PocSighashTest.java rename to rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java index 02076c05b48..66fb45715d6 100644 --- a/rskj-core/src/test/java/co/rsk/peg/bitcoin/PocSighashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java @@ -1,4 +1,4 @@ -package co.rsk.peg.bitcoin; +package co.rsk.peg; import co.rsk.bitcoinj.core.Address; import co.rsk.bitcoinj.core.BtcECKey; @@ -14,11 +14,8 @@ import co.rsk.bitcoinj.wallet.RedeemData; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; -import co.rsk.peg.ErpFederation; -import co.rsk.peg.Federation; -import co.rsk.peg.FederationMember; -import co.rsk.peg.P2shErpFederation; -import co.rsk.peg.PegTestUtils; +import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -82,14 +79,14 @@ void test_each_input_sighash_is_unique(NetworkParameters networkParameters) { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - P2shErpFederation fed = new P2shErpFederation( + ErpFederation fed = new ErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), erpFedActivationDelay, - activations + new P2shErpRedeemScriptBuilder() ); List utxos = new ArrayList<>(); @@ -156,14 +153,14 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - P2shErpFederation fed = new P2shErpFederation( + ErpFederation fed = new ErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), erpFedActivationDelay, - activations + new P2shErpRedeemScriptBuilder() ); List utxos = new ArrayList<>(); @@ -253,14 +250,14 @@ void test_sighash_is_equal_for_signed_input_and_unsigned_input(NetworkParameters when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - P2shErpFederation fed = new P2shErpFederation( + ErpFederation fed = new ErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), erpFedActivationDelay, - activations + new P2shErpRedeemScriptBuilder() ); List utxos = new ArrayList<>(); @@ -315,14 +312,14 @@ void test_each_input_sighash_is_unique_using_real_tx_testnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - P2shErpFederation fed = new P2shErpFederation( + ErpFederation fed = new ErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), erpFedActivationDelay, - activations + new P2shErpRedeemScriptBuilder() ); Address expectedAddress = Address.fromBase58( @@ -401,14 +398,14 @@ void test_each_input_sighash_is_unique_for_a_signed_erp_tx_testnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - P2shErpFederation fed = new P2shErpFederation( + ErpFederation fed = new ErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), erpFedActivationDelay, - activations + new P2shErpRedeemScriptBuilder() ); Address expectedAddress = Address.fromBase58( @@ -492,14 +489,14 @@ void test_redeemScript_can_be_obtained_from_input() { FedSigner::getFed ).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); - P2shErpFederation fed = new P2shErpFederation( + ErpFederation fed = new ErpFederation( fedMembers, Instant.now(), 0L, networkParameters, erpPubKeys, erpFedActivationDelay, - activations + new P2shErpRedeemScriptBuilder() ); Address expectedAddress = Address.fromBase58( @@ -632,7 +629,7 @@ private Script createInputScriptWithSignature( scriptBuilder = scriptBuilder.number(0); signaturesEncoded.forEach(scriptBuilder::data); - if (federation instanceof P2shErpFederation || federation instanceof ErpFederation){ + if (federation instanceof ErpFederation){ int flowOpCode = signWithTheEmergencyMultisig ? 1 : 0; scriptBuilder.number(flowOpCode); } From e2d410e4697a5542077e5d2f14a90bd3b0f0b768 Mon Sep 17 00:00:00 2001 From: julia zack Date: Wed, 6 Dec 2023 13:29:06 -0300 Subject: [PATCH 035/137] Create FederationFactory to create federations without inconsistency between redeem script and format version. Adapt to that change. Move Federation related files to new federation package --- .../java/co/rsk/config/BridgeConstants.java | 2 +- .../co/rsk/config/BridgeDevNetConstants.java | 4 +- .../co/rsk/config/BridgeMainNetConstants.java | 4 +- .../co/rsk/config/BridgeRegTestConstants.java | 4 +- .../co/rsk/config/BridgeTestNetConstants.java | 4 +- .../src/main/java/co/rsk/peg/Bridge.java | 1 + .../main/java/co/rsk/peg/BridgeBtcWallet.java | 1 + .../co/rsk/peg/BridgeSerializationUtils.java | 27 ++- .../co/rsk/peg/BridgeStorageProvider.java | 104 +++++------ .../main/java/co/rsk/peg/BridgeSupport.java | 3 + .../src/main/java/co/rsk/peg/BridgeUtils.java | 3 +- .../java/co/rsk/peg/BridgeUtilsLegacy.java | 1 + .../java/co/rsk/peg/FederationSupport.java | 1 + .../rsk/peg/FlyoverCompatibleBtcWallet.java | 1 + ...ompatibleBtcWalletWithMultipleScripts.java | 1 + ...erCompatibleBtcWalletWithSingleScript.java | 1 + ...FlyoverCompatibleBtcWalletWithStorage.java | 1 + .../src/main/java/co/rsk/peg/PegUtils.java | 1 + .../main/java/co/rsk/peg/PegUtilsLegacy.java | 2 + ...StandardErpRedeemScriptBuilderFactory.java | 3 +- .../peg/{ => federation}/ErpFederation.java | 13 +- .../ErpFederationCreationException.java | 2 +- .../rsk/peg/{ => federation}/Federation.java | 17 +- .../rsk/peg/federation/FederationFactory.java | 75 ++++++++ .../federation/FederationFormatVersion.java | 17 ++ .../{ => federation}/PendingFederation.java | 21 +-- .../StandardMultisigFederation.java | 10 +- .../co/rsk/peg/utils/BridgeEventLogger.java | 2 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 2 +- .../peg/utils/BrigeEventLoggerLegacyImpl.java | 2 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 19 +- .../BridgeStorageProviderFederationTests.java | 110 ++++++------ .../co/rsk/peg/BridgeStorageProviderTest.java | 88 +++++----- .../peg/BridgeSupportAddSignatureTest.java | 12 +- .../co/rsk/peg/BridgeSupportFlyoverTest.java | 1 + ...ridgeSupportProcessFundsMigrationTest.java | 4 +- ...idgeSupportRegisterBtcTransactionTest.java | 57 ++---- .../rsk/peg/BridgeSupportReleaseBtcTest.java | 4 +- .../co/rsk/peg/BridgeSupportSigHashTest.java | 6 +- .../java/co/rsk/peg/BridgeSupportTest.java | 45 +++-- .../rsk/peg/BridgeSupportTestIntegration.java | 139 ++++++++++----- .../src/test/java/co/rsk/peg/BridgeTest.java | 6 +- .../co/rsk/peg/BridgeTestIntegration.java | 1 + .../co/rsk/peg/BridgeUtilsLegacyTest.java | 8 +- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 57 +++--- .../co/rsk/peg/FederationSupportTest.java | 14 +- .../java/co/rsk/peg/FederationTestUtils.java | 5 +- ...verCompatibleBtcWalletWithStorageTest.java | 9 +- ...patibleBtcWallextWithSingleScriptTest.java | 17 +- .../peg/NonStandardErpFederationsTest.java | 32 ++-- .../co/rsk/peg/P2shErpFederationTest.java | 39 ++--- .../test/java/co/rsk/peg/PegTestUtils.java | 13 +- ...XOsToFedAreAboveMinimumPeginValueTest.java | 1 + .../co/rsk/peg/PegUtilsEvaluatePeginTest.java | 1 + .../peg/PegUtilsGetTransactionTypeTest.java | 4 +- .../PegUtilsLegacyGetTransactionTypeTest.java | 55 +++--- .../java/co/rsk/peg/PegUtilsLegacyTest.java | 164 +++++++----------- .../test/java/co/rsk/peg/PegUtilsTest.java | 22 +-- .../co/rsk/peg/PendingFederationTest.java | 14 +- .../test/java/co/rsk/peg/PocSighashTest.java | 72 +++----- .../java/co/rsk/peg/PowpegMigrationTest.java | 12 +- .../peg/ReleaseTransactionBuilderTest.java | 11 +- .../peg/StandardMultisigFederationTest.java | 30 ++-- .../peg/performance/ActiveFederationTest.java | 5 +- .../rsk/peg/performance/AddSignatureTest.java | 2 +- .../peg/performance/FederationChangeTest.java | 1 + .../rsk/peg/performance/GetFeePerKbTest.java | 2 +- .../performance/PendingFederationTest.java | 2 +- .../RegisterBtcTransactionTest.java | 1 + .../RegisterFlyoverBtcTransactionTest.java | 1 + .../performance/RetiringFederationTest.java | 6 +- .../StateForBtcReleaseClientTest.java | 2 +- .../peg/utils/BridgeEventLoggerImplTest.java | 7 +- .../BridgeEventLoggerLegacyImplTest.java | 7 +- 74 files changed, 772 insertions(+), 666 deletions(-) rename rskj-core/src/main/java/co/rsk/peg/{ => federation}/ErpFederation.java (90%) rename rskj-core/src/main/java/co/rsk/peg/{ => federation}/ErpFederationCreationException.java (95%) rename rskj-core/src/main/java/co/rsk/peg/{ => federation}/Federation.java (92%) create mode 100644 rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/federation/FederationFormatVersion.java rename rskj-core/src/main/java/co/rsk/peg/{ => federation}/PendingFederation.java (89%) rename rskj-core/src/main/java/co/rsk/peg/{ => federation}/StandardMultisigFederation.java (90%) diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeConstants.java index 8f73bcae7d7..8b8046b18dc 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeConstants.java @@ -22,7 +22,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; -import co.rsk.peg.Federation; +import co.rsk.peg.federation.Federation; import java.util.List; import org.ethereum.config.blockchain.upgrades.ActivationConfig; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java index b07b22bfd2d..13a8a9616cb 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java @@ -23,7 +23,7 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; import co.rsk.peg.FederationMember; -import co.rsk.peg.StandardMultisigFederation; +import co.rsk.peg.federation.FederationFactory; import java.time.Instant; import java.util.Arrays; import java.util.List; @@ -57,7 +57,7 @@ public BridgeDevNetConstants(List federationPublicKeys) { // Expected federation address is: // 2NCEo1RdmGDj6MqiipD6DUSerSxKv79FNWX - genesisFederation = new StandardMultisigFederation( + genesisFederation = FederationFactory.buildStandardMultiSigFederation( federationMembers, genesisFederationAddressCreatedAt, 1L, diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java index fbc7e22470e..510358dd1e9 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java @@ -5,7 +5,7 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; import co.rsk.peg.FederationMember; -import co.rsk.peg.StandardMultisigFederation; +import co.rsk.peg.federation.FederationFactory; import com.google.common.collect.Lists; import java.time.Instant; import java.util.Arrays; @@ -52,7 +52,7 @@ public class BridgeMainNetConstants extends BridgeConstants { // Wednesday, January 3, 2018 12:00:00 AM GMT-03:00 Instant genesisFederationAddressCreatedAt = Instant.ofEpochMilli(1514948400L); - genesisFederation = new StandardMultisigFederation( + genesisFederation = FederationFactory.buildStandardMultiSigFederation( federationMembers, genesisFederationAddressCreatedAt, 1L, diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java index f3d7ef3bdd9..d18c777e46c 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java @@ -23,7 +23,7 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; import co.rsk.peg.FederationMember; -import co.rsk.peg.StandardMultisigFederation; +import co.rsk.peg.federation.FederationFactory; import java.nio.charset.StandardCharsets; import java.time.Instant; import java.time.ZonedDateTime; @@ -55,7 +55,7 @@ public BridgeRegTestConstants(List federationPublicKeys) { Instant genesisFederationCreatedAt = ZonedDateTime.parse("2016-01-01T00:00:00Z").toInstant(); - genesisFederation = new StandardMultisigFederation( + genesisFederation = FederationFactory.buildStandardMultiSigFederation( federationMembers, genesisFederationCreatedAt, 1L, diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java index 21e475843b3..01761605f14 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java @@ -23,7 +23,7 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; import co.rsk.peg.FederationMember; -import co.rsk.peg.StandardMultisigFederation; +import co.rsk.peg.federation.FederationFactory; import java.time.Instant; import java.util.Arrays; import java.util.List; @@ -65,7 +65,7 @@ public class BridgeTestNetConstants extends BridgeConstants { // Currently set to: Monday, October 8, 2018 12:00:00 AM GMT-03:00 Instant genesisFederationAddressCreatedAt = Instant.ofEpochMilli(1538967600l); - genesisFederation = new StandardMultisigFederation( + genesisFederation = FederationFactory.buildStandardMultiSigFederation( federationMembers, genesisFederationAddressCreatedAt, 1L, diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 30b3030fead..fe8502bbb10 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -25,6 +25,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.panic.PanicProcessor; import co.rsk.peg.bitcoin.MerkleBranch; +import co.rsk.peg.federation.Federation; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.utils.BtcTransactionFormatUtils; import co.rsk.peg.whitelist.LockWhitelistEntry; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java b/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java index c777f7b8a17..662fa2747d3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeBtcWallet.java @@ -21,6 +21,7 @@ import co.rsk.bitcoinj.core.Context; import co.rsk.bitcoinj.wallet.RedeemData; import co.rsk.bitcoinj.wallet.Wallet; +import co.rsk.peg.federation.Federation; import java.util.Arrays; import java.util.List; import java.util.Optional; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index c0f39c45d98..85f6d118a34 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -24,9 +24,7 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.CoinbaseInformation; -import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.*; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.whitelist.OneOffWhiteListEntry; import co.rsk.peg.whitelist.UnlimitedWhiteListEntry; @@ -276,7 +274,12 @@ private static StandardMultisigFederation deserializeStandardMultisigFederationW federationMembers.add(member); } - return new StandardMultisigFederation(federationMembers, creationTime, creationBlockNumber, networkParameters); + return FederationFactory.buildStandardMultiSigFederation( + federationMembers, + creationTime, + creationBlockNumber, + networkParameters + ); } /** @@ -328,17 +331,14 @@ public static ErpFederation deserializeLegacyErpFederation( BridgeSerializationUtils::deserializeFederationMember ); - ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); - - return new ErpFederation( + return FederationFactory.buildNonStandardErpFederation( federation.getMembers(), - federation.creationTime, + federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - erpRedeemScriptBuilder + activations ); } @@ -351,14 +351,13 @@ public static ErpFederation deserializeP2shErpFederation( bridgeConstants.getBtcParams(), BridgeSerializationUtils::deserializeFederationMember ); - return new ErpFederation( + return FederationFactory.buildP2shErpFederation( federation.getMembers(), - federation.creationTime, + federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 9c203405054..5a8c8e23ce3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -24,8 +24,8 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.CoinbaseInformation; -import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.PendingFederation; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.whitelist.LockWhitelist; import co.rsk.peg.whitelist.LockWhitelistEntry; @@ -41,6 +41,7 @@ import java.util.*; import static co.rsk.peg.BridgeStorageIndexKey.*; +import static co.rsk.peg.federation.FederationFormatVersion.*; import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; /** @@ -50,9 +51,6 @@ * @author Oscar Guindzberg */ public class BridgeStorageProvider { - protected static final int STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION = 1000; - protected static final int LEGACY_ERP_FEDERATION_FORMAT_VERSION = 2000; - protected static final int P2SH_ERP_FEDERATION_FORMAT_VERSION = 3000; // Dummy value to use when saving key only indexes private static final byte TRUE_VALUE = (byte) 1; @@ -363,25 +361,10 @@ public void saveNewFederation() { RepositorySerializer serializer = BridgeSerializationUtils::serializeFederationOnlyBtcKeys; if (activations.isActive(RSKIP123)) { - if (newFederation instanceof ErpFederation) { - ErpRedeemScriptBuilder builder = ((ErpFederation) newFederation).getErpRedeemScriptBuilder(); - if (builder instanceof P2shErpRedeemScriptBuilder) { - saveStorageVersion( - NEW_FEDERATION_FORMAT_VERSION.getKey(), - P2SH_ERP_FEDERATION_FORMAT_VERSION - ); - } else { - saveStorageVersion( - NEW_FEDERATION_FORMAT_VERSION.getKey(), - LEGACY_ERP_FEDERATION_FORMAT_VERSION - ); - } - } else { - saveStorageVersion( - NEW_FEDERATION_FORMAT_VERSION.getKey(), - STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION - ); - } + saveStorageVersion( + NEW_FEDERATION_FORMAT_VERSION.getKey(), + newFederation.getFormatVersion() + ); serializer = BridgeSerializationUtils::serializeFederation; } @@ -428,27 +411,18 @@ protected void saveOldFederation() { RepositorySerializer serializer = BridgeSerializationUtils::serializeFederationOnlyBtcKeys; if (activations.isActive(RSKIP123)) { - if (oldFederation instanceof ErpFederation) { - ErpRedeemScriptBuilder builder = ((ErpFederation) oldFederation).getErpRedeemScriptBuilder(); - if (builder instanceof P2shErpRedeemScriptBuilder) { - saveStorageVersion( - OLD_FEDERATION_FORMAT_VERSION.getKey(), - P2SH_ERP_FEDERATION_FORMAT_VERSION - ); - } else { - saveStorageVersion( - OLD_FEDERATION_FORMAT_VERSION.getKey(), - LEGACY_ERP_FEDERATION_FORMAT_VERSION - ); - } + if (oldFederation != null) { + saveStorageVersion( + OLD_FEDERATION_FORMAT_VERSION.getKey(), + oldFederation.getFormatVersion() + ); } else { // assume it is a standard federation to keep backwards compatibility saveStorageVersion( OLD_FEDERATION_FORMAT_VERSION.getKey(), - STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION + STANDARD_MULTISIG_FEDERATION.getFormatVersion() ); } - serializer = BridgeSerializationUtils::serializeFederation; } @@ -492,7 +466,11 @@ public void savePendingFederation() { RepositorySerializer serializer = BridgeSerializationUtils::serializePendingFederationOnlyBtcKeys; if (activations.isActive(RSKIP123)) { - saveStorageVersion(PENDING_FEDERATION_FORMAT_VERSION.getKey(), STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION); + // we only need to save the standard part of the fed since the emergency part is constant + saveStorageVersion( + PENDING_FEDERATION_FORMAT_VERSION.getKey(), + STANDARD_MULTISIG_FEDERATION.getFormatVersion() + ); serializer = BridgeSerializationUtils::serializePendingFederation; } @@ -1090,30 +1068,30 @@ private Federation deserializeFederationAccordingToVersion( int version, BridgeConstants bridgeConstants ) { - switch (version) { - case LEGACY_ERP_FEDERATION_FORMAT_VERSION: - return BridgeSerializationUtils.deserializeLegacyErpFederation( - data, - bridgeConstants, - activations - ); - case P2SH_ERP_FEDERATION_FORMAT_VERSION: - return BridgeSerializationUtils.deserializeP2shErpFederation( - data, - bridgeConstants - ); - case STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION: - return BridgeSerializationUtils.deserializeStandardMultisigFederation( - data, - networkParameters - ); - default: - // To keep backwards compatibility - return BridgeSerializationUtils.deserializeStandardMultisigFederation( - data, - networkParameters - ); + if (version == STANDARD_MULTISIG_FEDERATION.getFormatVersion()) { + return BridgeSerializationUtils.deserializeStandardMultisigFederation( + data, + networkParameters + ); } + if (version == NON_STANDARD_ERP_FEDERATION.getFormatVersion()) { + return BridgeSerializationUtils.deserializeLegacyErpFederation( + data, + bridgeConstants, + activations + ); + } + if (version == P2SH_ERP_FEDERATION.getFormatVersion()) { + return BridgeSerializationUtils.deserializeP2shErpFederation( + data, + bridgeConstants + ); + } + // To keep backwards compatibility + return BridgeSerializationUtils.deserializeStandardMultisigFederation( + data, + networkParameters + ); } private T safeGetFromRepository(BridgeStorageIndexKey keyAddress, RepositoryDeserializer deserializer) { 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 e202bc16f60..27ae35ca9f8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -64,6 +64,9 @@ import co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector; import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.PendingFederation; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.pegin.PeginEvaluationResult; 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 aea5bab53e4..0a92ca0fe75 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java @@ -29,6 +29,7 @@ import co.rsk.core.RskAddress; import co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector; import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType; +import co.rsk.peg.federation.Federation; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.utils.BtcTransactionFormatUtils; import org.ethereum.config.Constants; @@ -583,7 +584,7 @@ public static int calculatePegoutTxSize(ActivationConfig.ForBlock activations, F } final int SIGNATURE_MULTIPLIER = 72; - BtcTransaction pegoutTx = new BtcTransaction(federation.btcParams); + BtcTransaction pegoutTx = new BtcTransaction(federation.getBtcParams()); for (int i = 0; i < inputs; i++) { pegoutTx.addInput(Sha256Hash.ZERO_HASH, 0, federation.getRedeemScript()); } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeUtilsLegacy.java b/rskj-core/src/main/java/co/rsk/peg/BridgeUtilsLegacy.java index 7cf62f03b30..33a198ed894 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeUtilsLegacy.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeUtilsLegacy.java @@ -6,6 +6,7 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.core.TransactionOutput; import co.rsk.bitcoinj.core.UTXO; +import co.rsk.peg.federation.Federation; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; diff --git a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java index ea657d14fd5..82f6fd85054 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java @@ -20,6 +20,7 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.UTXO; import co.rsk.config.BridgeConstants; +import co.rsk.peg.federation.Federation; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.core.Block; diff --git a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java index 06e0c99b13d..6cf1e261013 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java +++ b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWallet.java @@ -9,6 +9,7 @@ import co.rsk.bitcoinj.script.RedeemScriptParserFactory; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.wallet.RedeemData; +import co.rsk.peg.federation.Federation; import co.rsk.peg.flyover.FlyoverFederationInformation; import java.util.List; import java.util.Optional; diff --git a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithMultipleScripts.java b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithMultipleScripts.java index d59d97902ef..d92ff94caaf 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithMultipleScripts.java +++ b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithMultipleScripts.java @@ -1,6 +1,7 @@ package co.rsk.peg; import co.rsk.bitcoinj.core.Context; +import co.rsk.peg.federation.Federation; import co.rsk.peg.flyover.FlyoverFederationInformation; import java.util.Arrays; diff --git a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithSingleScript.java b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithSingleScript.java index 64b3a84a56e..a0885c5e638 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithSingleScript.java +++ b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithSingleScript.java @@ -1,6 +1,7 @@ package co.rsk.peg; import co.rsk.bitcoinj.core.Context; +import co.rsk.peg.federation.Federation; import co.rsk.peg.flyover.FlyoverFederationInformation; import java.util.List; import java.util.Optional; diff --git a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorage.java b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorage.java index ec319fd9378..8fb9b98fadc 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorage.java +++ b/rskj-core/src/main/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorage.java @@ -1,6 +1,7 @@ package co.rsk.peg; import co.rsk.bitcoinj.core.Context; +import co.rsk.peg.federation.Federation; import co.rsk.peg.flyover.FlyoverFederationInformation; import java.util.List; import java.util.Optional; 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 4c88f3c4e92..c93df550fbe 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PegUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/PegUtils.java @@ -16,6 +16,7 @@ import co.rsk.config.BridgeConstants; import co.rsk.peg.bitcoin.BitcoinUtils; import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType; +import co.rsk.peg.federation.Federation; import co.rsk.peg.pegin.PeginEvaluationResult; import co.rsk.peg.pegin.PeginProcessAction; import co.rsk.peg.pegininstructions.PeginInstructionsException; diff --git a/rskj-core/src/main/java/co/rsk/peg/PegUtilsLegacy.java b/rskj-core/src/main/java/co/rsk/peg/PegUtilsLegacy.java index 2aca294e977..7e1af3bbe7f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PegUtilsLegacy.java +++ b/rskj-core/src/main/java/co/rsk/peg/PegUtilsLegacy.java @@ -22,6 +22,8 @@ import java.util.List; import java.util.Objects; import java.util.Optional; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.slf4j.Logger; diff --git a/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java index 3f76d53a456..b946fa8760e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/bitcoin/NonStandardErpRedeemScriptBuilderFactory.java @@ -6,8 +6,7 @@ public class NonStandardErpRedeemScriptBuilderFactory { - private NonStandardErpRedeemScriptBuilderFactory() { - } + private NonStandardErpRedeemScriptBuilderFactory() {} public static ErpRedeemScriptBuilder getNonStandardErpRedeemScriptBuilder( ActivationConfig.ForBlock activations, diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java similarity index 90% rename from rskj-core/src/main/java/co/rsk/peg/ErpFederation.java rename to rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java index 08c0509acfd..800bfabed83 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; @@ -7,6 +7,7 @@ import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.script.ScriptChunk; +import co.rsk.peg.FederationMember; import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.RedeemScriptCreationException; import co.rsk.peg.utils.EcKeyUtils; @@ -14,8 +15,8 @@ import java.util.Collections; import java.util.List; -import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; -import static co.rsk.peg.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; public class ErpFederation extends Federation { private final List erpPubKeys; @@ -31,9 +32,11 @@ protected ErpFederation( NetworkParameters btcParams, List erpPubKeys, long activationDelay, - ErpRedeemScriptBuilder erpRedeemScriptBuilder) { + ErpRedeemScriptBuilder erpRedeemScriptBuilder, + int formatVersion + ) { - super(members, creationTime, creationBlockNumber, btcParams); + super(members, creationTime, creationBlockNumber, btcParams, formatVersion); validateEmergencyKeys(erpPubKeys); this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpPubKeys); diff --git a/rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationCreationException.java similarity index 95% rename from rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java rename to rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationCreationException.java index ce40ccbf24b..65d83be5a5d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/ErpFederationCreationException.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationCreationException.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.federation; /** * Exception to be thrown when attempting to create a Federation with invalid values diff --git a/rskj-core/src/main/java/co/rsk/peg/Federation.java b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java similarity index 92% rename from rskj-core/src/main/java/co/rsk/peg/Federation.java rename to rskj-core/src/main/java/co/rsk/peg/federation/Federation.java index 247554623c1..8e46b67d775 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java @@ -16,13 +16,14 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.Address; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.peg.FederationMember; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -45,10 +46,17 @@ public abstract class Federation { protected final NetworkParameters btcParams; protected Script redeemScript; + protected int formatVersion; protected Script p2shScript; protected Address address; - protected Federation(List members, Instant creationTime, long creationBlockNumber, NetworkParameters btcParams) { + protected Federation( + List members, + Instant creationTime, + long creationBlockNumber, + NetworkParameters btcParams, + int formatVersion + ) { // Sorting members ensures same order of federation members for same members // Immutability provides protection against unwanted modification, thus making the Federation instance // effectively immutable @@ -56,6 +64,11 @@ protected Federation(List members, Instant creationTime, long this.creationTime = creationTime.truncatedTo(ChronoUnit.MILLIS); this.creationBlockNumber = creationBlockNumber; this.btcParams = btcParams; + this.formatVersion = formatVersion; + } + + public int getFormatVersion() { + return formatVersion; } public List getMembers() { diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java new file mode 100644 index 00000000000..15636706828 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java @@ -0,0 +1,75 @@ +package co.rsk.peg.federation; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.peg.FederationMember; +import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; +import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; +import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; + +import java.time.Instant; +import java.util.List; + +import static co.rsk.peg.federation.FederationFormatVersion.*; + +public class FederationFactory { + + private FederationFactory() {} + + public static StandardMultisigFederation buildStandardMultiSigFederation(List members, + Instant creationTime, + long creationBlockNumber, + NetworkParameters btcParams) { + return new StandardMultisigFederation( + members, + creationTime, + creationBlockNumber, + btcParams, + STANDARD_MULTISIG_FEDERATION.getFormatVersion() + ); + } + + public static ErpFederation buildNonStandardErpFederation(List members, + Instant creationTime, + long creationBlockNumber, + NetworkParameters btcParams, + List erpPubKeys, + long activationDelay, + ActivationConfig.ForBlock activations) { + ErpRedeemScriptBuilder erpRedeemScriptBuilder = + NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, btcParams); + + return new ErpFederation( + members, + creationTime, + creationBlockNumber, + btcParams, + erpPubKeys, + activationDelay, + erpRedeemScriptBuilder, + NON_STANDARD_ERP_FEDERATION.getFormatVersion() + ); + } + + public static ErpFederation buildP2shErpFederation(List members, + Instant creationTime, + long creationBlockNumber, + NetworkParameters btcParams, + List erpPubKeys, + long activationDelay) { + + ErpRedeemScriptBuilder erpRedeemScriptBuilder = new P2shErpRedeemScriptBuilder(); + return new ErpFederation( + members, + creationTime, + creationBlockNumber, + btcParams, + erpPubKeys, + activationDelay, + erpRedeemScriptBuilder, + P2SH_ERP_FEDERATION.getFormatVersion() + ); + } + +} diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFormatVersion.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFormatVersion.java new file mode 100644 index 00000000000..217014b30aa --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFormatVersion.java @@ -0,0 +1,17 @@ +package co.rsk.peg.federation; + +public enum FederationFormatVersion { + STANDARD_MULTISIG_FEDERATION(1000), + NON_STANDARD_ERP_FEDERATION(2000), + P2SH_ERP_FEDERATION(3000); + + private int version; + + FederationFormatVersion(int i) { + this.version = i; + } + + public int getFormatVersion() { + return version; + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java similarity index 89% rename from rskj-core/src/main/java/co/rsk/peg/PendingFederation.java rename to rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index 89e51da2436..f56ebd8d952 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -16,14 +16,13 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.config.BridgeConstants; import co.rsk.crypto.Keccak256; -import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.BridgeSerializationUtils; +import co.rsk.peg.FederationMember; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.crypto.HashUtil; @@ -109,35 +108,31 @@ public Federation buildFederation( if (activations.isActive(ConsensusRule.RSKIP353)) { logger.info("[buildFederation] Going to create a P2SH ERP Federation"); - return new ErpFederation( + return FederationFactory.buildP2shErpFederation( members, creationTime, blockNumber, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); } if (activations.isActive(ConsensusRule.RSKIP201)) { logger.info("[buildFederation] Going to create an ERP Federation"); - ErpRedeemScriptBuilder erpRedeemScriptBuilder - = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); - - return new ErpFederation( + return FederationFactory.buildNonStandardErpFederation( members, creationTime, blockNumber, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - erpRedeemScriptBuilder + activations ); } - return new StandardMultisigFederation( + return FederationFactory.buildStandardMultiSigFederation( members, creationTime, blockNumber, diff --git a/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java similarity index 90% rename from rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java rename to rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java index 3ccb9f2a28e..0a1224291dd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/StandardMultisigFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java @@ -16,11 +16,12 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.peg.FederationMember; import co.rsk.peg.bitcoin.ScriptValidations; import java.time.Instant; @@ -34,13 +35,14 @@ public class StandardMultisigFederation extends Federation { - public StandardMultisigFederation( + protected StandardMultisigFederation( List members, Instant creationTime, long creationBlockNumber, - NetworkParameters btcParams) { + NetworkParameters btcParams, + int formatVersion) { - super(members, creationTime, creationBlockNumber, btcParams); + super(members, creationTime, creationBlockNumber, btcParams, formatVersion); validateRedeemScriptSize(); } diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLogger.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLogger.java index 62bc7f7121b..d96e4268c10 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLogger.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLogger.java @@ -21,7 +21,7 @@ import co.rsk.bitcoinj.core.*; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; -import co.rsk.peg.Federation; +import co.rsk.peg.federation.Federation; import co.rsk.peg.pegin.RejectedPeginReason; import org.ethereum.core.Block; import org.ethereum.core.Transaction; diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index 9f8c328f975..13b92f5596b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -22,7 +22,7 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.BridgeEvents; -import co.rsk.peg.Federation; +import co.rsk.peg.federation.Federation; import co.rsk.peg.pegin.RejectedPeginReason; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java index 81d521ea1cb..18a62fbb12d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java @@ -22,7 +22,7 @@ import co.rsk.config.BridgeConstants; import co.rsk.peg.Bridge; import co.rsk.peg.DeprecatedMethodCallException; -import co.rsk.peg.Federation; +import co.rsk.peg.federation.Federation; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.Block; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 32dd0f5ae49..6cbeaf48705 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -28,7 +28,7 @@ import co.rsk.peg.bitcoin.CoinbaseInformation; import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.*; import co.rsk.peg.resources.TestConstants; import co.rsk.peg.utils.MerkleTreeUtils; import co.rsk.peg.flyover.FlyoverFederationInformation; @@ -154,7 +154,7 @@ void serializeFederationOnlyBtcKeys() throws Exception { }; // Only actual keys serialized are BTC keys, so we don't really care about RSK or MST keys - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList(new BtcECKey[]{ BtcECKey.fromPublicOnly(publicKeyBytes[0]), BtcECKey.fromPublicOnly(publicKeyBytes[1]), @@ -305,7 +305,7 @@ void serializeFederation_serializedKeysAreCompressedAndThree() { members.add(new FederationMember(new BtcECKey(), new ECKey(), new ECKey())); } - Federation testFederation = new StandardMultisigFederation( + Federation testFederation = FederationFactory.buildStandardMultiSigFederation( members, Instant.now(), 123, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); @@ -790,7 +790,7 @@ void serializeAndDeserializeFederationOnlyBtcKeysWithRealRLP() { }; // Only actual keys serialized are BTC keys, so deserialization will fill RSK and MST keys with those - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithKeys(Arrays.asList( BtcECKey.fromPublicOnly(publicKeyBytes[0]), BtcECKey.fromPublicOnly(publicKeyBytes[1]), @@ -1252,7 +1252,7 @@ private void testSerializeAndDeserializeFederation( members.add(new FederationMember(new BtcECKey(), new ECKey(), new ECKey())); } - Federation testFederation = new StandardMultisigFederation( + Federation testFederation = FederationFactory.buildStandardMultiSigFederation( members, Instant.now(), 123, @@ -1265,14 +1265,14 @@ private void testSerializeAndDeserializeFederation( bridgeConstants.getBtcParams() ); - Federation testErpFederation = new ErpFederation( + Federation testErpFederation = FederationFactory.buildNonStandardErpFederation( members, Instant.now(), 123, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - erpRedeemScriptBuilder + activations ); byte[] serializedTestErpFederation = BridgeSerializationUtils.serializeFederation(testErpFederation); @@ -1292,14 +1292,13 @@ private void testSerializeAndDeserializeFederation( } if (isRskip353Active) { - Federation testP2shErpFederation = new ErpFederation( + Federation testP2shErpFederation = FederationFactory.buildP2shErpFederation( members, Instant.now(), 123, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); byte[] serializedTestP2shErpFederation = BridgeSerializationUtils.serializeFederation(testP2shErpFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index df79d3aed22..ba206006424 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -1,5 +1,6 @@ package co.rsk.peg; +import static co.rsk.peg.federation.FederationFormatVersion.*; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -14,9 +15,7 @@ import java.time.Instant; import java.util.List; import co.rsk.config.BridgeRegTestConstants; -import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.*; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -27,9 +26,9 @@ class BridgeStorageProviderFederationTests { - private static final int STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION = 1000; - private static final int LEGACY_ERP_FEDERATION_FORMAT_VERSION = 2000; - private static final int P2SH_ERP_FEDERATION_FORMAT_VERSION = 3000; + private static final int STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION = STANDARD_MULTISIG_FEDERATION.getFormatVersion(); + private static final int NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION = NON_STANDARD_ERP_FEDERATION.getFormatVersion(); + private static final int P2SH_ERP_FEDERATION_FORMAT_VERSION = P2SH_ERP_FEDERATION.getFormatVersion(); private final BridgeConstants bridgeConstantsRegtest = BridgeRegTestConstants.getInstance(); private ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -46,9 +45,9 @@ void getNewFederation_should_return_P2shErpFederation() { @Test void getNewFederation_should_return_erp_federation() { - Federation federation = createFederation(LEGACY_ERP_FEDERATION_FORMAT_VERSION); + Federation federation = createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION); testGetNewFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, federation ); } @@ -70,7 +69,7 @@ void getNewFederation_should_return_null() { ); testGetNewFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, null ); @@ -151,9 +150,9 @@ void getOldFederation_should_return_P2shErpFederation() { @Test void getOldFederation_should_return_erp_federation() { - Federation federation = createFederation(LEGACY_ERP_FEDERATION_FORMAT_VERSION); + Federation federation = createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION); testGetOldFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, federation ); } @@ -175,7 +174,7 @@ void getOldFederation_should_return_null() { ); testGetOldFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, null ); @@ -252,8 +251,8 @@ void saveNewFederation_before_RSKIP123_should_allow_to_save_any_fed_type() throw ); testSaveNewFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, - createFederation(LEGACY_ERP_FEDERATION_FORMAT_VERSION) + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, + createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) ); testSaveNewFederation( @@ -303,8 +302,8 @@ void saveNewFederation_after_RSKIP201_should_save_erp_fed_format() throws IOExce ConsensusRule.RSKIP201 ).forBlock(0); testSaveNewFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, - createFederation(LEGACY_ERP_FEDERATION_FORMAT_VERSION) + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, + createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) ); } @@ -316,8 +315,8 @@ void saveNewFederation_after_RSKIP353_should_save_erp_fed_format() throws IOExce ConsensusRule.RSKIP353 ).forBlock(0); testSaveNewFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, - createFederation(LEGACY_ERP_FEDERATION_FORMAT_VERSION) + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, + createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) ); } @@ -425,8 +424,8 @@ void saveOldFederation_before_RSKIP123_should_allow_to_save_any_fed_type() throw ); testSaveOldFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, - createFederation(LEGACY_ERP_FEDERATION_FORMAT_VERSION) + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, + createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) ); testSaveOldFederation( @@ -476,8 +475,8 @@ void saveOldFederation_after_RSKIP201_should_save_erp_fed_format() throws IOExce ConsensusRule.RSKIP201 ).forBlock(0); testSaveOldFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, - createFederation(LEGACY_ERP_FEDERATION_FORMAT_VERSION) + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, + createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) ); } @@ -489,8 +488,8 @@ void saveOldFederation_after_RSKIP353_should_save_erp_fed_format() throws IOExce ConsensusRule.RSKIP353 ).forBlock(0); testSaveOldFederation( - LEGACY_ERP_FEDERATION_FORMAT_VERSION, - createFederation(LEGACY_ERP_FEDERATION_FORMAT_VERSION) + NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, + createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) ); } @@ -605,36 +604,41 @@ private Federation createFederation(int version) { PegTestUtils.createRandomBtcECKeys(7) ); - switch (version) { - case P2SH_ERP_FEDERATION_FORMAT_VERSION: - return new ErpFederation( - members, - Instant.now(), - 1L, - bridgeConstantsRegtest.getBtcParams(), - bridgeConstantsRegtest.getErpFedPubKeysList(), - bridgeConstantsRegtest.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() - ); - case LEGACY_ERP_FEDERATION_FORMAT_VERSION: - ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstantsRegtest.getBtcParams()); - return new ErpFederation( - members, - Instant.now(), - 1L, - bridgeConstantsRegtest.getBtcParams(), - bridgeConstantsRegtest.getErpFedPubKeysList(), - bridgeConstantsRegtest.getErpFedActivationDelay(), - erpRedeemScriptBuilder - ); - default: - return new StandardMultisigFederation( - members, - Instant.now(), - 1L, - bridgeConstantsRegtest.getBtcParams() + if (version == STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION) { + return FederationFactory.buildStandardMultiSigFederation( + members, + Instant.now(), + 1L, + bridgeConstantsRegtest.getBtcParams() + ); + } + if (version == NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) { + return FederationFactory.buildNonStandardErpFederation( + members, + Instant.now(), + 1L, + bridgeConstantsRegtest.getBtcParams(), + bridgeConstantsRegtest.getErpFedPubKeysList(), + bridgeConstantsRegtest.getErpFedActivationDelay(), + activations + ); + } + if (version == P2SH_ERP_FEDERATION_FORMAT_VERSION) { + return FederationFactory.buildP2shErpFederation( + members, + Instant.now(), + 1L, + bridgeConstantsRegtest.getBtcParams(), + bridgeConstantsRegtest.getErpFedPubKeysList(), + bridgeConstantsRegtest.getErpFedActivationDelay() ); } + // To keep backwards compatibility + return FederationFactory.buildStandardMultiSigFederation( + members, + Instant.now(), + 1L, + bridgeConstantsRegtest.getBtcParams() + ); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index ee8ff1bdf87..ab03fb34ef1 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -28,6 +28,7 @@ import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; import co.rsk.peg.bitcoin.*; +import co.rsk.peg.federation.*; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.whitelist.LockWhitelist; import co.rsk.peg.whitelist.LockWhitelistEntry; @@ -65,6 +66,7 @@ import java.util.*; import java.util.concurrent.atomic.AtomicReference; +import static co.rsk.peg.federation.FederationFormatVersion.*; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.junit.jupiter.api.Assertions.*; @@ -79,13 +81,14 @@ @MockitoSettings(strictness = Strictness.LENIENT) class BridgeStorageProviderTest { private static final byte FAST_BRIDGE_FEDERATION_SCRIPT_HASH_TRUE_VALUE_TEST = (byte) 1; - private static final int FEDERATION_FORMAT_VERSION_MULTIKEY = 1000; - private static final int ERP_FEDERATION_FORMAT_VERSION = 2000; - private static final int P2SH_ERP_FEDERATION_FORMAT_VERSION = 3000; + private static final int STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION = STANDARD_MULTISIG_FEDERATION.getFormatVersion(); + private static final int NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION = NON_STANDARD_ERP_FEDERATION.getFormatVersion(); + private static final int P2SH_ERP_FEDERATION_FORMAT_VERSION = P2SH_ERP_FEDERATION.getFormatVersion(); private final TestSystemProperties config = new TestSystemProperties(); private final ActivationConfig.ForBlock activationsBeforeFork = ActivationConfigsForTest.genesis().forBlock(0L); private final ActivationConfig.ForBlock activationsAllForks = ActivationConfigsForTest.all().forBlock(0); + private final ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); private final BridgeTestNetConstants bridgeTestnetInstance = BridgeTestNetConstants.getInstance(); private final NetworkParameters networkParameters = bridgeTestnetInstance.getBtcParams(); @@ -403,14 +406,16 @@ void getNewFederation_multiKeyVersion() { void getNewFederation_erp_fed() { BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = new ErpFederation( + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( newFederation.getMembers(), newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - new NonStandardErpRedeemScriptBuilderHardcoded() + activations ); testGetNewFederationPostMultiKey(erpFederation); @@ -419,14 +424,13 @@ void getNewFederation_erp_fed() { @Test void getNewFederation_p2sh_erp_fed() { Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation p2shErpFederation = new ErpFederation( + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation( newFederation.getMembers(), newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), bridgeTestnetInstance.getErpFedPubKeysList(), - bridgeTestnetInstance.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeTestnetInstance.getErpFedActivationDelay() ); testGetNewFederationPostMultiKey(p2shErpFederation); @@ -535,7 +539,7 @@ void saveNewFederation_postMultiKey() { when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); Federation newFederation = buildMockFederation(100, 200, 300); - testSaveNewFederationPostMultiKey(newFederation, FEDERATION_FORMAT_VERSION_MULTIKEY, activations); + testSaveNewFederationPostMultiKey(newFederation, STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION, activations); } @Test @@ -547,17 +551,17 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = new ErpFederation( + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( newFederation.getMembers(), newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - new NonStandardErpRedeemScriptBuilder() + activations ); - testSaveNewFederationPostMultiKey(erpFederation, ERP_FEDERATION_FORMAT_VERSION, activations); + testSaveNewFederationPostMultiKey(erpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); } @Test @@ -569,14 +573,13 @@ void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation p2shErpFederation = new ErpFederation( + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation( newFederation.getMembers(), newFederation.getCreationTime(), newFederation.getCreationBlockNumber(), newFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); testSaveNewFederationPostMultiKey(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activations); @@ -688,14 +691,14 @@ void getOldFederation_nonStandardHardcoaded_fed() { when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - ErpFederation erpFederation = new ErpFederation( + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - new NonStandardErpRedeemScriptBuilderHardcoded() + activations ); testGetOldFederation(erpFederation, activations); @@ -711,14 +714,14 @@ void getOldFederation_nonStandardWithUnsignedBE_fed() { when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - ErpFederation erpFederation = new ErpFederation( + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - new NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE() + activations ); testGetOldFederation(erpFederation, activations); @@ -735,14 +738,14 @@ void getOldFederation_nonStandard_fed() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation erpFederation = new ErpFederation( + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - new NonStandardErpRedeemScriptBuilder() + activations ); testGetOldFederation(erpFederation, activations); @@ -754,14 +757,13 @@ void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { Federation oldFederation = buildMockFederation(100, 200, 300); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - ErpFederation p2shErpFederation = new ErpFederation( + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); testGetOldFederation(p2shErpFederation, activations); @@ -866,44 +868,48 @@ void saveOldFederation_postMultikey() { when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); Federation oldFederation = buildMockFederation(100, 200, 300); - testSaveOldFederation(oldFederation, FEDERATION_FORMAT_VERSION_MULTIKEY, activations); + testSaveOldFederation(oldFederation, STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION, activations); } @Test void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = new ErpFederation( + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - new NonStandardErpRedeemScriptBuilder() + activations ); - testSaveOldFederation(erpFederation, ERP_FEDERATION_FORMAT_VERSION, activations); + testSaveOldFederation(erpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); } @Test void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(true); BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); - ErpFederation p2shErpFederation = new ErpFederation( + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation( oldFederation.getMembers(), oldFederation.getCreationTime(), oldFederation.getCreationBlockNumber(), oldFederation.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); testSaveOldFederation(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activations); @@ -3642,7 +3648,7 @@ private void testGetOldFederation(Federation oldFederation, ActivationConfig.For if (storageCalls.size() == 1) { // First call is storage version getter Assertions.assertEquals(OLD_FEDERATION_FORMAT_VERSION.getKey(), address); - int federationVersion = getFederationVersion(oldFederation); + int federationVersion = oldFederation.getFormatVersion(); return RLP.encodeBigInteger(BigInteger.valueOf(federationVersion)); } else { // Second call is the actual storage getter @@ -3733,7 +3739,7 @@ private void testGetNewFederationPostMultiKey(Federation federation) { if (storageCalls.size() == 1) { // First call is storage version getter Assertions.assertEquals(NEW_FEDERATION_FORMAT_VERSION.getKey(), address); - int federationVersion = getFederationVersion(federation); + int federationVersion = federation.getFormatVersion(); return RLP.encodeBigInteger(BigInteger.valueOf(federationVersion)); } else { // Second call is the actual storage getter @@ -3939,7 +3945,7 @@ private Address getBtcAddress(String addr) { } private Federation buildMockFederation(Integer... pks) { - return new StandardMultisigFederation( + return FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersFromPks(pks), Instant.ofEpochMilli(1000), 1, @@ -3960,18 +3966,4 @@ private static Repository createRepository() { TrieStore trieStore = new TrieStoreImpl(new HashMapDB()); return new MutableRepository(new MutableTrieCache(new MutableTrieImpl(trieStore, new Trie(trieStore)))); } - - private int getFederationVersion(Federation federation) { - if (federation instanceof StandardMultisigFederation) { - return BridgeStorageProvider.STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION; - } else if (federation instanceof ErpFederation) { - ErpRedeemScriptBuilder builder = ((ErpFederation) federation).getErpRedeemScriptBuilder(); - if (builder instanceof P2shErpRedeemScriptBuilder) { - return BridgeStorageProvider.P2SH_ERP_FEDERATION_FORMAT_VERSION; - } else { - return BridgeStorageProvider.LEGACY_ERP_FEDERATION_FORMAT_VERSION; - } - } - throw new IllegalArgumentException("Unknown Federation type: " + federation.getClass()); - } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index 5f4744eef9e..6c0769b0485 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -5,6 +5,8 @@ import java.util.*; import co.rsk.config.BridgeConstants; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; @@ -75,7 +77,7 @@ void addSignature_fedPubKey_belongs_to_active_federation() throws Exception { ); federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, @@ -133,7 +135,7 @@ void addSignature_fedPubKey_belongs_to_retiring_federation() throws Exception { BtcECKey.fromPrivate(Hex.decode("fa02"))); federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiringFederation = new StandardMultisigFederation( + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, @@ -147,7 +149,7 @@ void addSignature_fedPubKey_belongs_to_retiring_federation() throws Exception { ); activeFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -191,7 +193,7 @@ void addSignature_fedPubKey_no_belong_to_retiring_or_active_federation() throws ); federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiringFederation = new StandardMultisigFederation( + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, @@ -205,7 +207,7 @@ void addSignature_fedPubKey_no_belong_to_retiring_or_active_federation() throws ); activeFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 0L, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java index 68d5ebfc624..a640d8b5773 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java @@ -41,6 +41,7 @@ import co.rsk.peg.bitcoin.CoinbaseInformation; import co.rsk.peg.btcLockSender.BtcLockSender; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; +import co.rsk.peg.federation.Federation; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java index e7c37058e36..7cd70836baa 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java @@ -7,6 +7,8 @@ import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.test.builders.BridgeSupportBuilder; import org.bouncycastle.util.encoders.Hex; @@ -127,7 +129,7 @@ void test_processFundsMigration( federationActivationAge + bridgeConstants.getFundsMigrationAgeSinceActivationEnd(activations) + 1; - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, federationCreationBlockNumber, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index ffeb00631d7..fc46e8986be 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -1,16 +1,6 @@ package co.rsk.peg; -import co.rsk.bitcoinj.core.Address; -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.BtcTransaction; -import co.rsk.bitcoinj.core.Coin; -import co.rsk.bitcoinj.core.Context; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.core.PartialMerkleTree; -import co.rsk.bitcoinj.core.Sha256Hash; -import co.rsk.bitcoinj.core.StoredBlock; -import co.rsk.bitcoinj.core.TransactionWitness; -import co.rsk.bitcoinj.core.UTXO; +import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.store.BlockStoreException; @@ -21,8 +11,9 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.bitcoin.CoinbaseInformation; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.pegin.RejectedPeginReason; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; @@ -33,11 +24,7 @@ import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.config.blockchain.upgrades.ConsensusRule; -import org.ethereum.core.Block; -import org.ethereum.core.BlockTxSignatureCache; -import org.ethereum.core.ReceivedTxSignatureCache; -import org.ethereum.core.SignatureCache; -import org.ethereum.core.Transaction; +import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.vm.PrecompiledContracts; import org.junit.jupiter.api.Assertions; @@ -50,31 +37,15 @@ import java.io.IOException; import java.math.BigInteger; import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Stream; import static co.rsk.peg.BridgeSupportTestUtil.mockChainOfStoredBlocks; -import static co.rsk.peg.PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation; -import static co.rsk.peg.PegTestUtils.createBech32Output; -import static co.rsk.peg.PegTestUtils.createFederation; -import static co.rsk.peg.pegin.RejectedPeginReason.LEGACY_PEGIN_MULTISIG_SENDER; -import static co.rsk.peg.pegin.RejectedPeginReason.INVALID_AMOUNT; -import static co.rsk.peg.pegin.RejectedPeginReason.PEGIN_V1_INVALID_PAYLOAD; +import static co.rsk.peg.PegTestUtils.*; +import static co.rsk.peg.pegin.RejectedPeginReason.*; import static co.rsk.peg.utils.UnrefundablePeginReason.LEGACY_PEGIN_UNDETERMINED_SENDER; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.mockito.ArgumentMatchers.*; +import static org.mockito.Mockito.*; class BridgeSupportRegisterBtcTransactionTest { @@ -382,28 +353,26 @@ void init() throws IOException { ); retiringFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); - retiringFederation = new ErpFederation( + retiringFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedSigners), Instant.ofEpochMilli(1000L), 1, bridgeMainnetConstants.getBtcParams(), bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeMainnetConstants.getErpFedActivationDelay() ); activeFedSigners = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa07", "fa08", "fa09", "fa10", "fa11"}, true ); activeFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); - activeFederation = new ErpFederation( + activeFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFedSigners), Instant.ofEpochMilli(1000L), 2L, bridgeMainnetConstants.getBtcParams(), bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeMainnetConstants.getErpFedActivationDelay() ); mockFactory = mock(BtcBlockStoreWithCache.Factory.class); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java index 35cfde10491..b961165acee 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -25,6 +25,8 @@ import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.peg.utils.BridgeEventLoggerImpl; import co.rsk.peg.utils.RejectedPegoutReason; @@ -1250,7 +1252,7 @@ private static Repository createRepository() { } private static Federation getFederation() { - return new StandardMultisigFederation( + return FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java index 48e31a44009..a6217f9e782 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java @@ -11,6 +11,8 @@ import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.peg.bitcoin.BitcoinUtils; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import co.rsk.test.builders.BridgeSupportBuilder; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; @@ -121,7 +123,7 @@ void test_pegoutTxIndex_when_migration_tx_is_created(ActivationConfig.ForBlock a Federation oldFederation = bridgeMainnetConstants.getGenesisFederation(); long newFedCreationBlockNumber = 5L; - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, newFedCreationBlockNumber, @@ -190,7 +192,7 @@ void test_pegoutTxIndex_when_migration_and_pegout_batch_tx_are_created(Activatio Federation oldFederation = bridgeMainnetConstants.getGenesisFederation(); long newFedCreationBlockNumber = 5L; - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, newFedCreationBlockNumber, 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 83fa47cab8b..5a40e4744e4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -33,10 +33,10 @@ import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.bitcoin.CoinbaseInformation; import co.rsk.peg.bitcoin.MerkleBranch; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.btcLockSender.BtcLockSender; import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; +import co.rsk.peg.federation.*; import co.rsk.peg.pegininstructions.PeginInstructions; import co.rsk.peg.pegininstructions.PeginInstructionsException; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; @@ -968,7 +968,7 @@ void registerBtcTransactionLockTxNotWhitelisted_before_rskip_146_activation() th BtcECKey.fromPrivate(Hex.decode("fa02")) ); - Federation federation1 = new StandardMultisigFederation( + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, @@ -981,7 +981,7 @@ void registerBtcTransactionLockTxNotWhitelisted_before_rskip_146_activation() th BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03"))); - Federation federation2 = new StandardMultisigFederation( + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), Instant.ofEpochMilli(2000L), 0L, @@ -1138,7 +1138,7 @@ void registerBtcTransactionLockTxNotWhitelisted_after_rskip_146_activation() thr BtcECKey.fromPrivate(Hex.decode("fa02")) ); - Federation federation1 = new StandardMultisigFederation( + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, @@ -1151,7 +1151,7 @@ void registerBtcTransactionLockTxNotWhitelisted_after_rskip_146_activation() thr BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03"))); - Federation federation2 = new StandardMultisigFederation( + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), Instant.ofEpochMilli(2000L), 0L, @@ -1322,7 +1322,7 @@ void registerBtcTransaction_sending_segwit_tx_twice_locks_just_once() throws Blo BtcECKey.fromPrivate(Hex.decode("fa02")) ); - Federation fed = new StandardMultisigFederation( + Federation fed = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), Instant.ofEpochMilli(1000L), 0L, @@ -1414,7 +1414,7 @@ void callProcessFundsMigration_is_migrating_before_rskip_146_activation() throws Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, @@ -1477,7 +1477,7 @@ void callProcessFundsMigration_is_migrating_after_rskip_146_activation() throws Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, @@ -1542,7 +1542,7 @@ void callProcessFundsMigration_is_migrated_before_rskip_146_activation() throws Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, @@ -1605,7 +1605,7 @@ void callProcessFundsMigration_is_migrated_after_rskip_146_activation() throws I Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, @@ -1669,7 +1669,7 @@ void updateFederationCreationBlockHeights_before_rskip_186_activation() throws I Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, @@ -1732,7 +1732,7 @@ void updateFederationCreationBlockHeights_after_rskip_186_activation() throws IO Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, @@ -2113,7 +2113,7 @@ void rskTxWaitingForSignature_fail_adding_an_already_existing_key_after_rskip_37 // Set state to make concur a pegout migration tx and pegout batch creation on the same updateCollection Federation oldFederation = bridgeConstants.getGenesisFederation(); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, @@ -6405,13 +6405,13 @@ private void test_migrating_many_utxos(boolean isRskip294Active, int utxosToCrea oldFedMembers.add(FederationMember.getFederationMemberFromKey(new BtcECKey())); } - Federation oldFed = new StandardMultisigFederation( + Federation oldFed = FederationFactory.buildStandardMultiSigFederation( oldFedMembers, Instant.now(), 0, btcRegTestParams ); - Federation newFed = new StandardMultisigFederation( + Federation newFed = FederationFactory.buildStandardMultiSigFederation( Arrays.asList( FederationMember.getFederationMemberFromKey(new BtcECKey()), FederationMember.getFederationMemberFromKey(new BtcECKey()), @@ -6563,14 +6563,13 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ when(preRSKIP271_activations.isActive(ConsensusRule.RSKIP271)).thenReturn(false); when(preRSKIP271_activations.isActive(ConsensusRule.RSKIP385)).thenReturn(false); - Federation p2shFed = new ErpFederation( + Federation p2shFed = FederationFactory.buildP2shErpFederation( members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); Stream preRskip271 = Stream.of( @@ -6631,14 +6630,13 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ when(preRSKIP385_activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); when(preRSKIP385_activations.isActive(ConsensusRule.RSKIP385)).thenReturn(false); - Federation p2shFed = new ErpFederation( + Federation p2shFed = FederationFactory.buildP2shErpFederation( members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); Stream preRskip385 = Stream.of( @@ -6698,14 +6696,13 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ PegTestUtils.createRandomBtcECKeys(7) ); - ErpFederation p2shFed = new ErpFederation( + ErpFederation p2shFed = FederationFactory.buildP2shErpFederation( members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); Stream postRskip385 = Stream.of( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java index 386560080f5..dec37a942c8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java @@ -66,6 +66,7 @@ import co.rsk.db.MutableTrieImpl; import co.rsk.peg.bitcoin.MerkleBranch; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; +import co.rsk.peg.federation.*; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.simples.SimpleBlockChain; import co.rsk.peg.utils.BridgeEventLogger; @@ -626,7 +627,7 @@ void minimumProcessFundsMigrationValue() throws IOException { Federation oldFederation = bridgeConstants.getGenesisFederation(); BtcECKey key = new BtcECKey(new SecureRandom()); FederationMember member = new FederationMember(key, new ECKey(), new ECKey()); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( Collections.singletonList(member), Instant.EPOCH, 5L, @@ -1388,14 +1389,25 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(2000L), 2L, parameters); + List activeFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + activeFederationMembers, + Instant.ofEpochMilli(2000L), + 2L, + parameters + ); List retiringFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fb01")), BtcECKey.fromPrivate(Hex.decode("fb02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), Instant.ofEpochMilli(1000L), 1L, parameters); + List retiringFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + retiringFederationMembers, + Instant.ofEpochMilli(1000L), + 1L, + parameters); Repository repository = createRepository(); repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, LIMIT_MONETARY_BASE); @@ -1499,9 +1511,13 @@ void registerBtcTransactionWithCrossFederationsChange() throws Exception { .map(BtcECKey::fromPrivate) .sorted(BtcECKey.PUBKEY_COMPARATOR) .collect(Collectors.toList()); - Federation activeFederation = new StandardMultisigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), 5L, params + + List activeFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + activeFederationMembers, + Instant.ofEpochMilli(1000L), + 5L, + params ); final List retiringFedPrivateKeys = Arrays.asList( @@ -1594,7 +1610,13 @@ void registerBtcTransactionLockTxWhitelisted() throws Exception { }); federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation federation1 = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, btcParams); + List federation1Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys); + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( + federation1Members, + Instant.ofEpochMilli(1000L), + 0L, + btcParams + ); List federation2Keys = Arrays.asList(new BtcECKey[]{ BtcECKey.fromPrivate(Hex.decode("fb01")), @@ -1603,7 +1625,13 @@ void registerBtcTransactionLockTxWhitelisted() throws Exception { }); federation2Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation federation2 = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), Instant.ofEpochMilli(2000L), 0L, btcParams); + List federation2Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys); + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( + federation2Members, + Instant.ofEpochMilli(2000L), + 0L, + btcParams + ); Repository repository = createRepository(); repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, LIMIT_MONETARY_BASE); @@ -1754,13 +1782,13 @@ void getBtcTxHashProcessedHeight() throws IOException, BlockStoreException { @Test void getFederationMethods_genesis() throws IOException { - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation genesisFederation = new StandardMultisigFederation( + Federation genesisFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(6), Instant.ofEpochMilli(1000), 0L, @@ -1782,13 +1810,13 @@ void getFederationMethods_genesis() throws IOException { @Test void getFederationMethods_active() throws IOException { - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation genesisFederation = new StandardMultisigFederation( + Federation genesisFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(6), Instant.ofEpochMilli(1000), 0L, @@ -1818,13 +1846,13 @@ void getFederationMethods_active() throws IOException { @Test void getFederationMethods_newActivated() throws IOException { - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 15L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation oldFederation = new StandardMultisigFederation( + Federation oldFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(6), Instant.ofEpochMilli(1000), 0L, @@ -1858,13 +1886,13 @@ void getFederationMethods_newActivated() throws IOException { @Test void getFederationMethods_newNotActivated() throws IOException { - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 15L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation oldFederation = new StandardMultisigFederation( + Federation oldFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(6), Instant.ofEpochMilli(1000), 0L, @@ -1911,14 +1939,14 @@ void getRetiringFederationMethods_none() throws IOException { @Test void getRetiringFederationMethods_presentNewInactive() throws IOException { - Federation mockedNewFederation = new StandardMultisigFederation( + Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(2), Instant.ofEpochMilli(2000), 10L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation mockedOldFederation = new StandardMultisigFederation( + Federation mockedOldFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(4), Instant.ofEpochMilli(1000), 0L, @@ -1948,14 +1976,14 @@ void getRetiringFederationMethods_presentNewInactive() throws IOException { @Test void getRetiringFederationMethods_presentNewActive() throws IOException { - Federation mockedNewFederation = new StandardMultisigFederation( + Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(2), Instant.ofEpochMilli(2000), 10L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation mockedOldFederation = new StandardMultisigFederation( + Federation mockedOldFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(4), Instant.ofEpochMilli(1000), 0L, @@ -2165,14 +2193,14 @@ void createFederation_pendingExists() throws IOException, BridgeIllegalArgumentE void createFederation_withPendingActivation() throws IOException, BridgeIllegalArgumentException { VotingMocksProvider mocksProvider = new VotingMocksProvider("create", new byte[][]{}, false); - Federation mockedNewFederation = new StandardMultisigFederation( + Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(2), Instant.ofEpochMilli(2000), 10L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation mockedOldFederation = new StandardMultisigFederation( + Federation mockedOldFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(4), Instant.ofEpochMilli(1000), 0L, @@ -2206,14 +2234,14 @@ void createFederation_withPendingActivation() throws IOException, BridgeIllegalA void createFederation_withExistingRetiringFederation() throws IOException, BridgeIllegalArgumentException { VotingMocksProvider mocksProvider = new VotingMocksProvider("create", new byte[][]{}, false); - Federation mockedNewFederation = new StandardMultisigFederation( + Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(2), Instant.ofEpochMilli(2000), 10L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation mockedOldFederation = new StandardMultisigFederation( + Federation mockedOldFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(4), Instant.ofEpochMilli(1000), 0L, @@ -2735,6 +2763,7 @@ void rollbackFederation_noPendingFederation() throws IOException, BridgeIllegalA @Test void commitFederation_ok() throws IOException, BridgeIllegalArgumentException { + PendingFederation pendingFederation = new PendingFederation(FederationTestUtils.getFederationMembersWithKeys(Arrays.asList( BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")), @@ -2750,18 +2779,36 @@ void commitFederation_ok() throws IOException, BridgeIllegalArgumentException { when(executionBlock.getTimestamp()).thenReturn(15005L); when(executionBlock.getNumber()).thenReturn(15L); - Federation expectedFederation = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithKeys(Arrays.asList( - BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), - BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")), - BtcECKey.fromPublicOnly(Hex.decode("025eefeeeed5cdc40822880c7db1d0a88b7b986945ed3fc05a0b45fe166fe85e12")), - BtcECKey.fromPublicOnly(Hex.decode("03c67ad63527012fd4776ae892b5dc8c56f80f1be002dc65cd520a2efb64e37b49")))), - Instant.ofEpochMilli(15005L), 15L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); + List expectedFederationMembers = + FederationTestUtils.getFederationMembersWithKeys( + Arrays.asList( + BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), + BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")), + BtcECKey.fromPublicOnly(Hex.decode("025eefeeeed5cdc40822880c7db1d0a88b7b986945ed3fc05a0b45fe166fe85e12")), + BtcECKey.fromPublicOnly(Hex.decode("03c67ad63527012fd4776ae892b5dc8c56f80f1be002dc65cd520a2efb64e37b49")) + ) + ); + Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation( + expectedFederationMembers, + Instant.ofEpochMilli(15005L), + 15L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + ); - Federation newFederation = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithKeys(Arrays.asList( - BtcECKey.fromPublicOnly(Hex.decode("0346cb6b905e4dee49a862eeb2288217d06afcd4ace4b5ca77ebedfbc6afc1c19d")), - BtcECKey.fromPublicOnly(Hex.decode("0269a0dbe7b8f84d1b399103c466fb20531a56b1ad3a7b44fe419e74aad8c46db7")), - BtcECKey.fromPublicOnly(Hex.decode("026192d8ab41bd402eb0431457f6756a3f3ce15c955c534d2b87f1e0372d8ba338")))), - Instant.ofEpochMilli(5005L), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); + List newFederationMembers = + FederationTestUtils.getFederationMembersWithKeys( + Arrays.asList( + BtcECKey.fromPublicOnly(Hex.decode("0346cb6b905e4dee49a862eeb2288217d06afcd4ace4b5ca77ebedfbc6afc1c19d")), + BtcECKey.fromPublicOnly(Hex.decode("0269a0dbe7b8f84d1b399103c466fb20531a56b1ad3a7b44fe419e74aad8c46db7")), + BtcECKey.fromPublicOnly(Hex.decode("026192d8ab41bd402eb0431457f6756a3f3ce15c955c534d2b87f1e0372d8ba338")) + ) + ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationMembers, + Instant.ofEpochMilli(5005L), + 0L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + ); BridgeEventLogger eventLoggerMock = mock(BridgeEventLogger.class); @@ -2904,10 +2951,20 @@ void commitFederation_hashMismatch() throws IOException, BridgeIllegalArgumentEx @Test void getActiveFederationWallet() throws IOException { - Federation expectedFederation = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList(new BtcECKey[]{ - BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), - BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) - })), Instant.ofEpochMilli(5005L), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); + List expectedFederationMembers = + FederationTestUtils.getFederationMembersWithBtcKeys( + Arrays.asList( + BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), + BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) + ) + ); + Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation( + expectedFederationMembers, + Instant.ofEpochMilli(5005L), + 0L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + ); + BridgeSupport bridgeSupport = getBridgeSupportWithMocksForFederationTests( false, expectedFederation, @@ -2937,14 +2994,14 @@ void getActiveFederationWallet() throws IOException { @Test void getRetiringFederationWallet_nonEmpty() throws IOException { - Federation mockedNewFederation = new StandardMultisigFederation( + Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(2), Instant.ofEpochMilli(2000), 10L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - Federation expectedFederation = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList(new BtcECKey[]{ + Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList(new BtcECKey[]{ BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) })), Instant.ofEpochMilli(5005L), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 2bfee1299fc..7305e52ee7b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -7,6 +7,8 @@ import co.rsk.config.TestSystemProperties; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.Constants; @@ -238,7 +240,7 @@ void registerBtcTransaction_beforeRskip199_rejectsExternalCalls() ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); doReturn(false).when(activations).isActive(eq(RSKIP199), anyLong()); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, @@ -284,7 +286,7 @@ void registerBtcTransaction_beforeRskip199_acceptsCallFromFederationMember() List federationKeys = Arrays.asList(fed1Key, new BtcECKey(), new BtcECKey()); federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithKeys(federationKeys), Instant.ofEpochMilli(1000), 0L, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTestIntegration.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTestIntegration.java index 54fb781d41a..69422a6150c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTestIntegration.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTestIntegration.java @@ -50,6 +50,7 @@ import java.util.Set; import java.util.function.BiFunction; +import co.rsk.peg.federation.Federation; import co.rsk.test.builders.BlockChainBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.TestUtils; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java index 5f59ad6f9f3..9df877deefc 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java @@ -6,6 +6,8 @@ import co.rsk.config.BridgeRegTestConstants; import java.time.Instant; import java.util.List; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -456,7 +458,7 @@ void calculatePegoutTxSize_before_rskip_271() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(false); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, @@ -478,7 +480,7 @@ void calculatePegoutTxSize_after_rskip_271() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, @@ -493,7 +495,7 @@ void calculatePegoutTxSize_ZeroInput_ZeroOutput() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(false); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index bad859cbba4..8026fb61dff 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -33,9 +33,8 @@ import co.rsk.crypto.Keccak256; import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector; +import co.rsk.peg.federation.*; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.trie.Trie; import co.rsk.trie.TrieStore; @@ -471,7 +470,7 @@ void isInputSignedByThisFederator_isSigned() { // Arrange BtcECKey federator1Key = new BtcECKey(); BtcECKey federator2Key = new BtcECKey(); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(Arrays.asList(federator1Key, federator2Key)), Instant.now(), 0, @@ -519,7 +518,7 @@ void isInputSignedByThisFederator_isSignedByAnotherFederator() { // Arrange BtcECKey federator1Key = new BtcECKey(); BtcECKey federator2Key = new BtcECKey(); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(Arrays.asList(federator1Key, federator2Key)), Instant.now(), 0, @@ -567,7 +566,7 @@ void isInputSignedByThisFederator_notSigned() { // Arrange BtcECKey federator1Key = new BtcECKey(); BtcECKey federator2Key = new BtcECKey(); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(Arrays.asList(federator1Key, federator2Key)), Instant.now(), 0, @@ -913,7 +912,7 @@ void testCalculatePegoutTxSize_ZeroInput_ZeroOutput() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, @@ -929,7 +928,7 @@ void testCalculatePegoutTxSize_2Inputs_2Outputs() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, @@ -954,7 +953,7 @@ void testCalculatePegoutTxSize_9Inputs_2Outputs() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, @@ -979,7 +978,7 @@ void testCalculatePegoutTxSize_10Inputs_20Outputs() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, @@ -1007,7 +1006,7 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, @@ -1048,14 +1047,14 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs_erpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - new NonStandardErpRedeemScriptBuilder() + activations ); // Create a pegout tx with 50 inputs and 200 outputs @@ -1092,14 +1091,14 @@ void testCalculatePegoutTxSize_100Inputs_50Outputs_erpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - new NonStandardErpRedeemScriptBuilder() + activations ); // Create a pegout tx with 100 inputs and 50 outputs @@ -1126,7 +1125,7 @@ void getRegularPegoutTxSize_has_proper_calculations() { BtcECKey key2 = new BtcECKey(); BtcECKey key3 = new BtcECKey(); List keys = Arrays.asList(key1, key2, key3); - Federation fed = new StandardMultisigFederation( + Federation fed = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, @@ -1163,9 +1162,15 @@ void getRegularPegoutTxSize_has_proper_calculations() { } private void test_getSpendWallet(boolean isFlyoverCompatible) throws UTXOProviderException { - Federation federation = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList( - BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), - BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")))), + List federationMembers = + FederationTestUtils.getFederationMembersWithBtcKeys( + Arrays.asList( + BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), + BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) + ) + ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationMembers, Instant.ofEpochMilli(5005L), 0L, networkParameters); @@ -1194,9 +1199,15 @@ private void test_getSpendWallet(boolean isFlyoverCompatible) throws UTXOProvide } private void test_getNoSpendWallet(boolean isFlyoverCompatible) { - Federation federation = new StandardMultisigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList( - BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), - BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")))), + List federationMembers = + FederationTestUtils.getFederationMembersWithBtcKeys( + Arrays.asList( + BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), + BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) + ) + ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationMembers, Instant.ofEpochMilli(5005L), 0L, networkParameters); @@ -1423,14 +1434,14 @@ private Genesis getGenesisInstance(TrieStore trieStore) { private ErpFederation createErpFederation() { Federation genesisFederation = bridgeConstantsRegtest.getGenesisFederation(); - return new ErpFederation( + return FederationFactory.buildNonStandardErpFederation( genesisFederation.getMembers(), genesisFederation.getCreationTime(), genesisFederation.getCreationBlockNumber(), genesisFederation.getBtcParams(), bridgeConstantsRegtest.getErpFedPubKeysList(), bridgeConstantsRegtest.getErpFedActivationDelay(), - new NonStandardErpRedeemScriptBuilder() + activations ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java b/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java index e6ae63a464f..4346240ff15 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java @@ -23,6 +23,9 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.StandardMultisigFederation; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; @@ -37,7 +40,6 @@ import java.time.Instant; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.stream.Stream; @@ -167,7 +169,7 @@ void getFederatorPublicKeys() { ECKey rskKey1 = new ECKey(); ECKey mstKey1 = new ECKey(); - Federation theFederation = new StandardMultisigFederation( + Federation theFederation = FederationFactory.buildStandardMultiSigFederation( Arrays.asList( new FederationMember(btcKey0, rskKey0, mstKey0), new FederationMember(btcKey1, rskKey1, mstKey1) @@ -243,9 +245,11 @@ private Federation getNewFakeFederation(long creationBlockNumber) { ); List members = FederationTestUtils.getFederationMembersWithBtcKeys(keys); - return new StandardMultisigFederation( - members, Instant.ofEpochMilli(123), - creationBlockNumber, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + return FederationFactory.buildStandardMultiSigFederation( + members, + Instant.ofEpochMilli(123), + creationBlockNumber, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/FederationTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/FederationTestUtils.java index bd83f63d2d5..059e1ec825a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FederationTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/FederationTestUtils.java @@ -36,12 +36,15 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import org.ethereum.crypto.ECKey; public class FederationTestUtils { public static Federation getFederation(Integer... federationMemberPks) { - return new StandardMultisigFederation( + return FederationFactory.buildStandardMultiSigFederation( getFederationMembersFromPks(federationMemberPks), ZonedDateTime.parse("2017-06-10T02:30:01Z").toInstant(), 0L, diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java index fa0f5f3d935..c0da2ea3725 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java @@ -14,7 +14,7 @@ import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.wallet.RedeemData; import co.rsk.crypto.Keccak256; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; +import co.rsk.peg.federation.*; import co.rsk.peg.flyover.FlyoverFederationInformation; import java.time.Instant; import java.util.Arrays; @@ -23,6 +23,7 @@ import java.util.Optional; import java.util.stream.Collectors; import org.bouncycastle.util.encoders.Hex; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -42,21 +43,21 @@ class FlyoverCompatibleBtcWalletWithStorageTest { @BeforeEach void setup() { - federation = new StandardMultisigFederation( + federation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - erpFederation = new ErpFederation( + erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST), erpFedKeys, 5063, - new NonStandardErpRedeemScriptBuilder() + mock(ActivationConfig.ForBlock.class) ); federationList = Collections.singletonList(federation); diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java index d5348114524..9a7e63f76ef 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java @@ -1,6 +1,7 @@ package co.rsk.peg; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Context; @@ -10,7 +11,7 @@ import co.rsk.bitcoinj.script.FastBridgeRedeemScriptParser; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.wallet.RedeemData; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; +import co.rsk.peg.federation.*; import co.rsk.peg.flyover.FlyoverFederationInformation; import java.time.Instant; import java.util.Arrays; @@ -18,6 +19,8 @@ import java.util.List; import java.util.stream.Collectors; import org.bouncycastle.util.encoders.Hex; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -33,25 +36,31 @@ class FlyoverCompatibleBtcWallextWithSingleScriptTest { private ErpFederation erpFederation; private List federationList; private List erpFederationList; + private ActivationConfig.ForBlock activations; @BeforeEach void setup() { - federation = new StandardMultisigFederation( + federation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); - erpFederation = new ErpFederation( + activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST), erpFedKeys, 5063, - new NonStandardErpRedeemScriptBuilder() + activations ); federationList = Collections.singletonList(federation); diff --git a/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java index 678f3487a3e..f443f831ff1 100644 --- a/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java @@ -1,8 +1,8 @@ package co.rsk.peg; import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; -import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; -import static co.rsk.peg.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_CSV_VALUE; import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; @@ -22,6 +22,10 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.peg.bitcoin.*; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.ErpFederationCreationException; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.resources.TestConstants; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; @@ -95,17 +99,15 @@ private ErpFederation createDefaultNonStandardErpFederation() { List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(defaultKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); - return new ErpFederation( + return FederationFactory.buildNonStandardErpFederation( standardMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue, - erpRedeemScriptBuilder + activations ); } @@ -235,42 +237,42 @@ void testEquals_basic() { @Test void testEquals_same() { - ErpFederation otherFederation = new ErpFederation( + ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - erpRedeemScriptBuilder + activations ); assertEquals(federation, otherFederation); } @Test void testEquals_differentCreationTime() { - ErpFederation otherFederation = new ErpFederation( + ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation( federation.getMembers(), federation.getCreationTime().plus(1, ChronoUnit.MILLIS), federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - erpRedeemScriptBuilder + activations ); assertEquals(federation, otherFederation); } @Test void testEquals_differentCreationBlockNumber() { - ErpFederation otherFederation = new ErpFederation( + ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber() + 1, federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay(), - erpRedeemScriptBuilder + activations ); assertEquals(federation, otherFederation); } @@ -690,15 +692,15 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); - ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); - assertThrows(ErpFederationCreationException.class, () -> new ErpFederation( + assertThrows(ErpFederationCreationException.class, + () -> FederationFactory.buildNonStandardErpFederation( federationMembersWithBtcKeys, creationTime, 1, btcParams, emergencyMultisigKeys, activationDelay, - builder + activations )); } diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index 14a0dd93d08..6680e6e9346 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -1,8 +1,8 @@ package co.rsk.peg; import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; -import static co.rsk.peg.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; -import static co.rsk.peg.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_CSV_VALUE; import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; @@ -28,6 +28,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import co.rsk.peg.federation.*; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; @@ -85,14 +86,13 @@ private ErpFederation createDefaultP2shErpFederation() { Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - return new ErpFederation( + return FederationFactory.buildP2shErpFederation( standardMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, - activationDelayValue, - new P2shErpRedeemScriptBuilder() + activationDelayValue ); } @@ -206,15 +206,13 @@ void testEquals_basic() { @Test void testEquals_same() { - P2shErpRedeemScriptBuilder p2shErpRedeemScriptBuilder = new P2shErpRedeemScriptBuilder(); - ErpFederation otherFederation = new ErpFederation( + ErpFederation otherFederation = FederationFactory.buildP2shErpFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), - federation.getActivationDelay(), - p2shErpRedeemScriptBuilder + federation.getActivationDelay() ); assertEquals(federation, otherFederation); @@ -326,26 +324,23 @@ void getStandardRedeemScript() { int creationBlock = 0; NetworkParameters btcParams = BridgeRegTestConstants.getInstance().getBtcParams(); - ActivationConfig.ForBlock activations = ActivationConfigsForTest.all().forBlock(0); - - // Create a legacy powpeg and then a p2sh valid one. Both of them should produce the same standard redeem script - StandardMultisigFederation legacyFed = new StandardMultisigFederation( + // Create a standard multisig powpeg and then a p2sh valid one. Both of them should produce the same default redeem script + StandardMultisigFederation standardMultisigFed = FederationFactory.buildStandardMultiSigFederation( members, creationTime, creationBlock, btcParams ); - ErpFederation p2shFed = new ErpFederation( + ErpFederation p2shFed = FederationFactory.buildP2shErpFederation( members, creationTime, creationBlock, btcParams, Arrays.asList(new BtcECKey(), new BtcECKey()), - 10_000, - new P2shErpRedeemScriptBuilder() + 10_000 ); - assertEquals(legacyFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); + assertEquals(standardMultisigFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); Assertions.assertNotEquals(p2shFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); } @@ -447,14 +442,13 @@ void getErpRedeemScript_compareOtherImplementation_P2SHERPFederation() throws IO for (RawGeneratedRedeemScript generatedScript : generatedScripts) { // Skip test cases with invalid redeem script that exceed the maximum size if (generatedScript.script.getProgram().length <= MAX_SCRIPT_ELEMENT_SIZE) { - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(generatedScript.mainFed), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 1, NetworkParameters.fromID(NetworkParameters.ID_TESTNET), generatedScript.emergencyFed, - generatedScript.timelock, - new P2shErpRedeemScriptBuilder() + generatedScript.timelock ); Script rskjScript = erpFederation.getRedeemScript(); @@ -481,14 +475,13 @@ void spendFromP2shErpFed( true ); - ErpFederation p2shErpFed = new ErpFederation( + ErpFederation p2shErpFed = FederationFactory.buildP2shErpFederation( FederationMember.getFederationMembersFromKeys(defaultKeys), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 0L, networkParameters, emergencyKeys, - activationDelay, - new P2shErpRedeemScriptBuilder() + activationDelay ); Coin value = Coin.valueOf(1_000_000); diff --git a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java index aaba819daaa..8ac25eab272 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java @@ -26,14 +26,14 @@ import co.rsk.config.BridgeConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.simples.SimpleRskTransaction; import org.bouncycastle.util.encoders.Hex; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.core.Transaction; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.Keccak256Helper; -import org.mockito.Mockito; import java.time.Instant; import java.util.ArrayList; @@ -301,7 +301,7 @@ public static Federation createFederation(BridgeConstants bridgeConstants, Strin public static Federation createFederation(BridgeConstants bridgeConstants, List federationKeys) { federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - return new StandardMultisigFederation( + return FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -311,14 +311,13 @@ public static Federation createFederation(BridgeConstants bridgeConstants, List< public static ErpFederation createP2shErpFederation(BridgeConstants bridgeConstants, List federationKeys) { federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - return new ErpFederation( + return FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys), Instant.ofEpochMilli(1000L), 0L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsAllUTXOsToFedAreAboveMinimumPeginValueTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsAllUTXOsToFedAreAboveMinimumPeginValueTest.java index f44f3960904..3d73b1e2ec8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsAllUTXOsToFedAreAboveMinimumPeginValueTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsAllUTXOsToFedAreAboveMinimumPeginValueTest.java @@ -18,6 +18,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import co.rsk.peg.federation.Federation; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.junit.jupiter.api.BeforeEach; diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsEvaluatePeginTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsEvaluatePeginTest.java index 66e5346517b..74b59f1b0ed 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsEvaluatePeginTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsEvaluatePeginTest.java @@ -15,6 +15,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.btcLockSender.BtcLockSender; +import co.rsk.peg.federation.Federation; import co.rsk.peg.pegin.PeginEvaluationResult; import co.rsk.peg.pegin.PeginProcessAction; import co.rsk.peg.pegin.RejectedPeginReason; diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java index a6cb23f11b5..5e29272d8a7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java @@ -27,6 +27,8 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.bitcoin.BitcoinUtils; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; import co.rsk.test.builders.BridgeSupportBuilder; import java.util.Arrays; import java.util.List; @@ -2116,7 +2118,7 @@ void old_fed_to_live_fed( FederationTestUtils.addSignatures(oldFederation, REGTEST_OLD_FEDERATION_PRIVATE_KEYS, migrationTx); - Assertions.assertTrue(PegUtilsLegacy.txIsFromOldFederation(migrationTx, oldFederation.address)); + Assertions.assertTrue(PegUtilsLegacy.txIsFromOldFederation(migrationTx, oldFederation.getAddress())); // Act PegTxType transactionType = PegUtils.getTransactionType( diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java index 1d09e818f43..5a549014113 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java @@ -1,29 +1,15 @@ package co.rsk.peg; -import static co.rsk.peg.PegTestUtils.createFederation; -import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP186; -import static org.mockito.Mockito.mock; - -import co.rsk.bitcoinj.core.Address; -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.BtcTransaction; -import co.rsk.bitcoinj.core.Coin; -import co.rsk.bitcoinj.core.Context; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.core.Sha256Hash; +import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import java.time.Instant; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Stream; - -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; @@ -34,6 +20,16 @@ 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 org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP186; +import static org.mockito.Mockito.mock; + class PegUtilsLegacyGetTransactionTypeTest { private static final BridgeConstants bridgeMainnetConstants = BridgeMainNetConstants.getInstance(); private static final NetworkParameters btcMainnetParams = bridgeMainnetConstants.getBtcParams(); @@ -71,28 +67,26 @@ void test_sentFromP2SHErpFed() { ); // Arrange - Federation activeFederation = new ErpFederation( + ErpFederation activeFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), bridgeMainnetConstants.getGenesisFederation().getCreationTime(), 5L, bridgeMainnetConstants.getGenesisFederation().getBtcParams(), bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeMainnetConstants.getErpFedActivationDelay() ); List fedKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - ErpFederation p2shRetiringFederation = new ErpFederation( + ErpFederation p2shRetiringFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeMainnetConstants.getErpFedActivationDelay() ); // Create a migrationTx from the p2sh erp fed @@ -141,7 +135,7 @@ void test_sentFromOldFed(ActivationConfig.ForBlock activations, PegTxType expect ); // Arrange - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( bridgeRegTestConstants.getGenesisFederation().getMembers(), bridgeRegTestConstants.getGenesisFederation().getCreationTime(), 5L, @@ -345,14 +339,13 @@ void test_pegin( new String[]{"fa04", "fa05", "fa06"}, true ); - Federation activeFederation = new ErpFederation( + ErpFederation activeFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFedKeys), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, erpFedKeys, - 100L, - new P2shErpRedeemScriptBuilder() + 100L ); BtcTransaction peginTx = new BtcTransaction(btcMainnetParams); @@ -384,7 +377,7 @@ void test_pegout_tx() { new String[]{"fa01", "fa02", "fa03"}, true ); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), Instant.ofEpochMilli(1000L), 0L, @@ -427,7 +420,7 @@ void test_migration_tx() { new String[]{"fa01", "fa02", "fa03"}, true );; - Federation retiringFederation = new StandardMultisigFederation( + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedKeys), Instant.ofEpochMilli(1000L), 0L, @@ -465,7 +458,7 @@ void test_migration_to_p2shFed_tx() { new String[]{"fa01", "fa02", "fa03"}, true ); - Federation retiringFederation = new StandardMultisigFederation( + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedKeys), Instant.ofEpochMilli(1000L), 0L, diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java index 0096e80b33e..dfe71a74417 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java @@ -1,32 +1,17 @@ package co.rsk.peg; -import co.rsk.bitcoinj.core.Address; -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.BtcTransaction; -import co.rsk.bitcoinj.core.Coin; -import co.rsk.bitcoinj.core.Context; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.core.Sha256Hash; -import co.rsk.bitcoinj.core.TransactionInput; -import co.rsk.bitcoinj.core.TransactionOutPoint; -import co.rsk.bitcoinj.core.Utils; +import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.crypto.TransactionSignature; -import co.rsk.bitcoinj.script.ErpFederationRedeemScriptParser; -import co.rsk.bitcoinj.script.FastBridgeErpRedeemScriptParser; -import co.rsk.bitcoinj.script.FastBridgeP2shErpRedeemScriptParser; -import co.rsk.bitcoinj.script.FastBridgeRedeemScriptParser; -import co.rsk.bitcoinj.script.Script; -import co.rsk.bitcoinj.script.ScriptBuilder; -import co.rsk.bitcoinj.script.ScriptOpCodes; +import co.rsk.bitcoinj.script.*; import co.rsk.bitcoinj.wallet.RedeemData; import co.rsk.bitcoinj.wallet.Wallet; import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; -import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import co.rsk.peg.btcLockSender.BtcLockSender; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; @@ -42,15 +27,12 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static co.rsk.peg.PegUtilsLegacy.*; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import static co.rsk.peg.PegUtilsLegacy.*; - class PegUtilsLegacyTest { private ActivationConfig.ForBlock activations; @@ -227,7 +209,7 @@ void testIsValidPegInTxForTwoFederations() { BtcECKey.fromPrivate(Hex.decode("fa02")) ); federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation federation1 = new StandardMultisigFederation( + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, @@ -240,7 +222,7 @@ void testIsValidPegInTxForTwoFederations() { BtcECKey.fromPrivate(Hex.decode("fb03")) ); federation2Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation federation2 = new StandardMultisigFederation( + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), Instant.ofEpochMilli(2000L), 0L, @@ -557,7 +539,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_beforeRskip201_isP BtcECKey.fromPrivate(Hex.decode("fa02")) ); erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new StandardMultisigFederation( + Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -601,7 +583,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_afterRskip201_notP BtcECKey.fromPrivate(Hex.decode("fa02")) ); erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new StandardMultisigFederation( + Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -645,7 +627,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpFederation_beforeRskip201_isPegin() BtcECKey.fromPrivate(Hex.decode("fa02")) ); erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new StandardMultisigFederation( + Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -680,7 +662,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpFederation_afterRskip201_notPegin() BtcECKey.fromPrivate(Hex.decode("fa02")) ); erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = new StandardMultisigFederation( + Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -715,7 +697,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverRetiredFederation_beforeRskip201 BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -762,7 +744,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverRetiredFederation_afterRskip201_ BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -809,7 +791,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_beforeRskip BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -822,16 +804,14 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_beforeRskip ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpRedeemScriptBuilder erpRedeemScriptBuilder - = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - erpRedeemScriptBuilder + activations ); // Create a tx from the retired fast bridge fed to the active fed @@ -874,7 +854,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -887,16 +867,14 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpRedeemScriptBuilder erpRedeemScriptBuilder - = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - erpRedeemScriptBuilder + activations ); // Create a tx from the retired fast bridge fed to the active fed @@ -938,7 +916,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -951,16 +929,14 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpRedeemScriptBuilder erpRedeemScriptBuilder - = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - erpRedeemScriptBuilder + activations ); // Create a tx from the retired erp fed to the active fed @@ -998,7 +974,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_afterRskip201_notP BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -1011,16 +987,14 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_afterRskip201_notP ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpRedeemScriptBuilder erpRedeemScriptBuilder - = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - erpRedeemScriptBuilder + activations ); // Create a tx from the retired erp fed to the active fed @@ -1262,14 +1236,13 @@ private void testIsValidPegInTx_fromP2shErpScriptSender( List emergencyKeys = PegTestUtils.createRandomBtcECKeys(3); long activationDelay = 256L; - Federation p2shErpFederation = new ErpFederation( + Federation p2shErpFederation = FederationFactory.buildP2shErpFederation( activeFederation.getMembers(), activeFederation.getCreationTime(), activeFederation.getCreationBlockNumber(), networkParameters, emergencyKeys, - activationDelay, - new P2shErpRedeemScriptBuilder() + activationDelay ); Script flyoverP2shErpRedeemScript = FastBridgeP2shErpRedeemScriptParser.createFastBridgeP2shErpRedeemScript( @@ -1329,14 +1302,13 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - ErpFederation retiredFederation = new ErpFederation( + ErpFederation retiredFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstantsMainnet.getErpFedActivationDelay() ); List activeFederationKeys = Stream.of( @@ -1344,14 +1316,13 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new ErpFederation( + Federation activeFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstantsMainnet.getErpFedActivationDelay() ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1401,14 +1372,13 @@ void testIsMigrationTx_sending_funds_from_retiring_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = new ErpFederation( + Federation retiringFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFed), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstantsMainnet.getErpFedActivationDelay() ); List activeFederationKeys = Stream.of( @@ -1416,14 +1386,13 @@ void testIsMigrationTx_sending_funds_from_retiring_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new ErpFederation( + Federation activeFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstantsMainnet.getErpFedActivationDelay() ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1463,7 +1432,7 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_p2sh_fe BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1475,14 +1444,13 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_p2sh_fe BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new ErpFederation( + Federation activeFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstantsMainnet.getErpFedActivationDelay() ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1532,7 +1500,7 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_p2sh_f BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = new StandardMultisigFederation( + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1544,14 +1512,13 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_p2sh_f BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new ErpFederation( + Federation activeFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstantsMainnet.getErpFedActivationDelay() ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1591,7 +1558,7 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_standar BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1603,7 +1570,7 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_standar BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1657,7 +1624,7 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_standa BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = new StandardMultisigFederation( + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1669,7 +1636,7 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_standa BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1710,7 +1677,7 @@ void testIsMigrationTx() { BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = new StandardMultisigFederation( + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(2000L), 2L, @@ -1722,7 +1689,7 @@ void testIsMigrationTx() { BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = new StandardMultisigFederation( + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1733,7 +1700,7 @@ void testIsMigrationTx() { BtcECKey.fromPrivate(Hex.decode("fc01")), BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiredFederation = new StandardMultisigFederation( + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1869,7 +1836,7 @@ void testIsPegOutTx() { BtcECKey.fromPrivate(Hex.decode("fa02")), BtcECKey.fromPrivate(Hex.decode("fa03")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation federation2 = new StandardMultisigFederation( + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(2000L), 2L, @@ -1906,7 +1873,7 @@ void testIsPegOutTx_fromFlyoverFederation() { BtcECKey.fromPrivate(Hex.decode("fa03")) ); flyoverFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation flyoverFederation = new StandardMultisigFederation( + Federation flyoverFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(flyoverFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -1964,7 +1931,7 @@ void testIsPegOutTx_fromErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa03")) ); defaultFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation defaultFederation = new StandardMultisigFederation( + Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -1978,16 +1945,14 @@ void testIsPegOutTx_fromErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpRedeemScriptBuilder erpRedeemScriptBuilder - = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); - ErpFederation erpFederation = new ErpFederation( + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - erpRedeemScriptBuilder + activations ); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -2042,7 +2007,7 @@ void testIsPegOutTx_fromFlyoverErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa03")) ); defaultFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation defaultFederation = new StandardMultisigFederation( + Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, @@ -2056,16 +2021,14 @@ void testIsPegOutTx_fromFlyoverErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpRedeemScriptBuilder erpRedeemScriptBuilder - = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, networkParameters); - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, 500L, - erpRedeemScriptBuilder + activations ); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -2158,7 +2121,7 @@ void testChangeBetweenFederations() { .map(BtcECKey::fromPrivate) .sorted(BtcECKey.PUBKEY_COMPARATOR) .collect(Collectors.toList()); - Federation federation1 = new StandardMultisigFederation( + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); @@ -2168,9 +2131,12 @@ void testChangeBetweenFederations() { .map(BtcECKey::fromPrivate) .sorted(BtcECKey.PUBKEY_COMPARATOR) .collect(Collectors.toList()); - Federation federation2 = new StandardMultisigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), - Instant.ofEpochMilli(2000L), 0L, networkParameters + List federation2Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys); + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( + federation2Members, + Instant.ofEpochMilli(2000L), + 0L, + networkParameters ); Address federation2Address = federation2.getAddress(); 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 f8a47a9c66b..0612e5f008d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java @@ -1,12 +1,6 @@ package co.rsk.peg; -import co.rsk.bitcoinj.core.BtcTransaction; -import co.rsk.bitcoinj.core.Coin; -import co.rsk.bitcoinj.core.Context; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.core.Address; -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.Sha256Hash; +import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.wallet.Wallet; @@ -16,7 +10,9 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import co.rsk.test.builders.BridgeSupportBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -210,14 +206,13 @@ void test_getTransactionType_pegin_output_to_retiring_fed_and_other_addresses() List signers = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - ErpFederation activeFed = new ErpFederation( + ErpFederation activeFed = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(signers), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeMainnetConstants.getErpFedActivationDelay() ); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); @@ -613,14 +608,13 @@ void test_getTransactionType_flyover_segwit() { List signers = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - ErpFederation activeFed = new ErpFederation( + ErpFederation activeFed = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersWithBtcKeys(signers), Instant.ofEpochMilli(1000L), 0L, btcTestNetParams, bridgeTestNetConstants.getErpFedPubKeysList(), - bridgeTestNetConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeTestNetConstants.getErpFedActivationDelay() ); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index b52550c1793..2cb0794cb3e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -27,6 +27,7 @@ import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.*; import co.rsk.peg.resources.TestConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -291,29 +292,26 @@ private void testBuildFederation( Federation expectedFederation; if (isRskip353Active) { - expectedFederation = new ErpFederation( + expectedFederation = FederationFactory.buildP2shErpFederation( FederationTestUtils.getFederationMembersFromPks(privateKeys), creationTime, 0L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); } else if (isRskip201Active) { - ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); - expectedFederation = new ErpFederation( + expectedFederation = FederationFactory.buildNonStandardErpFederation( FederationTestUtils.getFederationMembersFromPks(privateKeys), creationTime, 0L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - erpRedeemScriptBuilder + activations ); } else { - expectedFederation = new StandardMultisigFederation( + expectedFederation = FederationFactory.buildStandardMultiSigFederation( FederationTestUtils.getFederationMembersFromPks(privateKeys), creationTime, 0L, diff --git a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java index 66fb45715d6..210f5c887c1 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java @@ -1,12 +1,6 @@ package co.rsk.peg; -import co.rsk.bitcoinj.core.Address; -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.BtcTransaction; -import co.rsk.bitcoinj.core.Coin; -import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.core.Sha256Hash; -import co.rsk.bitcoinj.core.TransactionInput; +import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.crypto.TransactionSignature; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; @@ -15,7 +9,9 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.ErpFederation; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -31,23 +27,12 @@ import java.nio.charset.StandardCharsets; import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; import static co.rsk.peg.FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR; -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -72,21 +57,22 @@ void test_each_input_sighash_is_unique(NetworkParameters networkParameters) { // Arrange int erpFedActivationDelay = 720; - List fedMembers = FedSigner.listOf("fed1", "fed2", "fed3", "fed4", "fed5", "fed6", "fed7"); - List erpFedMembers = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); + List fedSigners = FedSigner.listOf("fed1", "fed2", "fed3", "fed4", "fed5", "fed6", "fed7"); + List erpFedSigners = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = new ErpFederation( - fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), + List fedMembers = fedSigners.stream().map(FedSigner::getFed).collect(Collectors.toList()); + List erpFedPubKeys = erpFedSigners.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); + ErpFederation fed = FederationFactory.buildP2shErpFederation( + fedMembers, Instant.now(), 0L, networkParameters, - erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), - erpFedActivationDelay, - new P2shErpRedeemScriptBuilder() + erpFedPubKeys, + erpFedActivationDelay ); List utxos = new ArrayList<>(); @@ -117,7 +103,7 @@ void test_each_input_sighash_is_unique(NetworkParameters networkParameters) { networkParameters, erpFedActivationDelay, fed, - fedMembers, + fedSigners, false, utxos, totalAmount.minus(Coin.valueOf(15_000)), @@ -153,14 +139,13 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = new ErpFederation( + ErpFederation fed = FederationFactory.buildP2shErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), - erpFedActivationDelay, - new P2shErpRedeemScriptBuilder() + erpFedActivationDelay ); List utxos = new ArrayList<>(); @@ -250,14 +235,13 @@ void test_sighash_is_equal_for_signed_input_and_unsigned_input(NetworkParameters when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = new ErpFederation( + ErpFederation fed = FederationFactory.buildP2shErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), - erpFedActivationDelay, - new P2shErpRedeemScriptBuilder() + erpFedActivationDelay ); List utxos = new ArrayList<>(); @@ -312,14 +296,13 @@ void test_each_input_sighash_is_unique_using_real_tx_testnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = new ErpFederation( + ErpFederation fed = FederationFactory.buildP2shErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), - erpFedActivationDelay, - new P2shErpRedeemScriptBuilder() + erpFedActivationDelay ); Address expectedAddress = Address.fromBase58( @@ -393,19 +376,19 @@ void test_each_input_sighash_is_unique_for_a_signed_erp_tx_testnet() { List fedMembers = FedSigner.listOf("federator1", "federator2", "federator6"); List erpFedMembers = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); + List fedPubKeys = erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = new ErpFederation( + ErpFederation fed = FederationFactory.buildP2shErpFederation( fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, - erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), - erpFedActivationDelay, - new P2shErpRedeemScriptBuilder() + fedPubKeys, + erpFedActivationDelay ); Address expectedAddress = Address.fromBase58( @@ -489,14 +472,13 @@ void test_redeemScript_can_be_obtained_from_input() { FedSigner::getFed ).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); - ErpFederation fed = new ErpFederation( + ErpFederation fed = FederationFactory.buildP2shErpFederation( fedMembers, Instant.now(), 0L, networkParameters, erpPubKeys, - erpFedActivationDelay, - new P2shErpRedeemScriptBuilder() + erpFedActivationDelay ); Address expectedAddress = Address.fromBase58( diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index 15b6f1a62ce..ad63b28ab1b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -11,9 +11,9 @@ import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; import co.rsk.peg.bitcoin.BitcoinUtils; -import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; +import co.rsk.peg.federation.*; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.test.builders.BridgeSupportBuilder; @@ -133,26 +133,24 @@ private void testChangePowpeg( Federation originalPowpeg; switch (oldPowPegFederationType) { case legacyErp: - ErpRedeemScriptBuilder erpRedeemScriptBuilder = new NonStandardErpRedeemScriptBuilder(); - originalPowpeg = new ErpFederation( + originalPowpeg = FederationFactory.buildNonStandardErpFederation( originalPowpegMembers, Instant.now(), 0, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - erpRedeemScriptBuilder + activations ); break; case p2shErp: - originalPowpeg = new ErpFederation( + originalPowpeg = FederationFactory.buildP2shErpFederation( originalPowpegMembers, Instant.now(), 0, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - new P2shErpRedeemScriptBuilder() + bridgeConstants.getErpFedActivationDelay() ); // TODO: CHECK REDEEMSCRIPT break; diff --git a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java index 5a3e446f6de..7b7d700ecd9 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java @@ -53,7 +53,7 @@ import java.util.Collections; import java.util.List; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilder; +import co.rsk.peg.federation.*; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.junit.jupiter.api.Assertions; @@ -92,7 +92,7 @@ void setup() { @Test void first_output_pay_fees() { - Federation federation = new StandardMultisigFederation( + Federation federation = FederationFactory.buildStandardMultiSigFederation( FederationMember.getFederationMembersFromKeys(Arrays.asList( new BtcECKey(), new BtcECKey(), @@ -161,12 +161,13 @@ void first_output_pay_fees() { @Test void build_pegout_tx_from_erp_federation() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); // Use mainnet constants to test a real situation BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); - Federation erpFederation = new ErpFederation( + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( FederationMember.getFederationMembersFromKeys(Arrays.asList( new BtcECKey(), new BtcECKey(), @@ -177,7 +178,7 @@ void build_pegout_tx_from_erp_federation() { bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay(), - new NonStandardErpRedeemScriptBuilder() + activations ); List utxos = Arrays.asList( @@ -210,7 +211,7 @@ void build_pegout_tx_from_erp_federation() { ReleaseTransactionBuilder releaseTransactionBuilder = new ReleaseTransactionBuilder( bridgeConstants.getBtcParams(), thisWallet, - erpFederation.address, + erpFederation.getAddress(), Coin.SATOSHI.multiply(1000), activations ); diff --git a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java index cdc787066bb..b41fd8abaf5 100644 --- a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java @@ -36,6 +36,9 @@ import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.peg.bitcoin.ScriptCreationException; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.StandardMultisigFederation; import org.bouncycastle.util.encoders.Hex; import org.ethereum.TestUtils; import org.ethereum.crypto.ECKey; @@ -83,12 +86,15 @@ void createInvalidFederation_aboveMaxScriptSigSize() { newKeys.add(federator15PublicKey); List newMembers = FederationTestUtils.getFederationMembersWithBtcKeys(newKeys); Instant creationTime = federation.getCreationTime(); + long creationBlockNumber = federation.getCreationBlockNumber(); + NetworkParameters networkParameters = federation.getBtcParams(); ScriptCreationException exception = - assertThrows(ScriptCreationException.class, () -> new StandardMultisigFederation( + assertThrows(ScriptCreationException.class, + () -> FederationFactory.buildStandardMultiSigFederation( newMembers, creationTime, - federation.creationBlockNumber, - federation.btcParams + creationBlockNumber, + networkParameters )); assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); } @@ -123,7 +129,7 @@ void testEquals_basic() { @Test void testEquals_same() { - Federation otherFederation = new StandardMultisigFederation( + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), @@ -135,7 +141,7 @@ void testEquals_same() { @Test void testEquals_differentCreationTime() { - Federation otherFederation = new StandardMultisigFederation( + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( federation.getMembers(), federation.getCreationTime().plus(1, ChronoUnit.MILLIS), federation.getCreationBlockNumber(), @@ -146,7 +152,7 @@ void testEquals_differentCreationTime() { @Test void testEquals_differentCreationBlockNumber() { - Federation otherFederation = new StandardMultisigFederation( + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber() + 1, @@ -157,7 +163,7 @@ void testEquals_differentCreationBlockNumber() { @Test void testEquals_differentNetworkParameters() { - Federation otherFederation = new StandardMultisigFederation( + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), @@ -174,7 +180,7 @@ void testEquals_differentNumberOfMembers() { newKeys.remove(14); List newMembers = FederationTestUtils.getFederationMembersWithKeys(newKeys); - Federation otherFederation = new StandardMultisigFederation( + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( newMembers, federation.getCreationTime(), federation.getCreationBlockNumber(), @@ -195,10 +201,12 @@ void testEquals_differentMembers() { newKeys.add(anotherPublicKey); List differentMembers = FederationTestUtils.getFederationMembersWithKeys(newKeys); - Federation otherFederation = new StandardMultisigFederation( + Instant creationTime = federation.getCreationTime(); + long creationBlockNumber = federation.getCreationBlockNumber(); + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( differentMembers, - federation.getCreationTime(), - federation.getCreationBlockNumber(), + creationTime, + creationBlockNumber, networkParameters ); diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java index 96b4a111779..1669dc0527f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java @@ -21,6 +21,9 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.peg.*; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.StandardMultisigFederation; import org.ethereum.TestUtils; import org.ethereum.core.CallTransaction; import org.ethereum.core.Repository; @@ -114,7 +117,7 @@ private BridgeStorageProviderInitializer buildInitializer(boolean genesis) { int numFederators = Helper.randomInRange(minFederators, maxFederators); List members = getNRandomFederationMembers(numFederators); - federation = new StandardMultisigFederation( + federation = FederationFactory.buildStandardMultiSigFederation( members, Instant.ofEpochMilli(TestUtils.generateLong(String.valueOf(executionIndex))), Helper.randomInRange(1, 10), diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/AddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/AddSignatureTest.java index 0b7ecc5c40c..c127ba7c6f9 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/AddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/AddSignatureTest.java @@ -32,7 +32,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.Bridge; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.Federation; +import co.rsk.peg.federation.Federation; import co.rsk.peg.PegTestUtils; import org.ethereum.TestUtils; import org.ethereum.core.Repository; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java index 5ea9bde7cbd..1d1abb206ba 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java @@ -22,6 +22,7 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.core.RskAddress; import co.rsk.peg.*; +import co.rsk.peg.federation.PendingFederation; import org.ethereum.core.Repository; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/GetFeePerKbTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/GetFeePerKbTest.java index 9a8cba89f21..2e102d078ea 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/GetFeePerKbTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/GetFeePerKbTest.java @@ -22,7 +22,7 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.peg.Bridge; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.Federation; +import co.rsk.peg.federation.Federation; import org.ethereum.core.Repository; import org.ethereum.vm.exception.VMException; import org.junit.jupiter.api.Assertions; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java index 0d5c580939c..94b53c3e681 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java @@ -21,7 +21,7 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.peg.Bridge; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.PendingFederation; +import co.rsk.peg.federation.PendingFederation; import org.ethereum.core.CallTransaction; import org.ethereum.core.Repository; import org.ethereum.vm.exception.VMException; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/RegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/RegisterBtcTransactionTest.java index a2cc1b3ac1c..2a99f9b68f8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/RegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/RegisterBtcTransactionTest.java @@ -24,6 +24,7 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.core.RskAddress; import co.rsk.peg.*; +import co.rsk.peg.PegTestUtils; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Repository; import org.ethereum.crypto.ECKey; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/RegisterFlyoverBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/RegisterFlyoverBtcTransactionTest.java index f58290b09eb..b8721aac45c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/RegisterFlyoverBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/RegisterFlyoverBtcTransactionTest.java @@ -9,6 +9,7 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.*; +import co.rsk.peg.PegTestUtils; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.core.Repository; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java index 227f4d13f5a..87621156339 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java @@ -21,8 +21,8 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.peg.Bridge; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.Federation; -import co.rsk.peg.StandardMultisigFederation; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; import org.ethereum.core.CallTransaction; import org.ethereum.core.Repository; import org.ethereum.vm.exception.VMException; @@ -104,7 +104,7 @@ private BridgeStorageProviderInitializer buildInitializer(boolean present) { return (BridgeStorageProvider provider, Repository repository, int executionIndex, BtcBlockStore blockStore) -> { if (present) { int numFederators = Helper.randomInRange(minFederators, maxFederators); - retiringFederation = new StandardMultisigFederation( + retiringFederation = FederationFactory.buildStandardMultiSigFederation( ActiveFederationTest.getNRandomFederationMembers(numFederators), Instant.ofEpochMilli(random.nextLong()), Helper.randomInRange(1, 10), diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/StateForBtcReleaseClientTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/StateForBtcReleaseClientTest.java index b678be31160..0abfa48fbc2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/StateForBtcReleaseClientTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/StateForBtcReleaseClientTest.java @@ -26,7 +26,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.Bridge; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.Federation; +import co.rsk.peg.federation.Federation; import co.rsk.peg.PegTestUtils; import org.ethereum.TestUtils; import org.ethereum.core.Repository; diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index 369dc1898bd..f6fed8bb0c4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -23,6 +23,9 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.*; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.PegTestUtils; import co.rsk.peg.pegin.RejectedPeginReason; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -222,7 +225,7 @@ void logCommitFederation(boolean isRSKIP383Active) { List oldFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(oldFederationKeys); - Federation oldFederation = new StandardMultisigFederation( + Federation oldFederation = FederationFactory.buildStandardMultiSigFederation( oldFederationMembers, Instant.ofEpochMilli(15005L), 15L, @@ -237,7 +240,7 @@ void logCommitFederation(boolean isRSKIP383Active) { List newFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(newFederationKeys); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( newFederationMembers, Instant.ofEpochMilli(5005L), 0L, diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java index dfc52e60c63..7b64743c592 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java @@ -24,6 +24,9 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.*; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.PegTestUtils; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -207,7 +210,7 @@ void testLogCommitFederationBeforeRskip146() { List oldFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(oldFederationKeys); - Federation oldFederation = new StandardMultisigFederation(oldFederationMembers, + Federation oldFederation = FederationFactory.buildStandardMultiSigFederation(oldFederationMembers, Instant.ofEpochMilli(15005L), 15L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); List newFederationKeys = Arrays.asList( @@ -218,7 +221,7 @@ void testLogCommitFederationBeforeRskip146() { List newFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(newFederationKeys); - Federation newFederation = new StandardMultisigFederation( + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( newFederationMembers, Instant.ofEpochMilli(5005L), 0L, From d61b240867b522d1a9c8735c8930f879f65d7140 Mon Sep 17 00:00:00 2001 From: julia zack Date: Wed, 6 Dec 2023 21:19:31 -0300 Subject: [PATCH 036/137] Create federation package in tests and move federation related tests to it. Move FederationMember to federation package to avoid circular dependency. Rename int i to int version to use meaningful names --- .../java/co/rsk/config/BridgeDevNetConstants.java | 2 +- .../java/co/rsk/config/BridgeMainNetConstants.java | 2 +- .../java/co/rsk/config/BridgeRegTestConstants.java | 2 +- .../java/co/rsk/config/BridgeTestNetConstants.java | 2 +- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 1 + rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java | 4 +--- .../main/java/co/rsk/peg/BridgeSupportFactory.java | 1 + .../java/co/rsk/peg/federation/ErpFederation.java | 1 - .../main/java/co/rsk/peg/federation/Federation.java | 1 - .../java/co/rsk/peg/federation/FederationFactory.java | 1 - .../rsk/peg/federation/FederationFormatVersion.java | 4 ++-- .../co/rsk/peg/{ => federation}/FederationMember.java | 2 +- .../rsk/peg/{ => federation}/FederationSupport.java | 4 ++-- .../java/co/rsk/peg/federation/PendingFederation.java | 1 - .../peg/federation/StandardMultisigFederation.java | 1 - .../java/co/rsk/remasc/RemascFederationProvider.java | 2 +- .../co/rsk/peg/BridgeSupportAddSignatureTest.java | 2 ++ .../java/co/rsk/peg/BridgeSupportFlyoverTest.java | 1 + .../peg/BridgeSupportProcessFundsMigrationTest.java | 1 + .../peg/BridgeSupportRegisterBtcTransactionTest.java | 1 + .../java/co/rsk/peg/BridgeSupportReleaseBtcTest.java | 1 + .../java/co/rsk/peg/BridgeSupportSigHashTest.java | 1 + rskj-core/src/test/java/co/rsk/peg/BridgeTest.java | 1 + .../test/java/co/rsk/peg/BridgeTestIntegration.java | 1 + .../test/java/co/rsk/peg/BridgeUtilsLegacyTest.java | 1 + rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java | 1 + .../co/rsk/peg/PegUtilsGetTransactionTypeTest.java | 1 + .../rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java | 1 + .../src/test/java/co/rsk/peg/PegUtilsLegacyTest.java | 4 +--- rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java | 1 + .../src/test/java/co/rsk/peg/PocSighashTest.java | 3 ++- .../peg/{ => federation}/FederationMemberTest.java | 4 +--- .../peg/{ => federation}/FederationSupportTest.java | 6 ++---- .../rsk/peg/{ => federation}/FederationTestUtils.java | 5 +---- .../NonStandardErpFederationsTest.java | 6 +----- .../peg/{ => federation}/P2shErpFederationTest.java | 6 +----- .../peg/{ => federation}/PendingFederationTest.java | 11 ++++------- .../StandardMultisigFederationTest.java | 5 +---- .../co/rsk/peg/performance/ActiveFederationTest.java | 2 +- .../co/rsk/peg/performance/FederationChangeTest.java | 1 + .../co/rsk/peg/utils/BridgeEventLoggerImplTest.java | 2 ++ .../peg/utils/BridgeEventLoggerLegacyImplTest.java | 2 ++ .../co/rsk/test/builders/BridgeSupportBuilder.java | 2 +- 43 files changed, 48 insertions(+), 56 deletions(-) rename rskj-core/src/main/java/co/rsk/peg/{ => federation}/FederationMember.java (99%) rename rskj-core/src/main/java/co/rsk/peg/{ => federation}/FederationSupport.java (99%) rename rskj-core/src/test/java/co/rsk/peg/{ => federation}/FederationMemberTest.java (98%) rename rskj-core/src/test/java/co/rsk/peg/{ => federation}/FederationSupportTest.java (98%) rename rskj-core/src/test/java/co/rsk/peg/{ => federation}/FederationTestUtils.java (98%) rename rskj-core/src/test/java/co/rsk/peg/{ => federation}/NonStandardErpFederationsTest.java (99%) rename rskj-core/src/test/java/co/rsk/peg/{ => federation}/P2shErpFederationTest.java (99%) rename rskj-core/src/test/java/co/rsk/peg/{ => federation}/PendingFederationTest.java (98%) rename rskj-core/src/test/java/co/rsk/peg/{ => federation}/StandardMultisigFederationTest.java (98%) diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java index 13a8a9616cb..e37cd07ddb0 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java @@ -22,7 +22,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; -import co.rsk.peg.FederationMember; +import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationFactory; import java.time.Instant; import java.util.Arrays; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java index 510358dd1e9..1ac54a62c82 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java @@ -4,7 +4,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; -import co.rsk.peg.FederationMember; +import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationFactory; import com.google.common.collect.Lists; import java.time.Instant; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java index d18c777e46c..c3381b45ea6 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java @@ -22,7 +22,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; -import co.rsk.peg.FederationMember; +import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationFactory; import java.nio.charset.StandardCharsets; import java.time.Instant; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java index 01761605f14..04b72e1a34f 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java @@ -22,7 +22,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; -import co.rsk.peg.FederationMember; +import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationFactory; import java.time.Instant; import java.util.Arrays; diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index fe8502bbb10..22ac4b197e8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -26,6 +26,7 @@ import co.rsk.panic.PanicProcessor; import co.rsk.peg.bitcoin.MerkleBranch; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationMember; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.utils.BtcTransactionFormatUtils; import co.rsk.peg.whitelist.LockWhitelistEntry; 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 27ae35ca9f8..0f2523b2aa0 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -64,9 +64,7 @@ import co.rsk.peg.bitcoin.RskAllowUnconfirmedCoinSelector; import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; -import co.rsk.peg.federation.ErpFederation; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.PendingFederation; +import co.rsk.peg.federation.*; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.pegin.PeginEvaluationResult; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java index dcc9b9b8235..52101072d0c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java @@ -22,6 +22,7 @@ import co.rsk.core.RskAddress; import co.rsk.peg.BtcBlockStoreWithCache.Factory; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; +import co.rsk.peg.federation.FederationSupport; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.peg.utils.BridgeEventLoggerImpl; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java index 800bfabed83..c3705088b65 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java @@ -7,7 +7,6 @@ import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.bitcoinj.script.ScriptChunk; -import co.rsk.peg.FederationMember; import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.RedeemScriptCreationException; import co.rsk.peg.utils.EcKeyUtils; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java index 8e46b67d775..9949bdfa928 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java @@ -23,7 +23,6 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; -import co.rsk.peg.FederationMember; import java.time.Instant; import java.time.temporal.ChronoUnit; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java index 15636706828..8d1760b3149 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java @@ -2,7 +2,6 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.peg.FederationMember; import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFormatVersion.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFormatVersion.java index 217014b30aa..43b942716b6 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFormatVersion.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFormatVersion.java @@ -7,8 +7,8 @@ public enum FederationFormatVersion { private int version; - FederationFormatVersion(int i) { - this.version = i; + FederationFormatVersion(int version) { + this.version = version; } public int getFormatVersion() { diff --git a/rskj-core/src/main/java/co/rsk/peg/FederationMember.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java similarity index 99% rename from rskj-core/src/main/java/co/rsk/peg/FederationMember.java rename to rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java index af06f4d951d..1e4e5f781ea 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FederationMember.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import com.google.common.primitives.UnsignedBytes; diff --git a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationSupport.java similarity index 99% rename from rskj-core/src/main/java/co/rsk/peg/FederationSupport.java rename to rskj-core/src/main/java/co/rsk/peg/federation/FederationSupport.java index 82f6fd85054..2afd4c88b16 100644 --- a/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationSupport.java @@ -15,12 +15,12 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.UTXO; import co.rsk.config.BridgeConstants; -import co.rsk.peg.federation.Federation; +import co.rsk.peg.BridgeStorageProvider; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.core.Block; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index f56ebd8d952..6a0f3e92d86 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -22,7 +22,6 @@ import co.rsk.config.BridgeConstants; import co.rsk.crypto.Keccak256; import co.rsk.peg.BridgeSerializationUtils; -import co.rsk.peg.FederationMember; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.crypto.HashUtil; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java index 0a1224291dd..8182684a5e9 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java @@ -21,7 +21,6 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; -import co.rsk.peg.FederationMember; import co.rsk.peg.bitcoin.ScriptValidations; import java.time.Instant; diff --git a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java index ae5c8fcc37b..6d8630d74cf 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java +++ b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java @@ -20,7 +20,7 @@ import co.rsk.config.BridgeConstants; import co.rsk.core.RskAddress; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.FederationSupport; +import co.rsk.peg.federation.FederationSupport; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.core.Block; import org.ethereum.core.Repository; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index 6c0769b0485..d73c761d66d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -7,6 +7,8 @@ import co.rsk.config.BridgeConstants; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationSupport; +import co.rsk.peg.federation.FederationTestUtils; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java index a640d8b5773..4ed1d67fdc7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java @@ -42,6 +42,7 @@ import co.rsk.peg.btcLockSender.BtcLockSender; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationSupport; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java index 7cd70836baa..a7c5a4ac571 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java @@ -9,6 +9,7 @@ import co.rsk.config.BridgeTestNetConstants; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.test.builders.BridgeSupportBuilder; import org.bouncycastle.util.encoders.Hex; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index fc46e8986be..f03332e42de 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -14,6 +14,7 @@ import co.rsk.peg.btcLockSender.BtcLockSenderProvider; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.pegin.RejectedPeginReason; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java index b961165acee..8e70a97bd41 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -27,6 +27,7 @@ import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.peg.utils.BridgeEventLoggerImpl; import co.rsk.peg.utils.RejectedPegoutReason; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java index a6217f9e782..16dc0f3abb8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java @@ -13,6 +13,7 @@ import co.rsk.peg.bitcoin.BitcoinUtils; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.test.builders.BridgeSupportBuilder; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 7305e52ee7b..f10717f5576 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -9,6 +9,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.Constants; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTestIntegration.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTestIntegration.java index 69422a6150c..384f8d354fb 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTestIntegration.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTestIntegration.java @@ -51,6 +51,7 @@ import java.util.function.BiFunction; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationMember; import co.rsk.test.builders.BlockChainBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.TestUtils; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java index 9df877deefc..ff0b3ca379e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java @@ -8,6 +8,7 @@ import java.util.List; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationMember; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; diff --git a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java index 8ac25eab272..6e030b97322 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java @@ -29,6 +29,7 @@ import co.rsk.peg.federation.ErpFederation; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.simples.SimpleRskTransaction; import org.bouncycastle.util.encoders.Hex; import org.ethereum.core.Transaction; diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java index 5e29272d8a7..fa2ee1f9ea2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsGetTransactionTypeTest.java @@ -29,6 +29,7 @@ import co.rsk.peg.bitcoin.BitcoinUtils; import co.rsk.peg.federation.ErpFederation; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.test.builders.BridgeSupportBuilder; import java.util.Arrays; import java.util.List; diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java index 5a549014113..5b62e08db08 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java @@ -10,6 +10,7 @@ import co.rsk.peg.federation.ErpFederation; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationTestUtils; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java index dfe71a74417..da1c77a3e98 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java @@ -9,9 +9,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; import co.rsk.peg.btcLockSender.BtcLockSender; -import co.rsk.peg.federation.ErpFederation; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.*; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; 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 0612e5f008d..008bc5cf84b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java @@ -13,6 +13,7 @@ import co.rsk.peg.federation.ErpFederation; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.test.builders.BridgeSupportBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; diff --git a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java index 210f5c887c1..cab9a9076b0 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java @@ -12,6 +12,7 @@ import co.rsk.peg.federation.ErpFederation; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationMember; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -31,7 +32,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static co.rsk.peg.FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR; +import static co.rsk.peg.federation.FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; diff --git a/rskj-core/src/test/java/co/rsk/peg/FederationMemberTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationMemberTest.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/FederationMemberTest.java rename to rskj-core/src/test/java/co/rsk/peg/federation/FederationMemberTest.java index bb2fb579398..4c1ecdd7abe 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FederationMemberTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationMemberTest.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import org.ethereum.crypto.ECKey; @@ -24,8 +24,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.util.Arrays; - class FederationMemberTest { private BtcECKey btcKey; private ECKey rskKey; diff --git a/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationSupportTest.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java rename to rskj-core/src/test/java/co/rsk/peg/federation/FederationSupportTest.java index 4346240ff15..58227c955a6 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationSupportTest.java @@ -15,17 +15,15 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; +import co.rsk.peg.BridgeStorageProvider; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.StandardMultisigFederation; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; diff --git a/rskj-core/src/test/java/co/rsk/peg/FederationTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationTestUtils.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/FederationTestUtils.java rename to rskj-core/src/test/java/co/rsk/peg/federation/FederationTestUtils.java index 059e1ec825a..243dacb3514 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FederationTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationTestUtils.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import static co.rsk.peg.PegTestUtils.createBaseInputScriptThatSpendsFromTheFederation; import static co.rsk.peg.ReleaseTransactionBuilder.BTC_TX_VERSION_2; @@ -36,9 +36,6 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import co.rsk.peg.federation.ErpFederation; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; import org.ethereum.crypto.ECKey; public class FederationTestUtils { diff --git a/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java similarity index 99% rename from rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java rename to rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java index f443f831ff1..c8fe0cbcb4a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.federation; import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; @@ -22,10 +22,6 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.peg.bitcoin.*; -import co.rsk.peg.federation.ErpFederation; -import co.rsk.peg.federation.ErpFederationCreationException; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.resources.TestConstants; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java similarity index 99% rename from rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java rename to rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java index 6680e6e9346..2a5ab0c02b1 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java @@ -1,4 +1,4 @@ -package co.rsk.peg; +package co.rsk.peg.federation; import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; @@ -6,7 +6,6 @@ import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_CSV_VALUE; import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.Mockito.mock; import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.*; @@ -28,13 +27,10 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import co.rsk.peg.federation.*; import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import org.bouncycastle.util.encoders.Hex; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java rename to rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java index 2cb0794cb3e..02b8390d097 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; @@ -24,10 +24,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.crypto.Keccak256; -import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; -import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; -import co.rsk.peg.federation.*; +import co.rsk.peg.BridgeSerializationUtils; import co.rsk.peg.resources.TestConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -39,12 +36,12 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; +import org.mockito.junit.jupiter.MockitoSettings; +import org.mockito.quality.Strictness; import java.math.BigInteger; import java.time.Instant; import java.util.List; -import org.mockito.junit.jupiter.MockitoSettings; -import org.mockito.quality.Strictness; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; diff --git a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java rename to rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java index b41fd8abaf5..b47dcb3d77d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; import static org.junit.jupiter.api.Assertions.*; @@ -36,9 +36,6 @@ import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.peg.bitcoin.ScriptCreationException; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.StandardMultisigFederation; import org.bouncycastle.util.encoders.Hex; import org.ethereum.TestUtils; import org.ethereum.crypto.ECKey; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java index 1669dc0527f..fa5c6135605 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java @@ -23,7 +23,7 @@ import co.rsk.peg.*; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.StandardMultisigFederation; +import co.rsk.peg.federation.FederationMember; import org.ethereum.TestUtils; import org.ethereum.core.CallTransaction; import org.ethereum.core.Repository; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java index 1d1abb206ba..ff444375388 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java @@ -22,6 +22,7 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.core.RskAddress; import co.rsk.peg.*; +import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.PendingFederation; import org.ethereum.core.Repository; import org.ethereum.crypto.ECKey; diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index f6fed8bb0c4..bf61c46ca02 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -26,6 +26,8 @@ import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.PegTestUtils; +import co.rsk.peg.federation.FederationMember; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.pegin.RejectedPeginReason; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java index 7b64743c592..9d138a9d607 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java @@ -27,6 +27,8 @@ import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.PegTestUtils; +import co.rsk.peg.federation.FederationMember; +import co.rsk.peg.federation.FederationTestUtils; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; diff --git a/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java index 0bc09cb56a7..13ed4bbbe14 100644 --- a/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java +++ b/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java @@ -7,7 +7,7 @@ import co.rsk.peg.BridgeStorageProvider; import co.rsk.peg.BridgeSupport; import co.rsk.peg.BtcBlockStoreWithCache.Factory; -import co.rsk.peg.FederationSupport; +import co.rsk.peg.federation.FederationSupport; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; From cadc0f1868810c0802acc4896ab08eee81d728da Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 7 Dec 2023 11:00:16 -0300 Subject: [PATCH 037/137] Move FederationSupport and PendingFederation outside federation package to avoid circular dependency with peg package --- .../co/rsk/peg/BridgeStorageProvider.java | 1 - .../java/co/rsk/peg/BridgeSupportFactory.java | 1 - .../{federation => }/FederationSupport.java | 5 +- .../{federation => }/PendingFederation.java | 6 +- .../rsk/peg/federation/FederationMember.java | 86 +++++++++---------- .../rsk/remasc/RemascFederationProvider.java | 2 +- .../peg/BridgeSupportAddSignatureTest.java | 1 - .../co/rsk/peg/BridgeSupportFlyoverTest.java | 1 - .../FederationSupportTest.java | 7 +- .../PendingFederationTest.java | 7 +- .../NonStandardErpFederationsTest.java | 25 ++++++ .../peg/federation/P2shErpFederationTest.java | 25 ++++++ .../peg/performance/FederationChangeTest.java | 2 +- .../performance/PendingFederationTest.java | 2 +- .../test/builders/BridgeSupportBuilder.java | 2 +- 15 files changed, 114 insertions(+), 59 deletions(-) rename rskj-core/src/main/java/co/rsk/peg/{federation => }/FederationSupport.java (98%) rename rskj-core/src/main/java/co/rsk/peg/{federation => }/PendingFederation.java (97%) rename rskj-core/src/test/java/co/rsk/peg/{federation => }/FederationSupportTest.java (98%) rename rskj-core/src/test/java/co/rsk/peg/{federation => }/PendingFederationTest.java (98%) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 5a8c8e23ce3..76e7e1da4f6 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -25,7 +25,6 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.CoinbaseInformation; import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.PendingFederation; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.whitelist.LockWhitelist; import co.rsk.peg.whitelist.LockWhitelistEntry; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java index 52101072d0c..dcc9b9b8235 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java @@ -22,7 +22,6 @@ import co.rsk.core.RskAddress; import co.rsk.peg.BtcBlockStoreWithCache.Factory; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; -import co.rsk.peg.federation.FederationSupport; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.peg.utils.BridgeEventLoggerImpl; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationSupport.java b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java similarity index 98% rename from rskj-core/src/main/java/co/rsk/peg/federation/FederationSupport.java rename to rskj-core/src/main/java/co/rsk/peg/FederationSupport.java index 2afd4c88b16..0aa9ed223a0 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/FederationSupport.java @@ -15,12 +15,13 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ -package co.rsk.peg.federation; +package co.rsk.peg; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.UTXO; import co.rsk.config.BridgeConstants; -import co.rsk.peg.BridgeStorageProvider; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationMember; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.core.Block; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java similarity index 97% rename from rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java rename to rskj-core/src/main/java/co/rsk/peg/PendingFederation.java index 6a0f3e92d86..b368cb3aeb9 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java @@ -16,12 +16,14 @@ * along with this program. If not, see . */ -package co.rsk.peg.federation; +package co.rsk.peg; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.config.BridgeConstants; import co.rsk.crypto.Keccak256; -import co.rsk.peg.BridgeSerializationUtils; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationMember; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.crypto.HashUtil; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java index 1e4e5f781ea..30b62fb9ebc 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java @@ -38,10 +38,53 @@ * @author Ariel Mendelzon */ public final class FederationMember { + /** + * Compares federation members based on their underlying keys. + * + * The total ordering is defined such that, for any two members M1, M2, + * 1) M1 < M2 iff BTC_PUB_KEY(M1) M2 otherwise + * + * where BTC_RSK_MST_PUBKEYS_COMPARATOR = new Comparator() { + private Comparator comparator = UnsignedBytes.lexicographicalComparator(); + + @Override + public int compare(FederationMember m1, FederationMember m2) { + int btcKeysComparison = comparator.compare(m1.getBtcPublicKey().getPubKey(), m2.getBtcPublicKey().getPubKey()); + if (btcKeysComparison == 0) { + int rskKeysComparison = comparator.compare(m1.getRskPublicKey().getPubKey(), m2.getRskPublicKey().getPubKey()); + if (rskKeysComparison == 0) { + return comparator.compare(m1.getMstPublicKey().getPubKey(), m2.getMstPublicKey().getPubKey()); + } + return rskKeysComparison; + } + return btcKeysComparison; + } + }; + private final BtcECKey btcPublicKey; private final ECKey rskPublicKey; private final ECKey mstPublicKey; + public FederationMember(BtcECKey btcPublicKey, ECKey rskPublicKey, ECKey mstPublicKey) { + // Copy public keys to ensure effective immutability + // Make sure we always use compressed versions of public keys + this.btcPublicKey = BtcECKey.fromPublicOnly(btcPublicKey.getPubKeyPoint().getEncoded(true)); + this.rskPublicKey = ECKey.fromPublicOnly(rskPublicKey.getPubKey(true)); + this.mstPublicKey = ECKey.fromPublicOnly(mstPublicKey.getPubKey(true)); + } + public enum KeyType { BTC("btc"), RSK("rsk"), @@ -83,49 +126,6 @@ public static List getFederationMembersFromKeys(List return pks.stream().map(pk -> getFederationMemberFromKey(pk)).collect(Collectors.toList()); } - /** - * Compares federation members based on their underlying keys. - * - * The total ordering is defined such that, for any two members M1, M2, - * 1) M1 < M2 iff BTC_PUB_KEY(M1) M2 otherwise - * - * where BTC_RSK_MST_PUBKEYS_COMPARATOR = new Comparator() { - private Comparator comparator = UnsignedBytes.lexicographicalComparator(); - - @Override - public int compare(FederationMember m1, FederationMember m2) { - int btcKeysComparison = comparator.compare(m1.getBtcPublicKey().getPubKey(), m2.getBtcPublicKey().getPubKey()); - if (btcKeysComparison == 0) { - int rskKeysComparison = comparator.compare(m1.getRskPublicKey().getPubKey(), m2.getRskPublicKey().getPubKey()); - if (rskKeysComparison == 0) { - return comparator.compare(m1.getMstPublicKey().getPubKey(), m2.getMstPublicKey().getPubKey()); - } - return rskKeysComparison; - } - return btcKeysComparison; - } - }; - - public FederationMember(BtcECKey btcPublicKey, ECKey rskPublicKey, ECKey mstPublicKey) { - // Copy public keys to ensure effective immutability - // Make sure we always use compressed versions of public keys - this.btcPublicKey = BtcECKey.fromPublicOnly(btcPublicKey.getPubKeyPoint().getEncoded(true)); - this.rskPublicKey = ECKey.fromPublicOnly(rskPublicKey.getPubKey(true)); - this.mstPublicKey = ECKey.fromPublicOnly(mstPublicKey.getPubKey(true)); - } - public BtcECKey getBtcPublicKey() { // Return a copy return BtcECKey.fromPublicOnly(btcPublicKey.getPubKey()); diff --git a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java index 6d8630d74cf..ae5c8fcc37b 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java +++ b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java @@ -20,7 +20,7 @@ import co.rsk.config.BridgeConstants; import co.rsk.core.RskAddress; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.federation.FederationSupport; +import co.rsk.peg.FederationSupport; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.core.Block; import org.ethereum.core.Repository; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index d73c761d66d..58d3a847f45 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -7,7 +7,6 @@ import co.rsk.config.BridgeConstants; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationSupport; import co.rsk.peg.federation.FederationTestUtils; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java index 4ed1d67fdc7..a640d8b5773 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportFlyoverTest.java @@ -42,7 +42,6 @@ import co.rsk.peg.btcLockSender.BtcLockSender; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationSupport; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationSupportTest.java b/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/federation/FederationSupportTest.java rename to rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java index 58227c955a6..fb212ffd17b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java @@ -15,15 +15,18 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ -package co.rsk.peg.federation; +package co.rsk.peg; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; -import co.rsk.peg.BridgeStorageProvider; import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationMember; +import co.rsk.peg.federation.FederationTestUtils; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java similarity index 98% rename from rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java rename to rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index 02b8390d097..0cb9e4da7bc 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package co.rsk.peg.federation; +package co.rsk.peg; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; @@ -24,7 +24,10 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.crypto.Keccak256; -import co.rsk.peg.BridgeSerializationUtils; +import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationMember; +import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.resources.TestConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java index c8fe0cbcb4a..a2996632637 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java @@ -138,6 +138,31 @@ void createFederation_withOneErpKey_valid() { activationDelayValue)); } + @ParameterizedTest + @ValueSource(ints = {-100, 0}) + void createFederation_withInvalidThresholdValues_throwsIllegalArgumentException(int threshold) { + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); + assertThrows(IllegalArgumentException.class, + () -> builder.createRedeemScriptFromKeys( + defaultKeys, threshold, + emergencyKeys, emergencyThreshold, + activationDelayValue) + ); + } + + @Test + void createFederation_withThresholdAboveDefaultKeysSize_throwsIllegalArgumentException() { + int defaultThresholdAboveDefaultKeysSize = defaultKeys.size() + 1; + + ErpRedeemScriptBuilder builder = new NonStandardErpRedeemScriptBuilder(); + assertThrows(IllegalArgumentException.class, + () -> builder.createRedeemScriptFromKeys( + defaultKeys, defaultThresholdAboveDefaultKeysSize, + emergencyKeys, emergencyThreshold, + activationDelayValue) + ); + } + @ParameterizedTest @ValueSource(longs = { 130L, 500L, 33_000L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE}) void createFederation_postRSKIP293_withValidCsvValues_valid(long csvValue) { diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java index 2a5ab0c02b1..ddebc7fc07e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java @@ -129,6 +129,31 @@ void createFederation_withOneErpKey_valid() { createAndValidateFederation(); } + @ParameterizedTest + @ValueSource(ints = {-100, 0}) + void createFederation_withInvalidThresholdValues_throwsIllegalArgumentException(int threshold) { + ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + assertThrows(IllegalArgumentException.class, + () -> builder.createRedeemScriptFromKeys( + defaultKeys, threshold, + emergencyKeys, emergencyThreshold, + activationDelayValue) + ); + } + + @Test + void createFederation_withThresholdAboveDefaultKeysSize_throwsIllegalArgumentException() { + int defaultThresholdAboveDefaultKeysSize = defaultKeys.size() + 1; + + ErpRedeemScriptBuilder builder = new P2shErpRedeemScriptBuilder(); + assertThrows(IllegalArgumentException.class, + () -> builder.createRedeemScriptFromKeys( + defaultKeys, defaultThresholdAboveDefaultKeysSize, + emergencyKeys, emergencyThreshold, + activationDelayValue) + ); + } + @ParameterizedTest @ValueSource(longs = {20L, 130L, 500L, 33_000L, ErpRedeemScriptBuilderUtils.MAX_CSV_VALUE}) void createFederation_withValidCsvValues_valid(long csvValue) { diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java index ff444375388..cc674d670bc 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java @@ -23,7 +23,7 @@ import co.rsk.core.RskAddress; import co.rsk.peg.*; import co.rsk.peg.federation.FederationMember; -import co.rsk.peg.federation.PendingFederation; +import co.rsk.peg.PendingFederation; import org.ethereum.core.Repository; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java index 94b53c3e681..0d5c580939c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java @@ -21,7 +21,7 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.peg.Bridge; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.federation.PendingFederation; +import co.rsk.peg.PendingFederation; import org.ethereum.core.CallTransaction; import org.ethereum.core.Repository; import org.ethereum.vm.exception.VMException; diff --git a/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java index 13ed4bbbe14..0bc09cb56a7 100644 --- a/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java +++ b/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java @@ -7,7 +7,7 @@ import co.rsk.peg.BridgeStorageProvider; import co.rsk.peg.BridgeSupport; import co.rsk.peg.BtcBlockStoreWithCache.Factory; -import co.rsk.peg.federation.FederationSupport; +import co.rsk.peg.FederationSupport; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; From 7a68d0b887698f0ae359769348e04d0d1a11a273 Mon Sep 17 00:00:00 2001 From: julia zack Date: Tue, 12 Dec 2023 16:58:53 -0300 Subject: [PATCH 038/137] Refactor activation of consensus rules to use ActivationConfigsForTest --- .../co/rsk/peg/BridgeStorageProviderTest.java | 42 +--- .../peg/federation/FederationFactoryTest.java | 206 ++++++++++++++++++ .../NonStandardErpFederationsTest.java | 1 - 3 files changed, 216 insertions(+), 33 deletions(-) create mode 100644 rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index ab03fb34ef1..c02f9749e2f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -88,7 +88,6 @@ class BridgeStorageProviderTest { private final TestSystemProperties config = new TestSystemProperties(); private final ActivationConfig.ForBlock activationsBeforeFork = ActivationConfigsForTest.genesis().forBlock(0L); private final ActivationConfig.ForBlock activationsAllForks = ActivationConfigsForTest.all().forBlock(0); - private final ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); private final BridgeTestNetConstants bridgeTestnetInstance = BridgeTestNetConstants.getInstance(); private final NetworkParameters networkParameters = bridgeTestnetInstance.getBtcParams(); @@ -406,7 +405,7 @@ void getNewFederation_multiKeyVersion() { void getNewFederation_erp_fed() { BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); - when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( newFederation.getMembers(), @@ -535,8 +534,7 @@ void saveNewFederation_preMultikey() { @Test void saveNewFederation_postMultiKey() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + ActivationConfig.ForBlock activations = ActivationConfigsForTest.papyrus200().forBlock(0); Federation newFederation = buildMockFederation(100, 200, 300); testSaveNewFederationPostMultiKey(newFederation, STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION, activations); @@ -544,9 +542,7 @@ void saveNewFederation_postMultiKey() { @Test void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); @@ -566,10 +562,6 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { @Test void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(true); - BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); @@ -582,7 +574,7 @@ void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { bridgeConstants.getErpFedActivationDelay() ); - testSaveNewFederationPostMultiKey(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activations); + testSaveNewFederationPostMultiKey(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activationsAllForks); } @Test @@ -683,13 +675,11 @@ void getOldFederation_multiKeyVersion() { } @Test - void getOldFederation_nonStandardHardcoaded_fed() { + void getOldFederation_nonStandardHardcoded_fed() { BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( oldFederation.getMembers(), @@ -709,10 +699,8 @@ void getOldFederation_nonStandardWithUnsignedBE_fed() { BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + List rulesToDisable = Arrays.asList(ConsensusRule.RSKIP293); + ActivationConfig.ForBlock activations = ActivationConfigsForTest.hop400(rulesToDisable).forBlock(0); ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( oldFederation.getMembers(), @@ -732,11 +720,7 @@ void getOldFederation_nonStandard_fed() { BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + ActivationConfig.ForBlock activations = ActivationConfigsForTest.hop400().forBlock(0); ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( oldFederation.getMembers(), @@ -894,12 +878,6 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { @Test void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(true); BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); @@ -912,7 +890,7 @@ void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { bridgeConstants.getErpFedActivationDelay() ); - testSaveOldFederation(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activations); + testSaveOldFederation(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activationsAllForks); } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java new file mode 100644 index 00000000000..94009852beb --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java @@ -0,0 +1,206 @@ +package co.rsk.peg.federation; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.config.BridgeConstants; +import co.rsk.config.BridgeMainNetConstants; +import co.rsk.config.BridgeTestNetConstants; +import org.bouncycastle.util.encoders.Hex; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; + +import java.time.Instant; +import java.time.ZonedDateTime; +import java.util.Arrays; +import java.util.List; + +import static co.rsk.peg.federation.FederationFormatVersion.*; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class FederationFactoryTest { + private BridgeConstants bridgeConstants; + private NetworkParameters networkParameters; + private List federationMembers; + private List defaultKeys; + private Instant creationTime; + private long creationBlockNumber; + private List emergencyKeys; + private long activationDelayValue; + private ActivationConfig.ForBlock activations; + + @BeforeEach + void setUp() { + BtcECKey federator0PublicKey = BtcECKey.fromPublicOnly(Hex.decode("03b53899c390573471ba30e5054f78376c5f797fda26dde7a760789f02908cbad2")); + BtcECKey federator1PublicKey = BtcECKey.fromPublicOnly(Hex.decode("027319afb15481dbeb3c426bcc37f9a30e7f51ceff586936d85548d9395bcc2344")); + BtcECKey federator2PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0355a2e9bf100c00fc0a214afd1bf272647c7824eb9cb055480962f0c382596a70")); + BtcECKey federator3PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02566d5ded7c7db1aa7ee4ef6f76989fb42527fcfdcddcd447d6793b7d869e46f7")); + BtcECKey federator4PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0294c817150f78607566e961b3c71df53a22022a80acbb982f83c0c8baac040adc")); + BtcECKey federator5PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0372cd46831f3b6afd4c044d160b7667e8ebf659d6cb51a825a3104df6ee0638c6")); + BtcECKey federator6PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0340df69f28d69eef60845da7d81ff60a9060d4da35c767f017b0dd4e20448fb44")); + BtcECKey federator7PublicKey = BtcECKey.fromPublicOnly(Hex.decode("02ac1901b6fba2c1dbd47d894d2bd76c8ba1d296d65f6ab47f1c6b22afb53e73eb")); + BtcECKey federator8PublicKey = BtcECKey.fromPublicOnly(Hex.decode("031aabbeb9b27258f98c2bf21f36677ae7bae09eb2d8c958ef41a20a6e88626d26")); + BtcECKey federator9PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea")); + defaultKeys = Arrays.asList( + federator0PublicKey, federator1PublicKey, federator2PublicKey, + federator3PublicKey, federator4PublicKey, federator5PublicKey, + federator6PublicKey, federator7PublicKey, federator8PublicKey, + federator9PublicKey + ); + federationMembers = FederationTestUtils.getFederationMembersWithKeys(defaultKeys); + creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); + creationBlockNumber = 0L; + bridgeConstants = BridgeMainNetConstants.getInstance(); + networkParameters = bridgeConstants.getBtcParams(); + } + + @Test + void buildStandardMultiSigFederation() { + Federation federation = createStandardMultisigFederation(); + int version = federation.getFormatVersion(); + + assertEquals(STANDARD_MULTISIG_FEDERATION.getFormatVersion(), version); + } + + @Nested + @Tag("erpFeds") + class ErpFederationTests { + @BeforeEach + @Tag("erpFeds") + void setUp() { + emergencyKeys = bridgeConstants.getErpFedPubKeysList(); + activationDelayValue = bridgeConstants.getErpFedActivationDelay(); + activations = mock(ActivationConfig.ForBlock.class); + } + + @Test + void differentBuilderMethods_return_differentFederations(){ + Federation federationStandard = createStandardMultisigFederation(); + ErpFederation federationNonStandard = createNonStandardErpFederation(); + ErpFederation federationP2sh = createP2shErpFederation(); + + assertNotEquals(federationStandard.getFormatVersion(), federationNonStandard.getFormatVersion()); + assertNotEquals(federationStandard.getFormatVersion(), federationP2sh.getFormatVersion()); + assertNotEquals(federationNonStandard.getFormatVersion(), federationP2sh.getFormatVersion()); + } + + @Test + void differentNonStandardErpFederations_areNotEqualFeds_butHaveSameNonStandardFedFormat_testnet() { + bridgeConstants = BridgeTestNetConstants.getInstance(); + networkParameters = bridgeConstants.getBtcParams(); + + int version; + + // in testnet it should build non standard hardcoded fed + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + ErpFederation federationPostRSKIP201 = createNonStandardErpFederation(); + version = federationPostRSKIP201.getFormatVersion(); + + assertEquals(NON_STANDARD_ERP_FEDERATION.getFormatVersion(), version); + + // build non standard fed with csv unsigned big endian + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + ErpFederation federationPostRSKIP284 = createNonStandardErpFederation(); + version = federationPostRSKIP284.getFormatVersion(); + + assertEquals(NON_STANDARD_ERP_FEDERATION.getFormatVersion(), version); + assertNotEquals(federationPostRSKIP201, federationPostRSKIP284); + + // build non standard fed + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + ErpFederation federationPostRSKIP293 = createNonStandardErpFederation(); + version = federationPostRSKIP293.getFormatVersion(); + + assertEquals(NON_STANDARD_ERP_FEDERATION.getFormatVersion(), version); + assertNotEquals(federationPostRSKIP201, federationPostRSKIP293); + assertNotEquals(federationPostRSKIP284, federationPostRSKIP293); + } + + @Test + void differentNonStandardErpFederations_areNotEqualFeds_butHaveSameNonStandardFedFormat_mainnet() { + int version; + + // in mainnet it should build non standard fed with csv unsigned big endian + when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); + ErpFederation federationPostRSKIP201 = createNonStandardErpFederation(); + version = federationPostRSKIP201.getFormatVersion(); + + assertEquals(NON_STANDARD_ERP_FEDERATION.getFormatVersion(), version); + + // should build non standard fed with csv unsigned big endian + when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); + ErpFederation federationPostRSKIP284 = createNonStandardErpFederation(); + version = federationPostRSKIP284.getFormatVersion(); + + assertEquals(NON_STANDARD_ERP_FEDERATION.getFormatVersion(), version); + assertEquals(federationPostRSKIP201, federationPostRSKIP284); + + // build non standard fed + when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + ErpFederation federationPostRSKIP293 = createNonStandardErpFederation(); + version = federationPostRSKIP293.getFormatVersion(); + + assertEquals(NON_STANDARD_ERP_FEDERATION.getFormatVersion(), version); + assertNotEquals(federationPostRSKIP201, federationPostRSKIP293); + assertNotEquals(federationPostRSKIP284, federationPostRSKIP293); + } + + @Test + void p2shErpFederation_haveP2shFedFormat() { + ErpFederation federation; + int version; + + // mainnet + federation = createP2shErpFederation(); + version = federation.getFormatVersion(); + assertEquals(P2SH_ERP_FEDERATION.getFormatVersion(), version); + + // testnet + bridgeConstants = BridgeTestNetConstants.getInstance(); + networkParameters = bridgeConstants.getBtcParams(); + federation = createP2shErpFederation(); + version = federation.getFormatVersion(); + assertEquals(P2SH_ERP_FEDERATION.getFormatVersion(), version); + } + + } + + private Federation createStandardMultisigFederation() { + return FederationFactory.buildStandardMultiSigFederation( + federationMembers, + creationTime, + creationBlockNumber, + networkParameters + ); + } + + private ErpFederation createNonStandardErpFederation() { + return FederationFactory.buildNonStandardErpFederation( + federationMembers, + creationTime, + creationBlockNumber, + networkParameters, + emergencyKeys, + activationDelayValue, + activations + ); + } + + private ErpFederation createP2shErpFederation() { + return FederationFactory.buildP2shErpFederation( + federationMembers, + creationTime, + creationBlockNumber, + networkParameters, + emergencyKeys, + activationDelayValue + ); + } + +} diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java index a2996632637..1d7c92f6355 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java @@ -58,7 +58,6 @@ class NonStandardErpFederationsTest { private int emergencyThreshold; private long activationDelayValue; private ActivationConfig.ForBlock activations; - private ErpRedeemScriptBuilder erpRedeemScriptBuilder; @BeforeEach void setup() { From 31482312f1345ccc16ae93bce76e07a0923b3a54 Mon Sep 17 00:00:00 2001 From: julia zack Date: Tue, 12 Dec 2023 12:05:08 -0300 Subject: [PATCH 039/137] Move BTC_RSK_MST_PUBKEYS_COMPARATOR from FederationMember to its own file --- .../rsk/peg/federation/FederationMember.java | 40 +------------------ .../FederationMemberPubKeysComparator.java | 40 +++++++++++++++++++ 2 files changed, 42 insertions(+), 38 deletions(-) create mode 100644 rskj-core/src/main/java/co/rsk/peg/federation/FederationMemberPubKeysComparator.java diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java index 30b62fb9ebc..ecb3a5e82d6 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java @@ -19,12 +19,10 @@ package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; -import com.google.common.primitives.UnsignedBytes; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; import java.util.Arrays; -import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; @@ -38,41 +36,7 @@ * @author Ariel Mendelzon */ public final class FederationMember { - /** - * Compares federation members based on their underlying keys. - * - * The total ordering is defined such that, for any two members M1, M2, - * 1) M1 < M2 iff BTC_PUB_KEY(M1) M2 otherwise - * - * where BTC_RSK_MST_PUBKEYS_COMPARATOR = new Comparator() { - private Comparator comparator = UnsignedBytes.lexicographicalComparator(); - - @Override - public int compare(FederationMember m1, FederationMember m2) { - int btcKeysComparison = comparator.compare(m1.getBtcPublicKey().getPubKey(), m2.getBtcPublicKey().getPubKey()); - if (btcKeysComparison == 0) { - int rskKeysComparison = comparator.compare(m1.getRskPublicKey().getPubKey(), m2.getRskPublicKey().getPubKey()); - if (rskKeysComparison == 0) { - return comparator.compare(m1.getMstPublicKey().getPubKey(), m2.getMstPublicKey().getPubKey()); - } - return rskKeysComparison; - } - return btcKeysComparison; - } - }; - + public static final FederationMemberPubKeysComparator BTC_RSK_MST_PUBKEYS_COMPARATOR = new FederationMemberPubKeysComparator(); private final BtcECKey btcPublicKey; private final ECKey rskPublicKey; private final ECKey mstPublicKey; @@ -123,7 +87,7 @@ public static FederationMember getFederationMemberFromKey(BtcECKey pk) { } public static List getFederationMembersFromKeys(List pks) { - return pks.stream().map(pk -> getFederationMemberFromKey(pk)).collect(Collectors.toList()); + return pks.stream().map(FederationMember::getFederationMemberFromKey).collect(Collectors.toList()); } public BtcECKey getBtcPublicKey() { diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMemberPubKeysComparator.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMemberPubKeysComparator.java new file mode 100644 index 00000000000..7dc866dabf8 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMemberPubKeysComparator.java @@ -0,0 +1,40 @@ +package co.rsk.peg.federation; + +import com.google.common.primitives.UnsignedBytes; + +import java.util.Comparator; + +public class FederationMemberPubKeysComparator implements Comparator { + /** + * Compares federation members based on their underlying keys. + * + * The total ordering is defined such that, for any two members M1, M2, + * 1) M1 < M2 iff BTC_PUB_KEY(M1) M2 otherwise + * + * where comparator = UnsignedBytes.lexicographicalComparator(); + + @Override + public int compare(FederationMember fed1, FederationMember fed2) { + int btcKeysComparison = comparator.compare(fed1.getBtcPublicKey().getPubKey(), fed2.getBtcPublicKey().getPubKey()); + if (btcKeysComparison == 0) { + int rskKeysComparison = comparator.compare(fed1.getRskPublicKey().getPubKey(), fed2.getRskPublicKey().getPubKey()); + if (rskKeysComparison == 0) { + return comparator.compare(fed1.getMstPublicKey().getPubKey(), fed2.getMstPublicKey().getPubKey()); + } + return rskKeysComparison; + } + return btcKeysComparison; + } +} From 6d6711a78e01db287e4a9e3a7e7366248a4d97c6 Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 21 Dec 2023 16:47:55 -0300 Subject: [PATCH 040/137] Move pending federation serializer behaviour to PendingFederation class so it can be moved into federation package. Move PendingFederation class into federation package --- .../co/rsk/peg/BridgeSerializationUtils.java | 36 ---- .../co/rsk/peg/BridgeStorageProvider.java | 52 ++++-- .../rsk/peg/federation/FederationMember.java | 15 ++ .../{ => federation}/PendingFederation.java | 45 ++++- .../rsk/peg/BridgeSerializationUtilsTest.java | 6 +- .../co/rsk/peg/BridgeStorageProviderTest.java | 159 ++++++++---------- .../co/rsk/peg/PendingFederationTest.java | 19 +-- .../peg/performance/FederationChangeTest.java | 2 +- .../performance/PendingFederationTest.java | 2 +- 9 files changed, 173 insertions(+), 163 deletions(-) rename rskj-core/src/main/java/co/rsk/peg/{ => federation}/PendingFederation.java (79%) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 85f6d118a34..45ff8f54847 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -393,17 +393,6 @@ private static FederationMember deserializeFederationMember(byte[] data) { return new FederationMember(btcKey, rskKey, mstKey); } - /** - * A pending federation is serialized as the - * public keys conforming it. - * This is a legacy format for blocks before the Wasabi - * network upgrade. - * See BridgeSerializationUtils::serializeBtcPublicKeys - */ - public static byte[] serializePendingFederationOnlyBtcKeys(PendingFederation pendingFederation) { - return serializeBtcPublicKeys(pendingFederation.getBtcPublicKeys()); - } - // For the serialization format, see BridgeSerializationUtils::serializePendingFederationOnlyBtcKeys // and serializePublicKeys::deserializeBtcPublicKeys public static PendingFederation deserializePendingFederationOnlyBtcKeys(byte[] data) { @@ -415,19 +404,6 @@ public static PendingFederation deserializePendingFederationOnlyBtcKeys(byte[] d return new PendingFederation(members); } - /** - * A pending federation is serialized as the - * list of its sorted members serialized. - * For the member serialization format, see BridgeSerializationUtils::serializeFederationMember - */ - public static byte[] serializePendingFederation(PendingFederation pendingFederation) { - List encodedMembers = pendingFederation.getMembers().stream() - .sorted(FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR) - .map(BridgeSerializationUtils::serializeFederationMember) - .collect(Collectors.toList()); - return RLP.encodeList(encodedMembers.toArray(new byte[0][])); - } - // For the serialization format, see BridgeSerializationUtils::serializePendingFederation public static PendingFederation deserializePendingFederation(byte[] data) { RLPList rlpList = (RLPList)RLP.decode2(data).get(0); @@ -891,18 +867,6 @@ private static ABICallSpec deserializeABICallSpec(byte[] data) { return new ABICallSpec(function, arguments); } - // A list of btc public keys is serialized as - // [pubkey1, pubkey2, ..., pubkeyn], sorted - // using the lexicographical order of the public keys - // (see BtcECKey.PUBKEY_COMPARATOR). - private static byte[] serializeBtcPublicKeys(List keys) { - List encodedKeys = keys.stream() - .sorted(BtcECKey.PUBKEY_COMPARATOR) - .map(key -> RLP.encodeElement(key.getPubKey())) - .collect(Collectors.toList()); - return RLP.encodeList(encodedKeys.toArray(new byte[0][])); - } - // For the serialization format, see BridgeSerializationUtils::serializePublicKeys private static List deserializeBtcPublicKeys(byte[] data) { RLPList rlpList = (RLPList)RLP.decode2(data).get(0); diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 76e7e1da4f6..24a6bdd468c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -25,6 +25,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.CoinbaseInformation; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.PendingFederation; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.whitelist.LockWhitelist; import co.rsk.peg.whitelist.LockWhitelistEntry; @@ -460,21 +461,43 @@ public void setPendingFederation(PendingFederation federation) { /** * Save the pending federation */ - public void savePendingFederation() { + public void savePendingFederation() throws IOException { if (shouldSavePendingFederation) { - RepositorySerializer serializer = BridgeSerializationUtils::serializePendingFederationOnlyBtcKeys; - if (activations.isActive(RSKIP123)) { - // we only need to save the standard part of the fed since the emergency part is constant - saveStorageVersion( - PENDING_FEDERATION_FORMAT_VERSION.getKey(), - STANDARD_MULTISIG_FEDERATION.getFormatVersion() - ); - serializer = BridgeSerializationUtils::serializePendingFederation; + savePendingFederation(pendingFederation); + } + else { + savePendingFederationOnlyBtcKeys(pendingFederation); } + } + } - safeSaveToRepository(PENDING_FEDERATION_KEY, pendingFederation, serializer); + /** + * Save the pending federation before RSKIP123 + */ + private void savePendingFederationOnlyBtcKeys(PendingFederation pendingFederation) throws IOException { + byte[] fedSerialized = null; + if (pendingFederation != null) { + fedSerialized = pendingFederation.serializeOnlyBtcKeys(); } + savePendingFederationToRepository(fedSerialized); + } + + /** + * Save the pending federation + */ + private void savePendingFederation(PendingFederation pendingFederation) throws IOException { + // we only need to save the standard part of the fed since the emergency part is constant + saveStorageVersion( + PENDING_FEDERATION_FORMAT_VERSION.getKey(), + STANDARD_MULTISIG_FEDERATION.getFormatVersion() + ); + + byte[] fedSerialized = null; + if (pendingFederation != null) { + fedSerialized = pendingFederation.serialize(); + } + savePendingFederationToRepository(fedSerialized); } /** @@ -1137,6 +1160,15 @@ private void saveToRepository(DataWord addressKey, T object, RepositorySeria repository.addStorageBytes(contractAddress, addressKey, data); } + private void savePendingFederationToRepository(byte[] federationSerialized) throws IOException { + try { + DataWord pendingFederationKey = PENDING_FEDERATION_KEY.getKey(); + repository.addStorageBytes(contractAddress, pendingFederationKey, federationSerialized); + } catch (RuntimeException e) { + throw new IOException("Unable to save to repository: " + Arrays.toString(federationSerialized), e); + } + } + private interface RepositoryDeserializer { T deserialize(byte[] data) throws IOException; } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java index ecb3a5e82d6..551c7c15fd7 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java @@ -21,6 +21,7 @@ import co.rsk.bitcoinj.core.BtcECKey; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; +import org.ethereum.util.RLP; import java.util.Arrays; import java.util.List; @@ -37,6 +38,10 @@ */ public final class FederationMember { public static final FederationMemberPubKeysComparator BTC_RSK_MST_PUBKEYS_COMPARATOR = new FederationMemberPubKeysComparator(); + private static final int FEDERATION_MEMBER_LIST_SIZE = 3; + private static final int FEDERATION_MEMBER_BTC_KEY_INDEX = 0; + private static final int FEDERATION_MEMBER_RSK_KEY_INDEX = 1; + private static final int FEDERATION_MEMBER_MST_KEY_INDEX = 2; private final BtcECKey btcPublicKey; private final ECKey rskPublicKey; private final ECKey mstPublicKey; @@ -154,4 +159,14 @@ public int hashCode() { mstPublicKey ); } + + public byte[] serialize() { + byte[][] rlpElements = new byte[FEDERATION_MEMBER_LIST_SIZE][]; + rlpElements[FEDERATION_MEMBER_BTC_KEY_INDEX] = RLP.encodeElement( + this.getBtcPublicKey().getPubKeyPoint().getEncoded(true) + ); + rlpElements[FEDERATION_MEMBER_RSK_KEY_INDEX] = RLP.encodeElement(this.getRskPublicKey().getPubKey(true)); + rlpElements[FEDERATION_MEMBER_MST_KEY_INDEX] = RLP.encodeElement(this.getMstPublicKey().getPubKey(true)); + return RLP.encodeList(rlpElements); + } } diff --git a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java similarity index 79% rename from rskj-core/src/main/java/co/rsk/peg/PendingFederation.java rename to rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index b368cb3aeb9..17b3b683a5a 100644 --- a/rskj-core/src/main/java/co/rsk/peg/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -16,14 +16,11 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.config.BridgeConstants; import co.rsk.crypto.Keccak256; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationMember; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.crypto.HashUtil; @@ -34,6 +31,7 @@ import java.util.List; import java.util.Objects; import java.util.stream.Collectors; +import org.ethereum.util.RLP; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -48,9 +46,9 @@ public final class PendingFederation { private static final Logger logger = LoggerFactory.getLogger("PendingFederation"); private static final int MIN_MEMBERS_REQUIRED = 2; - private final List members; + public PendingFederation(List members) { // Sorting members ensures same order for members // Immutability provides protection against unwanted modification, thus making the Pending Federation instance @@ -160,7 +158,7 @@ public boolean equals(Object other) { } public Keccak256 getHash() { - byte[] encoded = BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(this); + byte[] encoded = this.serializeOnlyBtcKeys(); return new Keccak256(HashUtil.keccak256(encoded)); } @@ -170,4 +168,39 @@ public int hashCode() { // well-defined hashCode() return Objects.hash(getBtcPublicKeys()); } + + /** + * A pending federation is serialized as the + * public keys conforming it. + * A list of btc public keys is serialized as + * [pubkey1, pubkey2, ..., pubkeyn], sorted + * using the lexicographical order of the public keys + * (see BtcECKey.PUBKEY_COMPARATOR). + * This is a legacy format for blocks before the Wasabi + * network upgrade. + */ + public byte[] serializeOnlyBtcKeys() { + List encodedKeys = this.getBtcPublicKeys().stream() + .sorted(BtcECKey.PUBKEY_COMPARATOR) + .map(key -> RLP.encodeElement(key.getPubKey())) + .collect(Collectors.toList()); + return RLP.encodeList(encodedKeys.toArray(new byte[0][])); + } + + /** + * A pending federation is serialized as the + * list of its sorted members serialized. + * A FederationMember is serialized as a list in the following order: + * - BTC public key + * - RSK public key + * - MST public key + * All keys are stored in their COMPRESSED versions. + */ + public byte[] serialize() { + List encodedMembers = this.getMembers().stream() + .sorted(FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR) + .map(FederationMember::serialize) + .collect(Collectors.toList()); + return RLP.encodeList(encodedMembers.toArray(new byte[0][])); + } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 6cbeaf48705..1ff8355d348 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -363,7 +363,7 @@ void serializeAndDeserializePendingFederation() { } PendingFederation testPendingFederation = new PendingFederation(members); - byte[] serializedTestPendingFederation = BridgeSerializationUtils.serializePendingFederation(testPendingFederation); + byte[] serializedTestPendingFederation = testPendingFederation.serialize(); PendingFederation deserializedTestPendingFederation = BridgeSerializationUtils.deserializePendingFederation( serializedTestPendingFederation); @@ -385,7 +385,7 @@ void serializePendingFederation_serializedKeysAreCompressedAndThree() { PendingFederation testPendingFederation = new PendingFederation(members); - byte[] serializedPendingFederation = BridgeSerializationUtils.serializePendingFederation(testPendingFederation); + byte[] serializedPendingFederation = testPendingFederation.serialize(); RLPList memberList = (RLPList) RLP.decode2(serializedPendingFederation).get(0); @@ -438,7 +438,7 @@ void serializePendingFederationOnlyBtcKeys() throws Exception { })) ); - byte[] result = BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(pendingFederation); + byte[] result = pendingFederation.serializeOnlyBtcKeys(); StringBuilder expectedBuilder = new StringBuilder(); expectedBuilder.append("f8cc"); pendingFederation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index c02f9749e2f..fedbc18227f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -1126,124 +1126,100 @@ void getPendingFederation_multiKeyVersion_nullBytes() { } @Test - void savePendingFederation_preMultikey() { + void savePendingFederation_preMultikey() throws IOException { PendingFederation pendingFederation = buildMockPendingFederation(100, 200, 300); List storageBytesCalls = new ArrayList<>(); List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { - bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(any(PendingFederation.class))).then((InvocationOnMock invocation) -> { - PendingFederation federation = invocation.getArgument(0); - Assertions.assertEquals(pendingFederation, federation); - serializeCalls.add(0); - return new byte[]{(byte) 0xbb}; - }); + doAnswer((InvocationOnMock invocation) -> { + storageBytesCalls.add(0); + RskAddress contractAddress = invocation.getArgument(0); + DataWord address = invocation.getArgument(1); - doAnswer((InvocationOnMock invocation) -> { - storageBytesCalls.add(0); - RskAddress contractAddress = invocation.getArgument(0); - DataWord address = invocation.getArgument(1); - byte[] data = invocation.getArgument(2); - // Make sure the bytes are set to the correct address in the repo and that what's saved is what was serialized - assertArrayEquals(new byte[]{(byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd}, contractAddress.getBytes()); - Assertions.assertEquals(PENDING_FEDERATION_KEY.getKey(), address); - assertArrayEquals(new byte[]{(byte) 0xbb}, data); - return null; - }).when(repositoryMock).addStorageBytes(any(RskAddress.class), any(DataWord.class), any(byte[].class)); + // Make sure the bytes are set to the correct address in the repo and that what's saved is what was serialized + assertArrayEquals(new byte[]{(byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd}, contractAddress.getBytes()); + Assertions.assertEquals(PENDING_FEDERATION_KEY.getKey(), address); + return null; + }).when(repositoryMock).addStorageBytes(any(RskAddress.class), any(DataWord.class), any(byte[].class)); - storageProvider.savePendingFederation(); - // Shouldn't have tried to save nor serialize anything - assertEquals(0, storageBytesCalls.size()); - assertEquals(0, serializeCalls.size()); - storageProvider.setPendingFederation(pendingFederation); - storageProvider.savePendingFederation(); - assertEquals(1, storageBytesCalls.size()); - assertEquals(1, serializeCalls.size()); - } + storageProvider.savePendingFederation(); + // Shouldn't have tried to save anything since pending federation is not set + assertEquals(0, storageBytesCalls.size()); + + storageProvider.setPendingFederation(pendingFederation); + // Should save the pending federation because is now set + storageProvider.savePendingFederation(); + // Should have called storage one time + assertEquals(1, storageBytesCalls.size()); } @Test - void savePendingFederation_preMultikey_setToNull() { - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { - List storageBytesCalls = new ArrayList<>(); - Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); - - Mockito.doAnswer((InvocationOnMock invocation) -> { - storageBytesCalls.add(0); - RskAddress contractAddress = invocation.getArgument(0); - DataWord address = invocation.getArgument(1); - byte[] data = invocation.getArgument(2); - // Make sure the bytes are set to the correct address in the repo and that what's saved is what was serialized - assertArrayEquals(new byte[]{(byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd}, contractAddress.getBytes()); - Assertions.assertEquals(PENDING_FEDERATION_KEY.getKey(), address); - assertNull(data); - return null; - }).when(repositoryMock).addStorageBytes(any(RskAddress.class), any(DataWord.class), any()); + void savePendingFederation_preMultikey_setToNull() throws IOException { + List storageBytesCalls = new ArrayList<>(); + Repository repositoryMock = mock(Repository.class); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); - storageProvider.savePendingFederation(); - // Shouldn't have tried to save nor serialize anything - Assertions.assertEquals(0, storageBytesCalls.size()); - storageProvider.setPendingFederation(null); - storageProvider.savePendingFederation(); - Assertions.assertEquals(1, storageBytesCalls.size()); + Mockito.doAnswer((InvocationOnMock invocation) -> { + storageBytesCalls.add(0); + RskAddress contractAddress = invocation.getArgument(0); + DataWord address = invocation.getArgument(1); + byte[] data = invocation.getArgument(2); + // Make sure the bytes are set to the correct address in the repo and that what's saved is what was serialized + assertArrayEquals(new byte[]{(byte) 0xaa, (byte) 0xbb, (byte) 0xcc, (byte) 0xdd}, contractAddress.getBytes()); + Assertions.assertEquals(PENDING_FEDERATION_KEY.getKey(), address); + assertNull(data); + return null; + }).when(repositoryMock).addStorageBytes(any(RskAddress.class), any(DataWord.class), any()); - bridgeSerializationUtilsMocked.verify(() -> BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(any(PendingFederation.class)), never()); - bridgeSerializationUtilsMocked.verify(() -> BridgeSerializationUtils.serializePendingFederation(any(PendingFederation.class)), never()); - } + storageProvider.savePendingFederation(); + // Shouldn't have tried to save nor serialize anything + Assertions.assertEquals(0, storageBytesCalls.size()); + storageProvider.setPendingFederation(null); + storageProvider.savePendingFederation(); + Assertions.assertEquals(1, storageBytesCalls.size()); } @Test - void savePendingFederation_postMultikey() { + void savePendingFederation_postMultikey() throws IOException { PendingFederation pendingFederation = buildMockPendingFederation(100, 200, 300); List storageBytesCalls = new ArrayList<>(); - List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsAllForks); - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class, Mockito.CALLS_REAL_METHODS)) { - bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializePendingFederation(any(PendingFederation.class))).then((InvocationOnMock invocation) -> { - PendingFederation federation = invocation.getArgument(0); - Assertions.assertEquals(pendingFederation, federation); - serializeCalls.add(0); - return new byte[]{(byte) 0xbb}; - }); + Mockito.doAnswer((InvocationOnMock invocation) -> { + storageBytesCalls.add(0); + RskAddress contractAddress = invocation.getArgument(0); + DataWord address = invocation.getArgument(1); + byte[] data = invocation.getArgument(2); - Mockito.doAnswer((InvocationOnMock invocation) -> { - storageBytesCalls.add(0); - RskAddress contractAddress = invocation.getArgument(0); - DataWord address = invocation.getArgument(1); - byte[] data = invocation.getArgument(2); + assertArrayEquals(Hex.decode("aabbccdd"), contractAddress.getBytes()); - assertArrayEquals(Hex.decode("aabbccdd"), contractAddress.getBytes()); + if (storageBytesCalls.size() == 1) { + Assertions.assertEquals(PENDING_FEDERATION_FORMAT_VERSION.getKey(), address); + Assertions.assertEquals(BigInteger.valueOf(1000), RLP.decodeBigInteger(data, 0)); + } else { + Assertions.assertEquals(2, storageBytesCalls.size()); + // Make sure the bytes are set to the correct address in the repo and that what's saved is what was serialized + Assertions.assertEquals(PENDING_FEDERATION_KEY.getKey(), address); + } + return null; + }).when(repositoryMock).addStorageBytes(any(RskAddress.class), any(DataWord.class), any(byte[].class)); - if (storageBytesCalls.size() == 1) { - Assertions.assertEquals(PENDING_FEDERATION_FORMAT_VERSION.getKey(), address); - Assertions.assertEquals(BigInteger.valueOf(1000), RLP.decodeBigInteger(data, 0)); - } else { - Assertions.assertEquals(2, storageBytesCalls.size()); - // Make sure the bytes are set to the correct address in the repo and that what's saved is what was serialized - Assertions.assertEquals(PENDING_FEDERATION_KEY.getKey(), address); - assertArrayEquals(new byte[]{(byte) 0xbb}, data); - } - return null; - }).when(repositoryMock).addStorageBytes(any(RskAddress.class), any(DataWord.class), any(byte[].class)); + storageProvider.savePendingFederation(); + // Shouldn't have tried to save anything since pending federation is not set + Assertions.assertEquals(0, storageBytesCalls.size()); - storageProvider.savePendingFederation(); - // Shouldn't have tried to save nor serialize anything - Assertions.assertEquals(0, storageBytesCalls.size()); - Assertions.assertEquals(0, serializeCalls.size()); - storageProvider.setPendingFederation(pendingFederation); - storageProvider.savePendingFederation(); - Assertions.assertEquals(2, storageBytesCalls.size()); - Assertions.assertEquals(1, serializeCalls.size()); - } + storageProvider.setPendingFederation(pendingFederation); + // Should save the pending federation because is now set + storageProvider.savePendingFederation(); + // Should have called storage two times since RSKIP123 is activated + Assertions.assertEquals(2, storageBytesCalls.size()); } @Test - void savePendingFederation_postMultikey_setToNull() { + void savePendingFederation_postMultikey_setToNull() throws IOException { try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class, Mockito.CALLS_REAL_METHODS)) { List storageBytesCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); @@ -1275,9 +1251,6 @@ void savePendingFederation_postMultikey_setToNull() { storageProvider.setPendingFederation(null); storageProvider.savePendingFederation(); Assertions.assertEquals(2, storageBytesCalls.size()); - - bridgeSerializationUtilsMocked.verify(() -> BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(any(PendingFederation.class)), never()); - bridgeSerializationUtilsMocked.verify(() -> BridgeSerializationUtils.serializePendingFederation(any(PendingFederation.class)), never()); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index 0cb9e4da7bc..1210f7211b4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -24,10 +24,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.crypto.Keccak256; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationMember; -import co.rsk.peg.federation.FederationTestUtils; +import co.rsk.peg.federation.*; import co.rsk.peg.resources.TestConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -244,16 +241,12 @@ void buildFederation_incomplete() { fail(); } - @Test +/* @Test void getHash() { - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { - bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.serializePendingFederationOnlyBtcKeys(pendingFederation)).thenReturn(new byte[]{(byte) 0xaa}); - - Keccak256 expectedHash = new Keccak256(HashUtil.keccak256(new byte[]{(byte) 0xaa})); - - assertEquals(expectedHash, pendingFederation.getHash()); - } - } + byte[] pendingFederationBytes = {39, 127, 53, -79, -61, -73, 66, -15, 94, -22, -69, 36, 57, 103, 121, 77, -112, -93, -110, 109, 74, 74, -111, -53, -7, -41, -39, -20, -22, -59, 74, 86}; + Keccak256 expectedHash = new Keccak256(HashUtil.keccak256(pendingFederationBytes)); + assertEquals(expectedHash, pendingFederation.getHash()); + }*/ private void testBuildFederation( boolean isRskip201Active, diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java index cc674d670bc..ff444375388 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/FederationChangeTest.java @@ -23,7 +23,7 @@ import co.rsk.core.RskAddress; import co.rsk.peg.*; import co.rsk.peg.federation.FederationMember; -import co.rsk.peg.PendingFederation; +import co.rsk.peg.federation.PendingFederation; import org.ethereum.core.Repository; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java index 0d5c580939c..94b53c3e681 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/PendingFederationTest.java @@ -21,7 +21,7 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.peg.Bridge; import co.rsk.peg.BridgeStorageProvider; -import co.rsk.peg.PendingFederation; +import co.rsk.peg.federation.PendingFederation; import org.ethereum.core.CallTransaction; import org.ethereum.core.Repository; import org.ethereum.vm.exception.VMException; From 6c0c5d6e5afa8be376fc33b11b366d17e30d42ff Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 22 Dec 2023 12:24:06 -0300 Subject: [PATCH 041/137] Modify getHash test in PendingFederationTest --- .../src/test/java/co/rsk/peg/PendingFederationTest.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java index 1210f7211b4..9aad05d74e7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java @@ -34,7 +34,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.MockedStatic; import org.mockito.junit.jupiter.MockitoExtension; import org.mockito.junit.jupiter.MockitoSettings; import org.mockito.quality.Strictness; @@ -241,12 +240,12 @@ void buildFederation_incomplete() { fail(); } -/* @Test + @Test void getHash() { - byte[] pendingFederationBytes = {39, 127, 53, -79, -61, -73, 66, -15, 94, -22, -69, 36, 57, 103, 121, 77, -112, -93, -110, 109, 74, 74, -111, -53, -7, -41, -39, -20, -22, -59, 74, 86}; - Keccak256 expectedHash = new Keccak256(HashUtil.keccak256(pendingFederationBytes)); + byte[] pendingFederationData = pendingFederation.serializeOnlyBtcKeys(); + Keccak256 expectedHash = new Keccak256(HashUtil.keccak256(pendingFederationData)); assertEquals(expectedHash, pendingFederation.getHash()); - }*/ + } private void testBuildFederation( boolean isRskip201Active, From fbe19658fc7ffbc87e0cb438f5632520eda93d19 Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 22 Dec 2023 16:07:23 -0300 Subject: [PATCH 042/137] Add activations to serialization logic. Adapt to that change and refactor --- .../co/rsk/peg/BridgeStorageProvider.java | 29 +++------- .../rsk/peg/federation/PendingFederation.java | 43 +++++++++------ .../rsk/peg/BridgeSerializationUtilsTest.java | 18 +++++- .../co/rsk/peg/BridgeStorageProviderTest.java | 55 +++++++++---------- 4 files changed, 73 insertions(+), 72 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 24a6bdd468c..570fc2b50ef 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -464,38 +464,23 @@ public void setPendingFederation(PendingFederation federation) { public void savePendingFederation() throws IOException { if (shouldSavePendingFederation) { if (activations.isActive(RSKIP123)) { - savePendingFederation(pendingFederation); - } - else { - savePendingFederationOnlyBtcKeys(pendingFederation); + // we only need to save the standard part of the fed since the emergency part is constant + saveStorageVersion( + PENDING_FEDERATION_FORMAT_VERSION.getKey(), + STANDARD_MULTISIG_FEDERATION.getFormatVersion() + ); } + savePendingFederation(pendingFederation); } } - /** - * Save the pending federation before RSKIP123 - */ - private void savePendingFederationOnlyBtcKeys(PendingFederation pendingFederation) throws IOException { - byte[] fedSerialized = null; - if (pendingFederation != null) { - fedSerialized = pendingFederation.serializeOnlyBtcKeys(); - } - savePendingFederationToRepository(fedSerialized); - } - /** * Save the pending federation */ private void savePendingFederation(PendingFederation pendingFederation) throws IOException { - // we only need to save the standard part of the fed since the emergency part is constant - saveStorageVersion( - PENDING_FEDERATION_FORMAT_VERSION.getKey(), - STANDARD_MULTISIG_FEDERATION.getFormatVersion() - ); - byte[] fedSerialized = null; if (pendingFederation != null) { - fedSerialized = pendingFederation.serialize(); + fedSerialized = pendingFederation.serialize(activations); } savePendingFederationToRepository(fedSerialized); } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index 17b3b683a5a..f8a93db3ff9 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -48,7 +48,6 @@ public final class PendingFederation { private static final int MIN_MEMBERS_REQUIRED = 2; private final List members; - public PendingFederation(List members) { // Sorting members ensures same order for members // Immutability provides protection against unwanted modification, thus making the Pending Federation instance @@ -169,22 +168,12 @@ public int hashCode() { return Objects.hash(getBtcPublicKeys()); } - /** - * A pending federation is serialized as the - * public keys conforming it. - * A list of btc public keys is serialized as - * [pubkey1, pubkey2, ..., pubkeyn], sorted - * using the lexicographical order of the public keys - * (see BtcECKey.PUBKEY_COMPARATOR). - * This is a legacy format for blocks before the Wasabi - * network upgrade. - */ - public byte[] serializeOnlyBtcKeys() { - List encodedKeys = this.getBtcPublicKeys().stream() - .sorted(BtcECKey.PUBKEY_COMPARATOR) - .map(key -> RLP.encodeElement(key.getPubKey())) - .collect(Collectors.toList()); - return RLP.encodeList(encodedKeys.toArray(new byte[0][])); + public byte[] serialize(ActivationConfig.ForBlock activations) { + if (activations.isActive(ConsensusRule.RSKIP123)) { + return serializeFromMembers(); + } else { + return serializeOnlyBtcKeys(); + } } /** @@ -196,11 +185,29 @@ public byte[] serializeOnlyBtcKeys() { * - MST public key * All keys are stored in their COMPRESSED versions. */ - public byte[] serialize() { + private byte[] serializeFromMembers() { List encodedMembers = this.getMembers().stream() .sorted(FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR) .map(FederationMember::serialize) .collect(Collectors.toList()); return RLP.encodeList(encodedMembers.toArray(new byte[0][])); } + + /** + * A pending federation is serialized as the + * public keys conforming it. + * A list of btc public keys is serialized as + * [pubkey1, pubkey2, ..., pubkeyn], sorted + * using the lexicographical order of the public keys + * (see BtcECKey.PUBKEY_COMPARATOR). + * This is a legacy format for blocks before the Wasabi + * network upgrade. + */ + public byte[] serializeOnlyBtcKeys() { + List encodedKeys = this.getBtcPublicKeys().stream() + .sorted(BtcECKey.PUBKEY_COMPARATOR) + .map(key -> RLP.encodeElement(key.getPubKey())) + .collect(Collectors.toList()); + return RLP.encodeList(encodedKeys.toArray(new byte[0][])); + } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 1ff8355d348..cebdda868d4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -353,6 +353,10 @@ void deserializeFederation_invalidFederationMember() { @Test void serializeAndDeserializePendingFederation() { + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + // we want serialization from members + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + final int NUM_CASES = 20; for (int i = 0; i < NUM_CASES; i++) { @@ -363,7 +367,7 @@ void serializeAndDeserializePendingFederation() { } PendingFederation testPendingFederation = new PendingFederation(members); - byte[] serializedTestPendingFederation = testPendingFederation.serialize(); + byte[] serializedTestPendingFederation = testPendingFederation.serialize(activations); PendingFederation deserializedTestPendingFederation = BridgeSerializationUtils.deserializePendingFederation( serializedTestPendingFederation); @@ -374,6 +378,10 @@ void serializeAndDeserializePendingFederation() { @Test void serializePendingFederation_serializedKeysAreCompressedAndThree() { + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + // we want serialization from members + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + final int NUM_MEMBERS = 10; final int EXPECTED_NUM_KEYS = 3; final int EXPECTED_PUBLICKEY_SIZE = 33; @@ -385,7 +393,7 @@ void serializePendingFederation_serializedKeysAreCompressedAndThree() { PendingFederation testPendingFederation = new PendingFederation(members); - byte[] serializedPendingFederation = testPendingFederation.serialize(); + byte[] serializedPendingFederation = testPendingFederation.serialize(activations); RLPList memberList = (RLPList) RLP.decode2(serializedPendingFederation).get(0); @@ -417,6 +425,10 @@ void deserializePendingFederation_invalidFederationMember() { @Test void serializePendingFederationOnlyBtcKeys() throws Exception { + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + // we want serialization from pub keys + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(false); + byte[][] publicKeyBytes = new byte[][]{ BtcECKey.fromPrivate(BigInteger.valueOf(100)).getPubKey(), BtcECKey.fromPrivate(BigInteger.valueOf(200)).getPubKey(), @@ -438,7 +450,7 @@ void serializePendingFederationOnlyBtcKeys() throws Exception { })) ); - byte[] result = pendingFederation.serializeOnlyBtcKeys(); + byte[] result = pendingFederation.serialize(activations); StringBuilder expectedBuilder = new StringBuilder(); expectedBuilder.append("f8cc"); pendingFederation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index fedbc18227f..2e7d656e7a7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -1129,7 +1129,6 @@ void getPendingFederation_multiKeyVersion_nullBytes() { void savePendingFederation_preMultikey() throws IOException { PendingFederation pendingFederation = buildMockPendingFederation(100, 200, 300); List storageBytesCalls = new ArrayList<>(); - List serializeCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsBeforeFork); @@ -1220,38 +1219,36 @@ void savePendingFederation_postMultikey() throws IOException { @Test void savePendingFederation_postMultikey_setToNull() throws IOException { - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class, Mockito.CALLS_REAL_METHODS)) { - List storageBytesCalls = new ArrayList<>(); - Repository repositoryMock = mock(Repository.class); - BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsAllForks); + List storageBytesCalls = new ArrayList<>(); + Repository repositoryMock = mock(Repository.class); + BridgeStorageProvider storageProvider = new BridgeStorageProvider(repositoryMock, mockAddress("aabbccdd"), bridgeTestnetInstance, activationsAllForks); - Mockito.doAnswer((InvocationOnMock invocation) -> { - storageBytesCalls.add(0); - RskAddress contractAddress = invocation.getArgument(0); - DataWord address = invocation.getArgument(1); - byte[] data = invocation.getArgument(2); + Mockito.doAnswer((InvocationOnMock invocation) -> { + storageBytesCalls.add(0); + RskAddress contractAddress = invocation.getArgument(0); + DataWord address = invocation.getArgument(1); + byte[] data = invocation.getArgument(2); - assertArrayEquals(Hex.decode("aabbccdd"), contractAddress.getBytes()); + assertArrayEquals(Hex.decode("aabbccdd"), contractAddress.getBytes()); - if (storageBytesCalls.size() == 1) { - Assertions.assertEquals(PENDING_FEDERATION_FORMAT_VERSION.getKey(), address); - Assertions.assertEquals(BigInteger.valueOf(1000), RLP.decodeBigInteger(data, 0)); - } else { - Assertions.assertEquals(2, storageBytesCalls.size()); - // Make sure the bytes are set to the correct address in the repo and that what's saved is what was serialized - Assertions.assertEquals(PENDING_FEDERATION_KEY.getKey(), address); - assertNull(data); - } - return null; - }).when(repositoryMock).addStorageBytes(any(RskAddress.class), any(DataWord.class), any()); + if (storageBytesCalls.size() == 1) { + Assertions.assertEquals(PENDING_FEDERATION_FORMAT_VERSION.getKey(), address); + Assertions.assertEquals(BigInteger.valueOf(1000), RLP.decodeBigInteger(data, 0)); + } else { + Assertions.assertEquals(2, storageBytesCalls.size()); + // Make sure the bytes are set to the correct address in the repo and that what's saved is what was serialized + Assertions.assertEquals(PENDING_FEDERATION_KEY.getKey(), address); + assertNull(data); + } + return null; + }).when(repositoryMock).addStorageBytes(any(RskAddress.class), any(DataWord.class), any()); - storageProvider.savePendingFederation(); - // Shouldn't have tried to save nor serialize anything - Assertions.assertEquals(0, storageBytesCalls.size()); - storageProvider.setPendingFederation(null); - storageProvider.savePendingFederation(); - Assertions.assertEquals(2, storageBytesCalls.size()); - } + storageProvider.savePendingFederation(); + // Shouldn't have tried to save nor serialize anything + Assertions.assertEquals(0, storageBytesCalls.size()); + storageProvider.setPendingFederation(null); + storageProvider.savePendingFederation(); + Assertions.assertEquals(2, storageBytesCalls.size()); } @Test From 8f9d894f6e38201f3fa829af9bb3c041cfb8843f Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 4 Jan 2024 15:07:31 -0300 Subject: [PATCH 043/137] Move respective deserialization methods from BridgeSerializationUtils to PendingFederation and FederationMember. Move respective tests from BridgeSerializationUtilsTest to PendingFederationTest and FederationMemberTest. Rename methods to be clearer. --- .../co/rsk/peg/BridgeSerializationUtils.java | 87 +---------- .../co/rsk/peg/BridgeStorageProvider.java | 20 +-- .../rsk/peg/federation/FederationMember.java | 41 +++-- .../rsk/peg/federation/PendingFederation.java | 43 ++++- .../rsk/peg/BridgeSerializationUtilsTest.java | 141 ----------------- .../co/rsk/peg/BridgeStorageProviderTest.java | 16 +- .../peg/federation/FederationMemberTest.java | 8 + .../PendingFederationTest.java | 147 +++++++++++++++++- 8 files changed, 241 insertions(+), 262 deletions(-) rename rskj-core/src/test/java/co/rsk/peg/{ => federation}/PendingFederationTest.java (62%) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 45ff8f54847..83bc82e6f98 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -31,7 +31,6 @@ import org.apache.commons.lang3.tuple.Pair; import org.bouncycastle.util.BigIntegers; import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.crypto.ECKey; import org.ethereum.util.RLP; import org.ethereum.util.RLPElement; import org.ethereum.util.RLPList; @@ -56,11 +55,6 @@ public class BridgeSerializationUtils { private static final int FEDERATION_CREATION_BLOCK_NUMBER_INDEX = 1; private static final int FEDERATION_MEMBERS_INDEX = 2; - private static final int FEDERATION_MEMBER_LIST_SIZE = 3; - private static final int FEDERATION_MEMBER_BTC_KEY_INDEX = 0; - private static final int FEDERATION_MEMBER_RSK_KEY_INDEX = 1; - private static final int FEDERATION_MEMBER_MST_KEY_INDEX = 2; - private BridgeSerializationUtils() { throw new IllegalAccessError("Utility class, do not instantiate it"); } @@ -305,7 +299,7 @@ public static StandardMultisigFederation deserializeStandardMultisigFederationOn public static byte[] serializeFederation(Federation federation) { return serializeFederationWithSerializer( federation, - BridgeSerializationUtils::serializeFederationMember + FederationMember::serialize ); } @@ -317,7 +311,7 @@ public static StandardMultisigFederation deserializeStandardMultisigFederation( return deserializeStandardMultisigFederationWithDeserializer( data, networkParameters, - BridgeSerializationUtils::deserializeFederationMember + FederationMember::deserialize ); } public static ErpFederation deserializeLegacyErpFederation( @@ -328,7 +322,7 @@ public static ErpFederation deserializeLegacyErpFederation( Federation federation = deserializeStandardMultisigFederationWithDeserializer( data, bridgeConstants.getBtcParams(), - BridgeSerializationUtils::deserializeFederationMember + FederationMember::deserialize ); return FederationFactory.buildNonStandardErpFederation( @@ -349,7 +343,7 @@ public static ErpFederation deserializeP2shErpFederation( Federation federation = deserializeStandardMultisigFederationWithDeserializer( data, bridgeConstants.getBtcParams(), - BridgeSerializationUtils::deserializeFederationMember + FederationMember::deserialize ); return FederationFactory.buildP2shErpFederation( federation.getMembers(), @@ -361,64 +355,6 @@ public static ErpFederation deserializeP2shErpFederation( ); } - /** - * A FederationMember is serialized as a list in the following order: - * - BTC public key - * - RSK public key - * - MST public key - * All keys are stored in their COMPRESSED versions. - */ - public static byte[] serializeFederationMember(FederationMember federationMember) { - byte[][] rlpElements = new byte[FEDERATION_MEMBER_LIST_SIZE][]; - rlpElements[FEDERATION_MEMBER_BTC_KEY_INDEX] = RLP.encodeElement( - federationMember.getBtcPublicKey().getPubKeyPoint().getEncoded(true) - ); - rlpElements[FEDERATION_MEMBER_RSK_KEY_INDEX] = RLP.encodeElement(federationMember.getRskPublicKey().getPubKey(true)); - rlpElements[FEDERATION_MEMBER_MST_KEY_INDEX] = RLP.encodeElement(federationMember.getMstPublicKey().getPubKey(true)); - return RLP.encodeList(rlpElements); - } - - // For the serialization format, see BridgeSerializationUtils::serializeFederationMember - private static FederationMember deserializeFederationMember(byte[] data) { - RLPList rlpList = (RLPList)RLP.decode2(data).get(0); - - if (rlpList.size() != FEDERATION_RLP_LIST_SIZE) { - throw new RuntimeException(String.format("Invalid serialized FederationMember. Expected %d elements but got %d", FEDERATION_MEMBER_LIST_SIZE, rlpList.size())); - } - - BtcECKey btcKey = BtcECKey.fromPublicOnly(rlpList.get(FEDERATION_MEMBER_BTC_KEY_INDEX).getRLPData()); - ECKey rskKey = ECKey.fromPublicOnly(rlpList.get(FEDERATION_MEMBER_RSK_KEY_INDEX).getRLPData()); - ECKey mstKey = ECKey.fromPublicOnly(rlpList.get(FEDERATION_MEMBER_MST_KEY_INDEX).getRLPData()); - - return new FederationMember(btcKey, rskKey, mstKey); - } - - // For the serialization format, see BridgeSerializationUtils::serializePendingFederationOnlyBtcKeys - // and serializePublicKeys::deserializeBtcPublicKeys - public static PendingFederation deserializePendingFederationOnlyBtcKeys(byte[] data) { - // BTC, RSK and MST keys are the same - List members = deserializeBtcPublicKeys(data).stream().map(pk -> - FederationMember.getFederationMemberFromKey(pk) - ).collect(Collectors.toList()); - - return new PendingFederation(members); - } - - // For the serialization format, see BridgeSerializationUtils::serializePendingFederation - public static PendingFederation deserializePendingFederation(byte[] data) { - RLPList rlpList = (RLPList)RLP.decode2(data).get(0); - - List members = new ArrayList<>(); - - for (int k = 0; k < rlpList.size(); k++) { - RLPElement element = rlpList.get(k); - FederationMember member = deserializeFederationMember(element.getRLPData()); - members.add(member); - } - - return new PendingFederation(members); - } - // An ABI call election is serialized as a list of the votes, like so: // spec_1, voters_1, ..., spec_n, voters_n // Specs are sorted by their signed byte encoding lexicographically. @@ -867,21 +803,6 @@ private static ABICallSpec deserializeABICallSpec(byte[] data) { return new ABICallSpec(function, arguments); } - // For the serialization format, see BridgeSerializationUtils::serializePublicKeys - private static List deserializeBtcPublicKeys(byte[] data) { - RLPList rlpList = (RLPList)RLP.decode2(data).get(0); - - List keys = new ArrayList<>(); - - for (int k = 0; k < rlpList.size(); k++) { - RLPElement element = rlpList.get(k); - BtcECKey key = BtcECKey.fromPublicOnly(element.getRLPData()); - keys.add(key); - } - - return keys; - } - // A list of voters is serialized as // [voterBytes1, voterBytes2, ..., voterBytesn], sorted // using the lexicographical order of the voters' unsigned bytes diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 570fc2b50ef..348896e43f2 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -443,10 +443,10 @@ public PendingFederation getPendingFederation() { return null; } if (storageVersion.isPresent()) { - return BridgeSerializationUtils.deserializePendingFederation(data); // Assume this is the multi-key version + return PendingFederation.deserialize(data); // Assume this is the multi-key version } - return BridgeSerializationUtils.deserializePendingFederationOnlyBtcKeys(data); + return PendingFederation.deserializeFromBtcKeys(data); } ); @@ -461,7 +461,7 @@ public void setPendingFederation(PendingFederation federation) { /** * Save the pending federation */ - public void savePendingFederation() throws IOException { + protected void savePendingFederation() throws IOException { if (shouldSavePendingFederation) { if (activations.isActive(RSKIP123)) { // we only need to save the standard part of the fed since the emergency part is constant @@ -470,19 +470,15 @@ public void savePendingFederation() throws IOException { STANDARD_MULTISIG_FEDERATION.getFormatVersion() ); } - savePendingFederation(pendingFederation); + savePendingFederationToRepository(pendingFederation); } } - - /** - * Save the pending federation - */ - private void savePendingFederation(PendingFederation pendingFederation) throws IOException { + private void savePendingFederationToRepository(PendingFederation pendingFederation) throws IOException { byte[] fedSerialized = null; if (pendingFederation != null) { fedSerialized = pendingFederation.serialize(activations); } - savePendingFederationToRepository(fedSerialized); + saveSerializedPendingFederationToRepository(fedSerialized); } /** @@ -1145,12 +1141,12 @@ private void saveToRepository(DataWord addressKey, T object, RepositorySeria repository.addStorageBytes(contractAddress, addressKey, data); } - private void savePendingFederationToRepository(byte[] federationSerialized) throws IOException { + private void saveSerializedPendingFederationToRepository(byte[] federationSerialized) throws IOException { try { DataWord pendingFederationKey = PENDING_FEDERATION_KEY.getKey(); repository.addStorageBytes(contractAddress, pendingFederationKey, federationSerialized); } catch (RuntimeException e) { - throw new IOException("Unable to save to repository: " + Arrays.toString(federationSerialized), e); + throw new IOException("Unable to save pending federation to repository: " + Arrays.toString(federationSerialized), e); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java index 551c7c15fd7..9b57a5fcf2d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationMember.java @@ -22,6 +22,7 @@ import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; +import org.ethereum.util.RLPList; import java.util.Arrays; import java.util.List; @@ -38,10 +39,10 @@ */ public final class FederationMember { public static final FederationMemberPubKeysComparator BTC_RSK_MST_PUBKEYS_COMPARATOR = new FederationMemberPubKeysComparator(); - private static final int FEDERATION_MEMBER_LIST_SIZE = 3; - private static final int FEDERATION_MEMBER_BTC_KEY_INDEX = 0; - private static final int FEDERATION_MEMBER_RSK_KEY_INDEX = 1; - private static final int FEDERATION_MEMBER_MST_KEY_INDEX = 2; + private static final int KEYS_QUANTITY = 3; + private static final int BTC_KEY_INDEX = 0; + private static final int RSK_KEY_INDEX = 1; + private static final int MST_KEY_INDEX = 2; private final BtcECKey btcPublicKey; private final ECKey rskPublicKey; private final ECKey mstPublicKey; @@ -161,12 +162,32 @@ public int hashCode() { } public byte[] serialize() { - byte[][] rlpElements = new byte[FEDERATION_MEMBER_LIST_SIZE][]; - rlpElements[FEDERATION_MEMBER_BTC_KEY_INDEX] = RLP.encodeElement( - this.getBtcPublicKey().getPubKeyPoint().getEncoded(true) - ); - rlpElements[FEDERATION_MEMBER_RSK_KEY_INDEX] = RLP.encodeElement(this.getRskPublicKey().getPubKey(true)); - rlpElements[FEDERATION_MEMBER_MST_KEY_INDEX] = RLP.encodeElement(this.getMstPublicKey().getPubKey(true)); + byte[][] rlpElements = new byte[KEYS_QUANTITY][]; + byte[] btcPublicKeyBytes = this.getBtcPublicKey().getPubKeyPoint().getEncoded(true); + byte[] rskPublicKeyBytes = this.getRskPublicKey().getPubKey(true); + byte[] mstPublicKeyBytes = this.getMstPublicKey().getPubKey(true); + + rlpElements[BTC_KEY_INDEX] = RLP.encodeElement(btcPublicKeyBytes); + rlpElements[RSK_KEY_INDEX] = RLP.encodeElement(rskPublicKeyBytes); + rlpElements[MST_KEY_INDEX] = RLP.encodeElement(mstPublicKeyBytes); return RLP.encodeList(rlpElements); } + + public static FederationMember deserialize(byte[] data) { + RLPList rlpList = (RLPList)RLP.decode2(data).get(0); + if (rlpList.size() != KEYS_QUANTITY) { + throw new RuntimeException(String.format( + "Invalid serialized FederationMember. Expected %d elements but got %d", KEYS_QUANTITY, rlpList.size()) + ); + } + + byte[] btcKeyData = rlpList.get(BTC_KEY_INDEX).getRLPData(); + byte[] rskKeyData = rlpList.get(RSK_KEY_INDEX).getRLPData(); + byte[] mstKeyData = rlpList.get(MST_KEY_INDEX).getRLPData(); + + BtcECKey btcKey = BtcECKey.fromPublicOnly(btcKeyData); + ECKey rskKey = ECKey.fromPublicOnly(rskKeyData); + ECKey mstKey = ECKey.fromPublicOnly(mstKeyData); + return new FederationMember(btcKey, rskKey, mstKey); + } } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index f8a93db3ff9..a3f52277c4d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -32,6 +32,8 @@ import java.util.Objects; import java.util.stream.Collectors; import org.ethereum.util.RLP; +import org.ethereum.util.RLPElement; +import org.ethereum.util.RLPList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -169,11 +171,23 @@ public int hashCode() { } public byte[] serialize(ActivationConfig.ForBlock activations) { - if (activations.isActive(ConsensusRule.RSKIP123)) { - return serializeFromMembers(); - } else { + if (!activations.isActive(ConsensusRule.RSKIP123)) { return serializeOnlyBtcKeys(); } + return serializeFromMembers(); + } + + public static PendingFederation deserialize(byte[] data) { + RLPList rlpList = (RLPList)RLP.decode2(data).get(0); + List deserializedMembers = new ArrayList<>(); + + for (int k = 0; k < rlpList.size(); k++) { + RLPElement element = rlpList.get(k); + FederationMember member = FederationMember.deserialize(element.getRLPData()); + deserializedMembers.add(member); + } + + return new PendingFederation(deserializedMembers); } /** @@ -203,11 +217,32 @@ private byte[] serializeFromMembers() { * This is a legacy format for blocks before the Wasabi * network upgrade. */ - public byte[] serializeOnlyBtcKeys() { + private byte[] serializeOnlyBtcKeys() { List encodedKeys = this.getBtcPublicKeys().stream() .sorted(BtcECKey.PUBKEY_COMPARATOR) .map(key -> RLP.encodeElement(key.getPubKey())) .collect(Collectors.toList()); return RLP.encodeList(encodedKeys.toArray(new byte[0][])); } + + public static PendingFederation deserializeFromBtcKeys(byte[] data) { + // BTC, RSK and MST keys are the same + List deserializedMembers = deserializeBtcPublicKeys(data).stream() + .map(FederationMember::getFederationMemberFromKey) + .collect(Collectors.toList()); + + return new PendingFederation(deserializedMembers); + } + + private static List deserializeBtcPublicKeys(byte[] data) { + RLPList rlpList = (RLPList)RLP.decode2(data).get(0); + + List keys = new ArrayList<>(); + for (int k = 0; k < rlpList.size(); k++) { + RLPElement element = rlpList.get(k); + BtcECKey key = BtcECKey.fromPublicOnly(element.getRLPData()); + keys.add(key); + } + return keys; + } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index cebdda868d4..3f5e7ee95de 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -26,8 +26,6 @@ import co.rsk.config.BridgeTestNetConstants; import co.rsk.core.RskAddress; import co.rsk.peg.bitcoin.CoinbaseInformation; -import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; -import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; import co.rsk.peg.federation.*; import co.rsk.peg.resources.TestConstants; import co.rsk.peg.utils.MerkleTreeUtils; @@ -345,147 +343,11 @@ void deserializeFederation_invalidFederationMember() { RLP.encodeList(RLP.encodeList(RLP.encodeElement(new byte[0]), RLP.encodeElement(new byte[0]))) ); - NetworkParameters networkParameters = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); Exception ex = Assertions.assertThrows(RuntimeException.class, () -> BridgeSerializationUtils.deserializeStandardMultisigFederation(serialized, networkParameters)); Assertions.assertTrue(ex.getMessage().contains("Invalid serialized FederationMember")); } - @Test - void serializeAndDeserializePendingFederation() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - // we want serialization from members - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - - final int NUM_CASES = 20; - - for (int i = 0; i < NUM_CASES; i++) { - int numMembers = randomInRange(2, 14); - List members = new ArrayList<>(); - for (int j = 0; j < numMembers; j++) { - members.add(new FederationMember(new BtcECKey(), new ECKey(), new ECKey())); - } - PendingFederation testPendingFederation = new PendingFederation(members); - - byte[] serializedTestPendingFederation = testPendingFederation.serialize(activations); - - PendingFederation deserializedTestPendingFederation = BridgeSerializationUtils.deserializePendingFederation( - serializedTestPendingFederation); - - Assertions.assertEquals(testPendingFederation, deserializedTestPendingFederation); - } - } - - @Test - void serializePendingFederation_serializedKeysAreCompressedAndThree() { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - // we want serialization from members - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); - - final int NUM_MEMBERS = 10; - final int EXPECTED_NUM_KEYS = 3; - final int EXPECTED_PUBLICKEY_SIZE = 33; - - List members = new ArrayList<>(); - for (int j = 0; j < NUM_MEMBERS; j++) { - members.add(new FederationMember(new BtcECKey(), new ECKey(), new ECKey())); - } - - PendingFederation testPendingFederation = new PendingFederation(members); - - byte[] serializedPendingFederation = testPendingFederation.serialize(activations); - - RLPList memberList = (RLPList) RLP.decode2(serializedPendingFederation).get(0); - - Assertions.assertEquals(NUM_MEMBERS, memberList.size()); - - for (int i = 0; i < NUM_MEMBERS; i++) { - RLPList memberKeys = (RLPList) RLP.decode2(memberList.get(i).getRLPData()).get(0); - Assertions.assertEquals(EXPECTED_NUM_KEYS, memberKeys.size()); - for (int j = 0; j < EXPECTED_NUM_KEYS; j++) { - Assertions.assertEquals(EXPECTED_PUBLICKEY_SIZE, memberKeys.get(j).getRLPData().length); - } - - } - } - - @Test - void deserializePendingFederation_invalidFederationMember() { - byte[] serialized = RLP.encodeList( - RLP.encodeList(RLP.encodeElement(new byte[0]), RLP.encodeElement(new byte[0])) - ); - - try { - BridgeSerializationUtils.deserializePendingFederation(serialized); - Assertions.fail(); - } catch (RuntimeException e) { - Assertions.assertTrue(e.getMessage().contains("Invalid serialized FederationMember")); - } - } - - @Test - void serializePendingFederationOnlyBtcKeys() throws Exception { - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - // we want serialization from pub keys - when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(false); - - byte[][] publicKeyBytes = new byte[][]{ - BtcECKey.fromPrivate(BigInteger.valueOf(100)).getPubKey(), - BtcECKey.fromPrivate(BigInteger.valueOf(200)).getPubKey(), - BtcECKey.fromPrivate(BigInteger.valueOf(300)).getPubKey(), - BtcECKey.fromPrivate(BigInteger.valueOf(400)).getPubKey(), - BtcECKey.fromPrivate(BigInteger.valueOf(500)).getPubKey(), - BtcECKey.fromPrivate(BigInteger.valueOf(600)).getPubKey(), - }; - - // Only actual keys serialized are BTC keys, so we don't really care about RSK or MST keys - PendingFederation pendingFederation = new PendingFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList(new BtcECKey[]{ - BtcECKey.fromPublicOnly(publicKeyBytes[0]), - BtcECKey.fromPublicOnly(publicKeyBytes[1]), - BtcECKey.fromPublicOnly(publicKeyBytes[2]), - BtcECKey.fromPublicOnly(publicKeyBytes[3]), - BtcECKey.fromPublicOnly(publicKeyBytes[4]), - BtcECKey.fromPublicOnly(publicKeyBytes[5]), - })) - ); - - byte[] result = pendingFederation.serialize(activations); - StringBuilder expectedBuilder = new StringBuilder(); - expectedBuilder.append("f8cc"); - pendingFederation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { - expectedBuilder.append("a1"); - expectedBuilder.append(ByteUtil.toHexString(key.getPubKey())); - }); - - String expected = expectedBuilder.toString(); - Assertions.assertEquals(expected, ByteUtil.toHexString(result)); - } - - @Test - void deserializePendingFederationOnlyBtcKeys() throws Exception { - byte[][] publicKeyBytes = Arrays.asList(100, 200, 300, 400, 500, 600).stream() - .map(k -> BtcECKey.fromPrivate(BigInteger.valueOf(k))) - .sorted(BtcECKey.PUBKEY_COMPARATOR) - .map(k -> k.getPubKey()) - .toArray(byte[][]::new); - - byte[][] rlpBytes = new byte[publicKeyBytes.length][]; - - for (int k = 0; k < publicKeyBytes.length; k++) { - rlpBytes[k] = RLP.encodeElement(publicKeyBytes[k]); - } - - byte[] data = RLP.encodeList(rlpBytes); - - PendingFederation deserializedPendingFederation = BridgeSerializationUtils.deserializePendingFederationOnlyBtcKeys(data); - - Assertions.assertEquals(6, deserializedPendingFederation.getBtcPublicKeys().size()); - for (int i = 0; i < 6; i++) { - Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedPendingFederation.getBtcPublicKeys().get(i).getPubKey())); - } - } - @Test void serializeElection() throws Exception { AddressBasedAuthorizer authorizer = getTestingAddressBasedAuthorizer(); @@ -1253,9 +1115,6 @@ private void testSerializeAndDeserializeFederation( when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(isRskip284Active); when(activations.isActive(ConsensusRule.RSKIP353)).thenReturn(isRskip353Active); - ErpRedeemScriptBuilder erpRedeemScriptBuilder = - NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, bridgeConstants.getBtcParams()); - for (int i = 0; i < NUM_CASES; i++) { int numMembers = randomInRange(2, 14); List members = new ArrayList<>(); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 2e7d656e7a7..ca33fc44742 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -997,8 +997,8 @@ void getPendingFederation_initialVersion() { } }); - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { - bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.deserializePendingFederationOnlyBtcKeys(any(byte[].class))).then((InvocationOnMock invocation) -> { + try (MockedStatic pendingFederationMocked = mockStatic(PendingFederation.class)) { + pendingFederationMocked.when(() -> PendingFederation.deserializeFromBtcKeys(any(byte[].class))).then((InvocationOnMock invocation) -> { deserializeCalls.add(0); byte[] data = invocation.getArgument(0); // Make sure we're deserializing what just came from the repo with the correct BTC context @@ -1014,7 +1014,7 @@ void getPendingFederation_initialVersion() { @Test void getPendingFederation_initialVersion_nullBytes() { - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { + try (MockedStatic pendingFederationMocked = mockStatic(PendingFederation.class)) { List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); @@ -1042,7 +1042,7 @@ void getPendingFederation_initialVersion_nullBytes() { assertNull(storageProvider.getPendingFederation()); Assertions.assertEquals(2, storageCalls.size()); - bridgeSerializationUtilsMocked.verify(() -> BridgeSerializationUtils.deserializePendingFederation(any(byte[].class)), never()); + pendingFederationMocked.verify(() -> PendingFederation.deserialize(any(byte[].class)), never()); } } @@ -1073,8 +1073,8 @@ void getPendingFederation_multiKeyVersion() { } }); - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { - bridgeSerializationUtilsMocked.when(() -> BridgeSerializationUtils.deserializePendingFederation(any(byte[].class))).then((InvocationOnMock invocation) -> { + try (MockedStatic pendingFederationMocked = mockStatic(PendingFederation.class)) { + pendingFederationMocked.when(() -> PendingFederation.deserialize(any(byte[].class))).then((InvocationOnMock invocation) -> { deserializeCalls.add(0); byte[] data = invocation.getArgument(0); // Make sure we're deserializing what just came from the repo with the correct BTC context @@ -1090,7 +1090,7 @@ void getPendingFederation_multiKeyVersion() { @Test void getPendingFederation_multiKeyVersion_nullBytes() { - try (MockedStatic bridgeSerializationUtilsMocked = mockStatic(BridgeSerializationUtils.class)) { + try (MockedStatic pendingFederationMocked = mockStatic(PendingFederation.class)) { List storageCalls = new ArrayList<>(); Repository repositoryMock = mock(Repository.class); BridgeStorageProvider storageProvider = new BridgeStorageProvider( @@ -1121,7 +1121,7 @@ void getPendingFederation_multiKeyVersion_nullBytes() { assertNull(storageProvider.getPendingFederation()); assertEquals(2, storageCalls.size()); - bridgeSerializationUtilsMocked.verify(() -> BridgeSerializationUtils.deserializePendingFederation(any(byte[].class)), never()); + pendingFederationMocked.verify(() -> PendingFederation.deserialize(any(byte[].class)), never()); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationMemberTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationMemberTest.java index 4c1ecdd7abe..d6c26f2c05e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationMemberTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationMemberTest.java @@ -115,4 +115,12 @@ void keyType_byValueInvalid() { Assertions.fail(); } catch (IllegalArgumentException e) {} } + + @Test + void serializeAndDeserializeFederationMember() { + byte[] serializedMember = member.serialize(); + FederationMember deserializedSerializedMember = FederationMember.deserialize(serializedMember); + + Assertions.assertEquals(deserializedSerializedMember, member); + } } diff --git a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java similarity index 62% rename from rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java rename to rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java index 9aad05d74e7..c36c00bcc07 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package co.rsk.peg; +package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; @@ -24,12 +24,15 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.crypto.Keccak256; -import co.rsk.peg.federation.*; import co.rsk.peg.resources.TestConstants; +import org.ethereum.TestUtils; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; +import org.ethereum.util.ByteUtil; +import org.ethereum.util.RLP; +import org.ethereum.util.RLPList; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -40,6 +43,8 @@ import java.math.BigInteger; import java.time.Instant; +import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -242,11 +247,141 @@ void buildFederation_incomplete() { @Test void getHash() { - byte[] pendingFederationData = pendingFederation.serializeOnlyBtcKeys(); - Keccak256 expectedHash = new Keccak256(HashUtil.keccak256(pendingFederationData)); + Keccak256 expectedHash = new Keccak256("277f35b1c3b742f15eeabb243967794d90a3926d4a4a91cbf9d7d9eceac54a56"); assertEquals(expectedHash, pendingFederation.getHash()); } + @Test + void serializeAndDeserializePendingFederation() { + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + // we want serialization from members + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + + final int NUM_CASES = 20; + + for (int i = 0; i < NUM_CASES; i++) { + int numMembers = randomInRange(2, 14); + List members = new ArrayList<>(); + for (int j = 0; j < numMembers; j++) { + members.add(new FederationMember(new BtcECKey(), new ECKey(), new ECKey())); + } + PendingFederation testPendingFederation = new PendingFederation(members); + + byte[] serializedTestPendingFederation = testPendingFederation.serialize(activations); + PendingFederation deserializedTestPendingFederation = PendingFederation.deserialize(serializedTestPendingFederation); + + Assertions.assertEquals(testPendingFederation, deserializedTestPendingFederation); + } + } + + @Test + void serializePendingFederation_serializedKeysAreCompressedAndThree() { + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + // we want serialization from members + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); + + final int NUM_MEMBERS = 10; + final int EXPECTED_NUM_KEYS = 3; + final int EXPECTED_PUBLICKEY_SIZE = 33; + + List members = new ArrayList<>(); + for (int j = 0; j < NUM_MEMBERS; j++) { + members.add(new FederationMember(new BtcECKey(), new ECKey(), new ECKey())); + } + + PendingFederation testPendingFederation = new PendingFederation(members); + byte[] serializedPendingFederation = testPendingFederation.serialize(activations); + + RLPList memberList = (RLPList) RLP.decode2(serializedPendingFederation).get(0); + Assertions.assertEquals(NUM_MEMBERS, memberList.size()); + + for (int i = 0; i < NUM_MEMBERS; i++) { + RLPList memberKeys = (RLPList) RLP.decode2(memberList.get(i).getRLPData()).get(0); + Assertions.assertEquals(EXPECTED_NUM_KEYS, memberKeys.size()); + for (int j = 0; j < EXPECTED_NUM_KEYS; j++) { + Assertions.assertEquals(EXPECTED_PUBLICKEY_SIZE, memberKeys.get(j).getRLPData().length); + } + + } + } + + @Test + void deserializePendingFederation_invalidFederationMember() { + byte[] serialized = RLP.encodeList( + RLP.encodeList(RLP.encodeElement(new byte[0]), RLP.encodeElement(new byte[0])) + ); + + try { + PendingFederation.deserialize(serialized); + Assertions.fail(); + } catch (RuntimeException e) { + Assertions.assertTrue(e.getMessage().contains("Invalid serialized FederationMember")); + } + } + + @Test + void serializePendingFederationOnlyBtcKeys() throws Exception { + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + // we want serialization from pub keys + when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(false); + + byte[][] publicKeyBytes = new byte[][]{ + BtcECKey.fromPrivate(BigInteger.valueOf(100)).getPubKey(), + BtcECKey.fromPrivate(BigInteger.valueOf(200)).getPubKey(), + BtcECKey.fromPrivate(BigInteger.valueOf(300)).getPubKey(), + BtcECKey.fromPrivate(BigInteger.valueOf(400)).getPubKey(), + BtcECKey.fromPrivate(BigInteger.valueOf(500)).getPubKey(), + BtcECKey.fromPrivate(BigInteger.valueOf(600)).getPubKey(), + }; + + // Only actual keys serialized are BTC keys, so we don't really care about RSK or MST keys + List keys = Arrays.asList(new BtcECKey[]{ + BtcECKey.fromPublicOnly(publicKeyBytes[0]), + BtcECKey.fromPublicOnly(publicKeyBytes[1]), + BtcECKey.fromPublicOnly(publicKeyBytes[2]), + BtcECKey.fromPublicOnly(publicKeyBytes[3]), + BtcECKey.fromPublicOnly(publicKeyBytes[4]), + BtcECKey.fromPublicOnly(publicKeyBytes[5]), + }); + List members = FederationTestUtils.getFederationMembersWithBtcKeys(keys); + PendingFederation pendingFederation = new PendingFederation(members); + + byte[] result = pendingFederation.serialize(activations); + StringBuilder expectedBuilder = new StringBuilder(); + expectedBuilder.append("f8cc"); + pendingFederation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { + expectedBuilder.append("a1"); + expectedBuilder.append(ByteUtil.toHexString(key.getPubKey())); + }); + + String expected = expectedBuilder.toString(); + Assertions.assertEquals(expected, ByteUtil.toHexString(result)); + } + + @Test + void deserializePendingFederationOnlyBtcKeys() throws Exception { + byte[][] publicKeyBytes = Arrays.asList(100, 200, 300, 400, 500, 600).stream() + .map(k -> BtcECKey.fromPrivate(BigInteger.valueOf(k))) + .sorted(BtcECKey.PUBKEY_COMPARATOR) + .map(k -> k.getPubKey()) + .toArray(byte[][]::new); + + byte[][] rlpBytes = new byte[publicKeyBytes.length][]; + + for (int k = 0; k < publicKeyBytes.length; k++) { + rlpBytes[k] = RLP.encodeElement(publicKeyBytes[k]); + } + + byte[] data = RLP.encodeList(rlpBytes); + + PendingFederation deserializedPendingFederation = PendingFederation.deserializeFromBtcKeys(data); + + Assertions.assertEquals(6, deserializedPendingFederation.getBtcPublicKeys().size()); + for (int i = 0; i < 6; i++) { + Assertions.assertTrue(Arrays.equals(publicKeyBytes[i], deserializedPendingFederation.getBtcPublicKeys().get(i).getPubKey())); + } + } + private void testBuildFederation( boolean isRskip201Active, boolean isRskip284Active, @@ -316,4 +451,8 @@ private void testBuildFederation( assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, builtFederation.getRedeemScript()); } } + + private int randomInRange(int min, int max) { + return TestUtils.generateInt(PendingFederationTest.class.toString(),max - min + 1) + min; + } } From fd13e7b59911e45d6040581f2fcc579927194369 Mon Sep 17 00:00:00 2001 From: julia zack Date: Wed, 3 Jan 2024 15:26:25 -0300 Subject: [PATCH 044/137] Create FederationArgs to reduce the amount of fields the Federation constructor receives --- .../co/rsk/config/BridgeDevNetConstants.java | 9 +- .../co/rsk/config/BridgeMainNetConstants.java | 9 +- .../co/rsk/config/BridgeRegTestConstants.java | 9 +- .../co/rsk/config/BridgeTestNetConstants.java | 9 +- .../co/rsk/peg/BridgeSerializationUtils.java | 44 +-- .../co/rsk/peg/federation/ErpFederation.java | 26 +- .../rsk/peg/federation/ErpFederationArgs.java | 35 +++ .../co/rsk/peg/federation/Federation.java | 13 +- .../co/rsk/peg/federation/FederationArgs.java | 21 ++ .../rsk/peg/federation/FederationFactory.java | 53 +--- .../rsk/peg/federation/PendingFederation.java | 57 ++-- .../StandardMultisigFederation.java | 11 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 104 +++---- .../BridgeStorageProviderFederationTests.java | 42 +-- .../co/rsk/peg/BridgeStorageProviderTest.java | 219 ++++++-------- .../peg/BridgeSupportAddSignatureTest.java | 69 ++--- ...ridgeSupportProcessFundsMigrationTest.java | 6 +- ...idgeSupportRegisterBtcTransactionTest.java | 31 +- .../rsk/peg/BridgeSupportReleaseBtcTest.java | 8 +- .../co/rsk/peg/BridgeSupportSigHashTest.java | 19 +- .../java/co/rsk/peg/BridgeSupportTest.java | 134 ++++++--- .../rsk/peg/BridgeSupportTestIntegration.java | 271 +++++++++++------ .../src/test/java/co/rsk/peg/BridgeTest.java | 18 +- .../co/rsk/peg/BridgeUtilsLegacyTest.java | 32 +- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 81 +++-- .../co/rsk/peg/FederationSupportTest.java | 25 +- ...verCompatibleBtcWalletWithStorageTest.java | 24 +- ...patibleBtcWallextWithSingleScriptTest.java | 13 +- .../test/java/co/rsk/peg/PegTestUtils.java | 30 +- .../PegUtilsLegacyGetTransactionTypeTest.java | 49 +-- .../java/co/rsk/peg/PegUtilsLegacyTest.java | 279 +++++++++++------- .../test/java/co/rsk/peg/PegUtilsTest.java | 34 +-- .../test/java/co/rsk/peg/PocSighashTest.java | 42 ++- .../java/co/rsk/peg/PowpegMigrationTest.java | 24 +- .../peg/ReleaseTransactionBuilderTest.java | 31 +- .../peg/federation/FederationFactoryTest.java | 29 +- .../peg/federation/FederationTestUtils.java | 5 +- .../NonStandardErpFederationsTest.java | 62 ++-- .../peg/federation/P2shErpFederationTest.java | 65 ++-- .../peg/federation/PendingFederationTest.java | 35 +-- .../StandardMultisigFederationTest.java | 41 ++- .../peg/performance/ActiveFederationTest.java | 12 +- .../performance/RetiringFederationTest.java | 12 +- .../peg/utils/BridgeEventLoggerImplTest.java | 23 +- .../BridgeEventLoggerLegacyImplTest.java | 19 +- 45 files changed, 1136 insertions(+), 1048 deletions(-) create mode 100644 rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java index e37cd07ddb0..f7fbf2ac168 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeDevNetConstants.java @@ -22,6 +22,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationFactory; import java.time.Instant; @@ -57,12 +58,8 @@ public BridgeDevNetConstants(List federationPublicKeys) { // Expected federation address is: // 2NCEo1RdmGDj6MqiipD6DUSerSxKv79FNWX - genesisFederation = FederationFactory.buildStandardMultiSigFederation( - federationMembers, - genesisFederationAddressCreatedAt, - 1L, - getBtcParams() - ); + FederationArgs federationArgs = new FederationArgs(federationMembers, genesisFederationAddressCreatedAt, 1L, getBtcParams()); + genesisFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); btc2RskMinimumAcceptableConfirmations = 1; btc2RskMinimumAcceptableConfirmationsOnRsk = 10; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java index 1ac54a62c82..97b59c0a6ee 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java @@ -4,6 +4,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationFactory; import com.google.common.collect.Lists; @@ -52,12 +53,8 @@ public class BridgeMainNetConstants extends BridgeConstants { // Wednesday, January 3, 2018 12:00:00 AM GMT-03:00 Instant genesisFederationAddressCreatedAt = Instant.ofEpochMilli(1514948400L); - genesisFederation = FederationFactory.buildStandardMultiSigFederation( - federationMembers, - genesisFederationAddressCreatedAt, - 1L, - getBtcParams() - ); + FederationArgs federationArgs = new FederationArgs(federationMembers, genesisFederationAddressCreatedAt, 1L, getBtcParams()); + genesisFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); btc2RskMinimumAcceptableConfirmations = 100; btc2RskMinimumAcceptableConfirmationsOnRsk = 1000; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java index c3381b45ea6..211f7dbdd6d 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeRegTestConstants.java @@ -22,6 +22,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationFactory; import java.nio.charset.StandardCharsets; @@ -55,12 +56,8 @@ public BridgeRegTestConstants(List federationPublicKeys) { Instant genesisFederationCreatedAt = ZonedDateTime.parse("2016-01-01T00:00:00Z").toInstant(); - genesisFederation = FederationFactory.buildStandardMultiSigFederation( - federationMembers, - genesisFederationCreatedAt, - 1L, - getBtcParams() - ); + FederationArgs federationArgs = new FederationArgs(federationMembers, genesisFederationCreatedAt, 1L, getBtcParams()); + genesisFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); btc2RskMinimumAcceptableConfirmations = 3; btc2RskMinimumAcceptableConfirmationsOnRsk = 5; diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java index 04b72e1a34f..027c4ce9613 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java @@ -22,6 +22,7 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.AddressBasedAuthorizer; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationFactory; import java.time.Instant; @@ -65,12 +66,8 @@ public class BridgeTestNetConstants extends BridgeConstants { // Currently set to: Monday, October 8, 2018 12:00:00 AM GMT-03:00 Instant genesisFederationAddressCreatedAt = Instant.ofEpochMilli(1538967600l); - genesisFederation = FederationFactory.buildStandardMultiSigFederation( - federationMembers, - genesisFederationAddressCreatedAt, - 1L, - getBtcParams() - ); + FederationArgs federationArgs = new FederationArgs(federationMembers, genesisFederationAddressCreatedAt, 1L, getBtcParams()); + genesisFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); btc2RskMinimumAcceptableConfirmations = 10; btc2RskMinimumAcceptableConfirmationsOnRsk = 10; diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 83bc82e6f98..8d179c4e11d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -268,11 +268,9 @@ private static StandardMultisigFederation deserializeStandardMultisigFederationW federationMembers.add(member); } + FederationArgs federationArgs = new FederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters); return FederationFactory.buildStandardMultiSigFederation( - federationMembers, - creationTime, - creationBlockNumber, - networkParameters + federationArgs ); } @@ -325,15 +323,16 @@ public static ErpFederation deserializeLegacyErpFederation( FederationMember::deserialize ); - return FederationFactory.buildNonStandardErpFederation( - federation.getMembers(), - federation.getCreationTime(), - federation.getCreationBlockNumber(), - federation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); + List fedMembers = federation.getMembers(); + Instant creationTime = federation.getCreationTime(); + long creationBlockNumber = federation.getCreationBlockNumber(); + NetworkParameters btcParams = federation.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } public static ErpFederation deserializeP2shErpFederation( @@ -345,14 +344,17 @@ public static ErpFederation deserializeP2shErpFederation( bridgeConstants.getBtcParams(), FederationMember::deserialize ); - return FederationFactory.buildP2shErpFederation( - federation.getMembers(), - federation.getCreationTime(), - federation.getCreationBlockNumber(), - federation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + + List fedMembers = federation.getMembers(); + Instant creationTime = federation.getCreationTime(); + long creationBlockNumber = federation.getCreationBlockNumber(); + NetworkParameters btcParams = federation.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + return FederationFactory.buildP2shErpFederation(erpFederationArgs); } // An ABI call election is serialized as a list of the votes, like so: diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java index c3705088b65..20b889a4996 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java @@ -1,7 +1,6 @@ package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.script.RedeemScriptParser; import co.rsk.bitcoinj.script.RedeemScriptParserFactory; import co.rsk.bitcoinj.script.Script; @@ -10,11 +9,9 @@ import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.RedeemScriptCreationException; import co.rsk.peg.utils.EcKeyUtils; -import java.time.Instant; import java.util.Collections; import java.util.List; -import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; import static co.rsk.peg.federation.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; public class ErpFederation extends Federation { @@ -22,33 +19,20 @@ public class ErpFederation extends Federation { private final long activationDelay; private Script defaultRedeemScript; private Script defaultP2SHScript; - private ErpRedeemScriptBuilder erpRedeemScriptBuilder; + private final ErpRedeemScriptBuilder erpRedeemScriptBuilder; protected ErpFederation( - List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams, - List erpPubKeys, - long activationDelay, + ErpFederationArgs erpFederationArgs, ErpRedeemScriptBuilder erpRedeemScriptBuilder, int formatVersion ) { + super(erpFederationArgs, formatVersion); - super(members, creationTime, creationBlockNumber, btcParams, formatVersion); - validateEmergencyKeys(erpPubKeys); - - this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpPubKeys); - this.activationDelay = activationDelay; + this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpFederationArgs.erpPubKeys); + this.activationDelay = erpFederationArgs.activationDelay; this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; } - private void validateEmergencyKeys(List erpPubKeys) { - if (erpPubKeys == null || erpPubKeys.isEmpty()) { - String message = "Emergency keys are not provided"; - throw new ErpFederationCreationException(message, NULL_OR_EMPTY_EMERGENCY_KEYS); - } - } public ErpRedeemScriptBuilder getErpRedeemScriptBuilder() { return erpRedeemScriptBuilder; } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java new file mode 100644 index 00000000000..d1ea623805b --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java @@ -0,0 +1,35 @@ +package co.rsk.peg.federation; + +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.core.NetworkParameters; + +import java.time.Instant; +import java.util.List; + +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; + +public class ErpFederationArgs extends FederationArgs{ + protected final List erpPubKeys; + protected final long activationDelay; + public ErpFederationArgs( + List members, + Instant creationTime, + long creationBlockNumber, + NetworkParameters btcParams, + List erpPubKeys, + long activationDelay + ) { + super(members, creationTime, creationBlockNumber, btcParams); + + validateEmergencyKeys(erpPubKeys); + this.erpPubKeys = erpPubKeys; + this.activationDelay = activationDelay; + } + + private void validateEmergencyKeys(List erpPubKeys) { + if (erpPubKeys == null || erpPubKeys.isEmpty()) { + String message = "Emergency keys are not provided"; + throw new ErpFederationCreationException(message, NULL_OR_EMPTY_EMERGENCY_KEYS); + } + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java index 9949bdfa928..7609e1bd12c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java @@ -50,19 +50,16 @@ public abstract class Federation { protected Address address; protected Federation( - List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams, + FederationArgs federationArgs, int formatVersion ) { // Sorting members ensures same order of federation members for same members // Immutability provides protection against unwanted modification, thus making the Federation instance // effectively immutable - this.members = Collections.unmodifiableList(members.stream().sorted(FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR).collect(Collectors.toList())); - this.creationTime = creationTime.truncatedTo(ChronoUnit.MILLIS); - this.creationBlockNumber = creationBlockNumber; - this.btcParams = btcParams; + this.members = Collections.unmodifiableList(federationArgs.members.stream().sorted(FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR).collect(Collectors.toList())); + this.creationTime = federationArgs.creationTime.truncatedTo(ChronoUnit.MILLIS); + this.creationBlockNumber = federationArgs.creationBlockNumber; + this.btcParams = federationArgs.btcParams; this.formatVersion = formatVersion; } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java new file mode 100644 index 00000000000..aed980038d1 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java @@ -0,0 +1,21 @@ +package co.rsk.peg.federation; + +import co.rsk.bitcoinj.core.NetworkParameters; + +import java.time.Instant; +import java.util.List; + +public class FederationArgs { + protected final List members; + protected final Instant creationTime; + protected final long creationBlockNumber; + protected final NetworkParameters btcParams; + + public FederationArgs(List members, Instant creationTime, + long creationBlockNumber, NetworkParameters btcParams) { + this.members = members; + this.creationTime = creationTime; + this.creationBlockNumber = creationBlockNumber; + this.btcParams = btcParams; + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java index 8d1760b3149..8b60489d600 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java @@ -1,74 +1,37 @@ package co.rsk.peg.federation; -import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import java.time.Instant; -import java.util.List; - import static co.rsk.peg.federation.FederationFormatVersion.*; public class FederationFactory { private FederationFactory() {} - public static StandardMultisigFederation buildStandardMultiSigFederation(List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams) { + public static StandardMultisigFederation buildStandardMultiSigFederation(FederationArgs federationArgs) { return new StandardMultisigFederation( - members, - creationTime, - creationBlockNumber, - btcParams, + federationArgs, STANDARD_MULTISIG_FEDERATION.getFormatVersion() ); } - public static ErpFederation buildNonStandardErpFederation(List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams, - List erpPubKeys, - long activationDelay, - ActivationConfig.ForBlock activations) { + public static ErpFederation buildNonStandardErpFederation(ErpFederationArgs erpFederationArgs, + ActivationConfig.ForBlock activations) { + NetworkParameters btcParams = erpFederationArgs.btcParams; ErpRedeemScriptBuilder erpRedeemScriptBuilder = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, btcParams); - return new ErpFederation( - members, - creationTime, - creationBlockNumber, - btcParams, - erpPubKeys, - activationDelay, - erpRedeemScriptBuilder, - NON_STANDARD_ERP_FEDERATION.getFormatVersion() + return new ErpFederation(erpFederationArgs, erpRedeemScriptBuilder, NON_STANDARD_ERP_FEDERATION.getFormatVersion() ); } - public static ErpFederation buildP2shErpFederation(List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams, - List erpPubKeys, - long activationDelay) { - + public static ErpFederation buildP2shErpFederation(ErpFederationArgs erpFederationArgs) { ErpRedeemScriptBuilder erpRedeemScriptBuilder = new P2shErpRedeemScriptBuilder(); - return new ErpFederation( - members, - creationTime, - creationBlockNumber, - btcParams, - erpPubKeys, - activationDelay, - erpRedeemScriptBuilder, - P2SH_ERP_FEDERATION.getFormatVersion() + return new ErpFederation(erpFederationArgs, erpRedeemScriptBuilder, P2SH_ERP_FEDERATION.getFormatVersion() ); } - } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index a3f52277c4d..b98fe67438a 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -19,6 +19,7 @@ package co.rsk.peg.federation; import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.config.BridgeConstants; import co.rsk.crypto.Keccak256; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -97,47 +98,41 @@ public PendingFederation addMember(FederationMember member) { * @return a Federation */ public Federation buildFederation( - Instant creationTime, - long blockNumber, - BridgeConstants bridgeConstants, - ActivationConfig.ForBlock activations + Instant creationTime, + long blockNumber, + BridgeConstants bridgeConstants, + ActivationConfig.ForBlock activations ) { if (!this.isComplete()) { throw new IllegalStateException("PendingFederation is incomplete"); } - if (activations.isActive(ConsensusRule.RSKIP353)) { - logger.info("[buildFederation] Going to create a P2SH ERP Federation"); - return FederationFactory.buildP2shErpFederation( - members, - creationTime, - blockNumber, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + if (shouldBuildStandardMultisigFederation(activations)){ + FederationArgs federationArgs = new FederationArgs(members, creationTime, blockNumber, btcParams); + return FederationFactory.buildStandardMultiSigFederation(federationArgs); } - if (activations.isActive(ConsensusRule.RSKIP201)) { + // should build and erp federation due to activations + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(members, creationTime, blockNumber, btcParams, erpPubKeys, activationDelay); + if (shouldBuildNonStandardErpFederation(activations)) { logger.info("[buildFederation] Going to create an ERP Federation"); - - return FederationFactory.buildNonStandardErpFederation( - members, - creationTime, - blockNumber, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); + return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } - return FederationFactory.buildStandardMultiSigFederation( - members, - creationTime, - blockNumber, - bridgeConstants.getBtcParams() - ); + logger.info("[buildFederation] Going to create a P2SH ERP Federation"); + return FederationFactory.buildP2shErpFederation(erpFederationArgs); + } + + private boolean shouldBuildStandardMultisigFederation(ActivationConfig.ForBlock activations) { + return !activations.isActive(ConsensusRule.RSKIP201); + } + + private boolean shouldBuildNonStandardErpFederation(ActivationConfig.ForBlock activations) { + return !activations.isActive(ConsensusRule.RSKIP353); } @Override diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java index 8182684a5e9..839f51f3c11 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/StandardMultisigFederation.java @@ -18,14 +18,10 @@ package co.rsk.peg.federation; -import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptBuilder; import co.rsk.peg.bitcoin.ScriptValidations; -import java.time.Instant; -import java.util.List; - /** * Immutable representation of an RSK Federation in the context of * a specific BTC network. @@ -35,13 +31,10 @@ public class StandardMultisigFederation extends Federation { protected StandardMultisigFederation( - List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams, + FederationArgs federationArgs, int formatVersion) { - super(members, creationTime, creationBlockNumber, btcParams, formatVersion); + super(federationArgs, formatVersion); validateRedeemScriptSize(); } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 3f5e7ee95de..8362cd83abb 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -152,19 +152,25 @@ void serializeFederationOnlyBtcKeys() throws Exception { }; // Only actual keys serialized are BTC keys, so we don't really care about RSK or MST keys - Federation federation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList(new BtcECKey[]{ - BtcECKey.fromPublicOnly(publicKeyBytes[0]), - BtcECKey.fromPublicOnly(publicKeyBytes[1]), - BtcECKey.fromPublicOnly(publicKeyBytes[2]), - BtcECKey.fromPublicOnly(publicKeyBytes[3]), - BtcECKey.fromPublicOnly(publicKeyBytes[4]), - BtcECKey.fromPublicOnly(publicKeyBytes[5]), - })), - Instant.ofEpochMilli(0xabcdef), // - 42L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + List members = FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList(new BtcECKey[]{ + BtcECKey.fromPublicOnly(publicKeyBytes[0]), + BtcECKey.fromPublicOnly(publicKeyBytes[1]), + BtcECKey.fromPublicOnly(publicKeyBytes[2]), + BtcECKey.fromPublicOnly(publicKeyBytes[3]), + BtcECKey.fromPublicOnly(publicKeyBytes[4]), + BtcECKey.fromPublicOnly(publicKeyBytes[5]), + })); + Instant creationTime = Instant.ofEpochMilli(0xabcdef); + long creationBlockNumber = 42L; + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + + FederationArgs federationArgs = new FederationArgs( + members, + creationTime, + creationBlockNumber, + btcParams ); + Federation federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); byte[] result = BridgeSerializationUtils.serializeFederationOnlyBtcKeys(federation); StringBuilder expectedBuilder = new StringBuilder(); @@ -303,18 +309,19 @@ void serializeFederation_serializedKeysAreCompressedAndThree() { members.add(new FederationMember(new BtcECKey(), new ECKey(), new ECKey())); } - Federation testFederation = FederationFactory.buildStandardMultiSigFederation( - members, Instant.now(), 123, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); + Instant creationTime = Instant.now(); + long creationBlockNumber = 123; + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs federationArgs = + new FederationArgs(members, creationTime, creationBlockNumber, btcParams); + Federation testFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); byte[] serializedFederation = BridgeSerializationUtils.serializeFederation(testFederation); RLPList serializedList = (RLPList) RLP.decode2(serializedFederation).get(0); - Assertions.assertEquals(3, serializedList.size()); RLPList memberList = (RLPList) serializedList.get(2); - Assertions.assertEquals(NUM_MEMBERS, memberList.size()); for (int i = 0; i < NUM_MEMBERS; i++) { @@ -653,7 +660,8 @@ void serializeDeserializeOneOffLockWhitelistAndDisableBlockHeight() { @Test void serializeAndDeserializeFederationOnlyBtcKeysWithRealRLP() { - NetworkParameters networkParms = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + NetworkParameters networkParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + byte[][] publicKeyBytes = new byte[][]{ BtcECKey.fromPrivate(BigInteger.valueOf(100)).getPubKey(), BtcECKey.fromPrivate(BigInteger.valueOf(200)).getPubKey(), @@ -664,22 +672,20 @@ void serializeAndDeserializeFederationOnlyBtcKeysWithRealRLP() { }; // Only actual keys serialized are BTC keys, so deserialization will fill RSK and MST keys with those - Federation federation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithKeys(Arrays.asList( - BtcECKey.fromPublicOnly(publicKeyBytes[0]), - BtcECKey.fromPublicOnly(publicKeyBytes[1]), - BtcECKey.fromPublicOnly(publicKeyBytes[2]), - BtcECKey.fromPublicOnly(publicKeyBytes[3]), - BtcECKey.fromPublicOnly(publicKeyBytes[4]), - BtcECKey.fromPublicOnly(publicKeyBytes[5]) - )), - Instant.ofEpochMilli(0xabcdef), - 42L, - networkParms - ); + List members = FederationTestUtils.getFederationMembersWithKeys(Arrays.asList( + BtcECKey.fromPublicOnly(publicKeyBytes[0]), + BtcECKey.fromPublicOnly(publicKeyBytes[1]), + BtcECKey.fromPublicOnly(publicKeyBytes[2]), + BtcECKey.fromPublicOnly(publicKeyBytes[3]), + BtcECKey.fromPublicOnly(publicKeyBytes[4]), + BtcECKey.fromPublicOnly(publicKeyBytes[5]) + )); + FederationArgs federationArgs = new FederationArgs(members, Instant.ofEpochMilli(0xabcdef), 42L, + networkParams); + Federation federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); byte[] result = BridgeSerializationUtils.serializeFederationOnlyBtcKeys(federation); - Federation deserializedFederation = BridgeSerializationUtils.deserializeStandardMultisigFederationOnlyBtcKeys(result, networkParms); + Federation deserializedFederation = BridgeSerializationUtils.deserializeStandardMultisigFederationOnlyBtcKeys(result, networkParams); MatcherAssert.assertThat(federation, is(deserializedFederation)); } @@ -1123,12 +1129,13 @@ private void testSerializeAndDeserializeFederation( members.add(new FederationMember(new BtcECKey(), new ECKey(), new ECKey())); } - Federation testFederation = FederationFactory.buildStandardMultiSigFederation( - members, - Instant.now(), - 123, - bridgeConstants.getBtcParams() - ); + Instant creationTime = Instant.now(); + long creationBlockNumber = 123; + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + FederationArgs federationArgs = + new FederationArgs(members, creationTime, creationBlockNumber, btcParams); + Federation testFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); byte[] serializedTestFederation = BridgeSerializationUtils.serializeFederation(testFederation); Federation deserializedTestFederation = BridgeSerializationUtils.deserializeStandardMultisigFederation( @@ -1136,13 +1143,13 @@ private void testSerializeAndDeserializeFederation( bridgeConstants.getBtcParams() ); - Federation testErpFederation = FederationFactory.buildNonStandardErpFederation( - members, - Instant.now(), - 123, - bridgeConstants.getBtcParams(), + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(members, creationTime, creationBlockNumber, btcParams, bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), + bridgeConstants.getErpFedActivationDelay() + ); + Federation testErpFederation = FederationFactory.buildNonStandardErpFederation( + erpFederationArgs, activations ); byte[] serializedTestErpFederation = BridgeSerializationUtils.serializeFederation(testErpFederation); @@ -1163,14 +1170,7 @@ private void testSerializeAndDeserializeFederation( } if (isRskip353Active) { - Federation testP2shErpFederation = FederationFactory.buildP2shErpFederation( - members, - Instant.now(), - 123, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + Federation testP2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); byte[] serializedTestP2shErpFederation = BridgeSerializationUtils.serializeFederation(testP2shErpFederation); Federation deserializedTestP2shErpFederation = BridgeSerializationUtils.deserializeP2shErpFederation( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index ba206006424..2efe898ad8b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -10,6 +10,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import co.rsk.bitcoinj.core.BtcECKey; +import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.config.BridgeConstants; import java.io.IOException; import java.time.Instant; @@ -603,42 +605,24 @@ private Federation createFederation(int version) { List members = FederationMember.getFederationMembersFromKeys( PegTestUtils.createRandomBtcECKeys(7) ); + NetworkParameters btcParams = bridgeConstantsRegtest.getBtcParams(); + FederationArgs federationArgs = new FederationArgs(members, Instant.now(), 1L, btcParams); if (version == STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION) { - return FederationFactory.buildStandardMultiSigFederation( - members, - Instant.now(), - 1L, - bridgeConstantsRegtest.getBtcParams() - ); + return FederationFactory.buildStandardMultiSigFederation(federationArgs); } + + List erpPubKeys = bridgeConstantsRegtest.getErpFedPubKeysList(); + long activationDelay = bridgeConstantsRegtest.getErpFedActivationDelay(); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(members, Instant.now(), 1L, btcParams, + erpPubKeys, activationDelay); if (version == NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) { - return FederationFactory.buildNonStandardErpFederation( - members, - Instant.now(), - 1L, - bridgeConstantsRegtest.getBtcParams(), - bridgeConstantsRegtest.getErpFedPubKeysList(), - bridgeConstantsRegtest.getErpFedActivationDelay(), - activations - ); + return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } if (version == P2SH_ERP_FEDERATION_FORMAT_VERSION) { - return FederationFactory.buildP2shErpFederation( - members, - Instant.now(), - 1L, - bridgeConstantsRegtest.getBtcParams(), - bridgeConstantsRegtest.getErpFedPubKeysList(), - bridgeConstantsRegtest.getErpFedActivationDelay() - ); + return FederationFactory.buildP2shErpFederation(erpFederationArgs); } // To keep backwards compatibility - return FederationFactory.buildStandardMultiSigFederation( - members, - Instant.now(), - 1L, - bridgeConstantsRegtest.getBtcParams() - ); + return FederationFactory.buildStandardMultiSigFederation(federationArgs); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index ca33fc44742..7739c5cae06 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -402,36 +402,24 @@ void getNewFederation_multiKeyVersion() { } @Test - void getNewFederation_erp_fed() { - BridgeConstants bridgeConstants = bridgeTestnetInstance; - Federation newFederation = buildMockFederation(100, 200, 300); + void getNewFederation_erp_and_p2sh_erp_feds() { ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); + Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( - newFederation.getMembers(), - newFederation.getCreationTime(), - newFederation.getCreationBlockNumber(), - newFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); - - testGetNewFederationPostMultiKey(erpFederation); - } + List fedMembers = newFederation.getMembers(); + Instant creationTime = newFederation.getCreationTime(); + long creationBlockNumber = newFederation.getCreationBlockNumber(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); - @Test - void getNewFederation_p2sh_erp_fed() { - Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation( - newFederation.getMembers(), - newFederation.getCreationTime(), - newFederation.getCreationBlockNumber(), - newFederation.getBtcParams(), - bridgeTestnetInstance.getErpFedPubKeysList(), - bridgeTestnetInstance.getErpFedActivationDelay() - ); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + testGetNewFederationPostMultiKey(erpFederation); testGetNewFederationPostMultiKey(p2shErpFederation); } @@ -543,36 +531,38 @@ void saveNewFederation_postMultiKey() { @Test void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); + Federation newFederation = buildMockFederation(100, 200, 300); + List fedMembers = newFederation.getMembers(); + Instant creationTime = newFederation.getCreationTime(); + long creationBlockNumber = newFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - Federation newFederation = buildMockFederation(100, 200, 300); + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( - newFederation.getMembers(), - newFederation.getCreationTime(), - newFederation.getCreationBlockNumber(), - newFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); testSaveNewFederationPostMultiKey(erpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); } @Test void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { - BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation newFederation = buildMockFederation(100, 200, 300); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation( - newFederation.getMembers(), - newFederation.getCreationTime(), - newFederation.getCreationBlockNumber(), - newFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + List fedMembers = newFederation.getMembers(); + Instant creationTime = newFederation.getCreationTime(); + long creationBlockNumber = newFederation.getCreationBlockNumber(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); testSaveNewFederationPostMultiKey(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activationsAllForks); } @@ -675,81 +665,51 @@ void getOldFederation_multiKeyVersion() { } @Test - void getOldFederation_nonStandardHardcoded_fed() { - BridgeConstants bridgeConstants = bridgeTestnetInstance; + void getOldFederation_nonStandard_feds() { Federation oldFederation = buildMockFederation(100, 200, 300); - - ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); - - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( - oldFederation.getMembers(), - oldFederation.getCreationTime(), - oldFederation.getCreationBlockNumber(), - oldFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); - - testGetOldFederation(erpFederation, activations); - } - - @Test - void getOldFederation_nonStandardWithUnsignedBE_fed() { + List fedMembers = oldFederation.getMembers(); + Instant creationTime = oldFederation.getCreationTime(); + long creationBlockNumber = oldFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - Federation oldFederation = buildMockFederation(100, 200, 300); + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); - List rulesToDisable = Arrays.asList(ConsensusRule.RSKIP293); - ActivationConfig.ForBlock activations = ActivationConfigsForTest.hop400(rulesToDisable).forBlock(0); - - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( - oldFederation.getMembers(), - oldFederation.getCreationTime(), - oldFederation.getCreationBlockNumber(), - oldFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + // this should get non-standard hardcoded fed + ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); testGetOldFederation(erpFederation, activations); - } - - @Test - void getOldFederation_nonStandard_fed() { - BridgeConstants bridgeConstants = bridgeTestnetInstance; - Federation oldFederation = buildMockFederation(100, 200, 300); - - ActivationConfig.ForBlock activations = ActivationConfigsForTest.hop400().forBlock(0); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( - oldFederation.getMembers(), - oldFederation.getCreationTime(), - oldFederation.getCreationBlockNumber(), - oldFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); + // this should get non-standard with csv unsigned BE fed + erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + testGetOldFederation(erpFederation, activations); + // this should get non-standard fed + activations = ActivationConfigsForTest.hop400().forBlock(0); + erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); testGetOldFederation(erpFederation, activations); } @Test void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { - BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); - ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation( - oldFederation.getMembers(), - oldFederation.getCreationTime(), - oldFederation.getCreationBlockNumber(), - oldFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + List fedMembers = oldFederation.getMembers(); + Instant creationTime = oldFederation.getCreationTime(); + long creationBlockNumber = oldFederation.getCreationBlockNumber(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); testGetOldFederation(p2shErpFederation, activations); } @@ -861,35 +821,38 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( - oldFederation.getMembers(), - oldFederation.getCreationTime(), - oldFederation.getCreationBlockNumber(), - oldFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); + List fedMembers = oldFederation.getMembers(); + Instant creationTime = oldFederation.getCreationTime(); + long creationBlockNumber = oldFederation.getCreationBlockNumber(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); testSaveOldFederation(erpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); } @Test void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { - BridgeConstants bridgeConstants = bridgeTestnetInstance; Federation oldFederation = buildMockFederation(100, 200, 300); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation( - oldFederation.getMembers(), - oldFederation.getCreationTime(), - oldFederation.getCreationBlockNumber(), - oldFederation.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + List fedMembers = oldFederation.getMembers(); + Instant creationTime = oldFederation.getCreationTime(); + long creationBlockNumber = oldFederation.getCreationBlockNumber(); + BridgeConstants bridgeConstants = bridgeTestnetInstance; + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, + erpPubKeys, activationDelay); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); testSaveOldFederation(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activationsAllForks); } @@ -3893,12 +3856,10 @@ private Address getBtcAddress(String addr) { } private Federation buildMockFederation(Integer... pks) { - return FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersFromPks(pks), + FederationArgs federationArgs = new FederationArgs(FederationTestUtils.getFederationMembersFromPks(pks), Instant.ofEpochMilli(1000), - 1, - networkParameters - ); + 1, networkParameters); + return FederationFactory.buildStandardMultiSigFederation(federationArgs); } private PendingFederation buildMockPendingFederation(Integer... pks) { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index 58d3a847f45..d1775014b4c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -5,9 +5,7 @@ import java.util.*; import co.rsk.config.BridgeConstants; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationTestUtils; +import co.rsk.peg.federation.*; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; @@ -58,6 +56,8 @@ class BridgeSupportAddSignatureTest { private BridgeSupportBuilder bridgeSupportBuilder; private final BridgeConstants bridgeConstantsRegtest = BridgeRegTestConstants.getInstance(); private final NetworkParameters btcRegTestParams = bridgeConstantsRegtest.getBtcParams(); + private final Instant creationTime = Instant.ofEpochMilli(1000L); + private final long creationBlockNumber = 0L; @BeforeEach void setUpOnEachTest() { @@ -72,18 +72,16 @@ void addSignature_fedPubKey_belongs_to_active_federation() throws Exception { FederationSupport mockFederationSupport = mock(FederationSupport.class); // Creates new federation - List federation1Keys = Arrays.asList( + List activeFedKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ); - federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); + activeFedKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), - Instant.ofEpochMilli(1000L), - 0L, - btcRegTestParams - ); + List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFedKeys); + FederationArgs activeFedArgs = + new FederationArgs(activeFedMembers, creationTime, creationBlockNumber, btcRegTestParams); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation(activeFedArgs); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); BridgeSupport bridgeSupport = new BridgeSupport( @@ -131,17 +129,15 @@ void addSignature_fedPubKey_belongs_to_retiring_federation() throws Exception { ); // Creates retiring federation - List federation1Keys = Arrays.asList( + List retiringFedKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02"))); - federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); + retiringFedKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), - Instant.ofEpochMilli(1000L), - 0L, - btcRegTestParams - ); + List retiringFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedKeys); + FederationArgs retiringFedArgs = + new FederationArgs(retiringFedMembers, creationTime, creationBlockNumber, btcRegTestParams); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation(retiringFedArgs); // Creates active federation List activeFederationKeys = Arrays.asList( @@ -149,13 +145,10 @@ void addSignature_fedPubKey_belongs_to_retiring_federation() throws Exception { BtcECKey.fromPrivate(Hex.decode("fa04")) ); activeFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - btcRegTestParams - ); + List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); + FederationArgs activeFedArgs = + new FederationArgs(activeFedMembers, creationTime, creationBlockNumber, btcRegTestParams); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation(activeFedArgs); when(mockFederationSupport.getActiveFederation()).thenReturn(activeFederation); when(mockFederationSupport.getRetiringFederation()).thenReturn(retiringFederation); @@ -188,18 +181,15 @@ void addSignature_fedPubKey_no_belong_to_retiring_or_active_federation() throws ); // Creates retiring federation - List federation1Keys = Arrays.asList( + List retiringFedKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ); - federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), - Instant.ofEpochMilli(1000L), - 0L, - btcRegTestParams - ); + retiringFedKeys.sort(BtcECKey.PUBKEY_COMPARATOR); + List retiringFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedKeys); + FederationArgs retiringFedArgs = + new FederationArgs(retiringFedMembers, creationTime, creationBlockNumber, btcRegTestParams); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation(retiringFedArgs); // Creates active federation List activeFederationKeys = Arrays.asList( @@ -208,11 +198,10 @@ void addSignature_fedPubKey_no_belong_to_retiring_or_active_federation() throws ); activeFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - btcRegTestParams); + List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); + FederationArgs activeFedArgs = + new FederationArgs(activeFedMembers, creationTime, creationBlockNumber, btcRegTestParams); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation(activeFedArgs); when(mockFederationSupport.getActiveFederation()).thenReturn(activeFederation); when(mockFederationSupport.getRetiringFederation()).thenReturn(retiringFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java index a7c5a4ac571..b6d4563c41b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportProcessFundsMigrationTest.java @@ -8,6 +8,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.utils.BridgeEventLogger; @@ -130,12 +131,15 @@ void test_processFundsMigration( federationActivationAge + bridgeConstants.getFundsMigrationAgeSinceActivationEnd(activations) + 1; - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs newFederationArgs = new FederationArgs( FederationTestUtils.getFederationMembers(1), Instant.EPOCH, federationCreationBlockNumber, bridgeConstants.getBtcParams() ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs + ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Collections.emptyList())); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index f03332e42de..a5b77540b21 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -12,9 +12,7 @@ import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.bitcoin.CoinbaseInformation; import co.rsk.peg.btcLockSender.BtcLockSenderProvider; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationTestUtils; +import co.rsk.peg.federation.*; import co.rsk.peg.pegin.RejectedPeginReason; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; @@ -343,6 +341,7 @@ void init() throws IOException { registerHeader = null; userAddress = BitcoinTestUtils.createP2PKHAddress(btcMainnetParams, "userAddress"); + NetworkParameters btcParams = bridgeMainnetConstants.getBtcParams(); retiredFedSigners = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true @@ -354,27 +353,21 @@ void init() throws IOException { ); retiringFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); - retiringFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedSigners), - Instant.ofEpochMilli(1000L), - 1, - bridgeMainnetConstants.getBtcParams(), - bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay() - ); + List retiringFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedSigners); + List erpPubKeys = bridgeMainnetConstants.getErpFedPubKeysList(); + long activationDelay = bridgeMainnetConstants.getErpFedActivationDelay(); + ErpFederationArgs retiringFedArgs = new ErpFederationArgs(retiringFedMembers, Instant.ofEpochMilli(1000L), 1, btcParams, + erpPubKeys, activationDelay); + retiringFederation = FederationFactory.buildP2shErpFederation(retiringFedArgs); activeFedSigners = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa07", "fa08", "fa09", "fa10", "fa11"}, true ); activeFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); - activeFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFedSigners), - Instant.ofEpochMilli(1000L), - 2L, - bridgeMainnetConstants.getBtcParams(), - bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay() - ); + List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFedSigners); + ErpFederationArgs activeFedArgs = new ErpFederationArgs(activeFedMembers, Instant.ofEpochMilli(1000L), 2L, btcParams, + erpPubKeys, activationDelay); + activeFederation = FederationFactory.buildP2shErpFederation(activeFedArgs); mockFactory = mock(BtcBlockStoreWithCache.Factory.class); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java index 8e70a97bd41..5a0d41e0027 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -26,6 +26,7 @@ import co.rsk.db.MutableTrieImpl; import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.utils.BridgeEventLogger; @@ -1253,12 +1254,11 @@ private static Repository createRepository() { } private static Federation getFederation() { - return FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(3), + FederationArgs federationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); + NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); + return FederationFactory.buildStandardMultiSigFederation(federationArgs); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java index 16dc0f3abb8..f2aa5fc235c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportSigHashTest.java @@ -12,6 +12,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.peg.bitcoin.BitcoinUtils; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.federation.FederationTestUtils; import co.rsk.test.builders.BridgeSupportBuilder; @@ -124,12 +125,10 @@ void test_pegoutTxIndex_when_migration_tx_is_created(ActivationConfig.ForBlock a Federation oldFederation = bridgeMainnetConstants.getGenesisFederation(); long newFedCreationBlockNumber = 5L; - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), - Instant.EPOCH, - newFedCreationBlockNumber, - btcMainnetParams - ); + + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), + Instant.EPOCH, newFedCreationBlockNumber, btcMainnetParams); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation(newFederationArgs); when(provider.getOldFederation()) .thenReturn(oldFederation); when(provider.getNewFederation()) @@ -193,12 +192,10 @@ void test_pegoutTxIndex_when_migration_and_pegout_batch_tx_are_created(Activatio Federation oldFederation = bridgeMainnetConstants.getGenesisFederation(); long newFedCreationBlockNumber = 5L; + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), + Instant.EPOCH, newFedCreationBlockNumber, btcMainnetParams); Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), - Instant.EPOCH, - newFedCreationBlockNumber, - btcMainnetParams - ); + newFederationArgs); when(provider.getOldFederation()) .thenReturn(oldFederation); when(provider.getNewFederation()) 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 5a40e4744e4..1589b2742e3 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -960,6 +960,7 @@ void registerBtcTransactionLockTxNotWhitelisted_before_rskip_146_activation() th ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(false); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); BridgeEventLogger bridgeEventLogger = mock(BridgeEventLogger.class); //Creates federation 1 @@ -968,11 +969,14 @@ void registerBtcTransactionLockTxNotWhitelisted_before_rskip_146_activation() th BtcECKey.fromPrivate(Hex.decode("fa02")) ); - Federation federation1 = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federation1Args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + btcParams + ); + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( + federation1Args ); //Creates federation 2 @@ -981,11 +985,14 @@ void registerBtcTransactionLockTxNotWhitelisted_before_rskip_146_activation() th BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03"))); - Federation federation2 = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federation2Args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), Instant.ofEpochMilli(2000L), 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + btcParams + ); + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( + federation2Args ); Repository repository = createRepository(); @@ -1130,6 +1137,7 @@ void registerBtcTransactionLockTxNotWhitelisted_after_rskip_146_activation() thr ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); BridgeEventLogger bridgeEventLogger = mock(BridgeEventLogger.class); //Creates federation 1 @@ -1138,11 +1146,13 @@ void registerBtcTransactionLockTxNotWhitelisted_after_rskip_146_activation() thr BtcECKey.fromPrivate(Hex.decode("fa02")) ); - Federation federation1 = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), + FederationArgs federation1Args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), Instant.ofEpochMilli(1000L), 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + btcParams + ); + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( + federation1Args ); //Creates federation 2 @@ -1151,11 +1161,13 @@ void registerBtcTransactionLockTxNotWhitelisted_after_rskip_146_activation() thr BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03"))); - Federation federation2 = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), + FederationArgs federation2Args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), Instant.ofEpochMilli(2000L), 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + btcParams + ); + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( + federation2Args ); Repository repository = createRepository(); @@ -1322,11 +1334,13 @@ void registerBtcTransaction_sending_segwit_tx_twice_locks_just_once() throws Blo BtcECKey.fromPrivate(Hex.decode("fa02")) ); - Federation fed = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), + FederationArgs federationArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), Instant.ofEpochMilli(1000L), 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + btcRegTestParams + ); + Federation fed = FederationFactory.buildStandardMultiSigFederation( + federationArgs ); txWithWitness.addOutput(Coin.COIN.multiply(5), fed.getAddress()); @@ -1414,11 +1428,13 @@ void callProcessFundsMigration_is_migrating_before_rskip_146_activation() throws Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, - bridgeConstantsRegtest.getBtcParams() + btcRegTestParams + ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); @@ -1477,11 +1493,13 @@ void callProcessFundsMigration_is_migrating_after_rskip_146_activation() throws Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, - bridgeConstantsRegtest.getBtcParams() + btcRegTestParams + ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); @@ -1542,11 +1560,13 @@ void callProcessFundsMigration_is_migrated_before_rskip_146_activation() throws Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, - bridgeConstantsRegtest.getBtcParams() + btcRegTestParams + ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); @@ -1605,11 +1625,13 @@ void callProcessFundsMigration_is_migrated_after_rskip_146_activation() throws I Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, - bridgeConstantsRegtest.getBtcParams() + btcRegTestParams + ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); @@ -1669,11 +1691,13 @@ void updateFederationCreationBlockHeights_before_rskip_186_activation() throws I Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, - bridgeConstantsRegtest.getBtcParams() + btcRegTestParams + ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); @@ -1732,11 +1756,13 @@ void updateFederationCreationBlockHeights_after_rskip_186_activation() throws IO Federation oldFederation = bridgeConstantsRegtest.getGenesisFederation(); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, - bridgeConstantsRegtest.getBtcParams() + btcRegTestParams + ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); @@ -2113,12 +2139,14 @@ void rskTxWaitingForSignature_fail_adding_an_already_existing_key_after_rskip_37 // Set state to make concur a pegout migration tx and pegout batch creation on the same updateCollection Federation oldFederation = bridgeConstants.getGenesisFederation(); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(1), + FederationArgs newFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(1), Instant.EPOCH, 5L, bridgeConstants.getBtcParams() ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs + ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); @@ -6405,21 +6433,23 @@ private void test_migrating_many_utxos(boolean isRskip294Active, int utxosToCrea oldFedMembers.add(FederationMember.getFederationMemberFromKey(new BtcECKey())); } - Federation oldFed = FederationFactory.buildStandardMultiSigFederation( - oldFedMembers, + FederationArgs oldFedArgs = new FederationArgs(oldFedMembers, Instant.now(), 0, btcRegTestParams ); + Federation oldFed = FederationFactory.buildStandardMultiSigFederation( + oldFedArgs + ); + + List newFedMembers = Arrays.asList( + FederationMember.getFederationMemberFromKey(new BtcECKey()), + FederationMember.getFederationMemberFromKey(new BtcECKey()), + FederationMember.getFederationMemberFromKey(new BtcECKey()) + ); + FederationArgs newFedArgs = new FederationArgs(newFedMembers, Instant.now(), 1, btcRegTestParams); Federation newFed = FederationFactory.buildStandardMultiSigFederation( - Arrays.asList( - FederationMember.getFederationMemberFromKey(new BtcECKey()), - FederationMember.getFederationMemberFromKey(new BtcECKey()), - FederationMember.getFederationMemberFromKey(new BtcECKey()) - ), - Instant.now(), - 1, - btcRegTestParams + newFedArgs ); Block block = mock(Block.class); @@ -6563,14 +6593,16 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ when(preRSKIP271_activations.isActive(ConsensusRule.RSKIP271)).thenReturn(false); when(preRSKIP271_activations.isActive(ConsensusRule.RSKIP385)).thenReturn(false); - Federation p2shFed = FederationFactory.buildP2shErpFederation( - members, + ErpFederationArgs p2shFedArgs = new ErpFederationArgs(members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay() ); + Federation p2shFed = FederationFactory.buildP2shErpFederation( + p2shFedArgs + ); Stream preRskip271 = Stream.of( // active fed is standard and pegoutRequestsCount is equal to zero @@ -6630,14 +6662,16 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ when(preRSKIP385_activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); when(preRSKIP385_activations.isActive(ConsensusRule.RSKIP385)).thenReturn(false); - Federation p2shFed = FederationFactory.buildP2shErpFederation( - members, + ErpFederationArgs p2shFedArgs = new ErpFederationArgs(members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay() ); + Federation p2shFed = FederationFactory.buildP2shErpFederation( + p2shFedArgs + ); Stream preRskip385 = Stream.of( // active fed is standard and pegoutRequestsCount is equal to zero @@ -6696,14 +6730,16 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ PegTestUtils.createRandomBtcECKeys(7) ); - ErpFederation p2shFed = FederationFactory.buildP2shErpFederation( - members, + ErpFederationArgs p2shFedArgs = new ErpFederationArgs(members, Instant.now(), 1L, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay() ); + ErpFederation p2shFed = FederationFactory.buildP2shErpFederation( + p2shFedArgs + ); Stream postRskip385 = Stream.of( // active fed is standard and pegoutRequestsCount is equal to zero diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java index dec37a942c8..b0af957e074 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTestIntegration.java @@ -627,11 +627,14 @@ void minimumProcessFundsMigrationValue() throws IOException { Federation oldFederation = bridgeConstants.getGenesisFederation(); BtcECKey key = new BtcECKey(new SecureRandom()); FederationMember member = new FederationMember(key, new ECKey(), new ECKey()); + FederationArgs newFederationArgs = new FederationArgs( + Collections.singletonList(member), + Instant.EPOCH, + 5L, + bridgeConstants.getBtcParams() + ); Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - Collections.singletonList(member), - Instant.EPOCH, - 5L, - bridgeConstants.getBtcParams() + newFederationArgs ); BridgeStorageProvider provider = mock(BridgeStorageProvider.class); @@ -1390,12 +1393,14 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); List activeFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - activeFederationMembers, + FederationArgs activeFedArgs = new FederationArgs(activeFederationMembers, Instant.ofEpochMilli(2000L), 2L, parameters ); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + activeFedArgs + ); List retiringFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fb01")), @@ -1403,11 +1408,12 @@ void registerBtcTransactionMigrationTx() throws BlockStoreException, AddressForm ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); List retiringFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys); - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( - retiringFederationMembers, + FederationArgs retiringFedArgs = new FederationArgs(retiringFederationMembers, Instant.ofEpochMilli(1000L), 1L, - parameters); + parameters + ); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation(retiringFedArgs); Repository repository = createRepository(); repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, LIMIT_MONETARY_BASE); @@ -1513,12 +1519,15 @@ void registerBtcTransactionWithCrossFederationsChange() throws Exception { .collect(Collectors.toList()); List activeFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs activeFedArgs = new FederationArgs( activeFederationMembers, Instant.ofEpochMilli(1000L), 5L, params ); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + activeFedArgs + ); final List retiringFedPrivateKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("47129ffed2c0273c75d21bb8ba020073bb9a1638df0e04853407461fdd9e8b83")), @@ -1611,12 +1620,14 @@ void registerBtcTransactionLockTxWhitelisted() throws Exception { federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); List federation1Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys); - Federation federation1 = FederationFactory.buildStandardMultiSigFederation( - federation1Members, + FederationArgs federation1Args = new FederationArgs(federation1Members, Instant.ofEpochMilli(1000L), 0L, btcParams ); + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( + federation1Args + ); List federation2Keys = Arrays.asList(new BtcECKey[]{ BtcECKey.fromPrivate(Hex.decode("fb01")), @@ -1626,11 +1637,12 @@ void registerBtcTransactionLockTxWhitelisted() throws Exception { federation2Keys.sort(BtcECKey.PUBKEY_COMPARATOR); List federation2Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys); - Federation federation2 = FederationFactory.buildStandardMultiSigFederation( - federation2Members, + FederationArgs federation2Args = new FederationArgs(federation2Members, Instant.ofEpochMilli(2000L), 0L, - btcParams + btcParams); + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( + federation2Args ); Repository repository = createRepository(); @@ -1782,17 +1794,22 @@ void getBtcTxHashProcessedHeight() throws IOException, BlockStoreException { @Test void getFederationMethods_genesis() throws IOException { + FederationArgs activeFedArgs = new FederationArgs(FederationTestUtils.getFederationMembers(3), + Instant.ofEpochMilli(1000), + 0L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + ); Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + activeFedArgs + ); + + FederationArgs genesisFedArgs = new FederationArgs(FederationTestUtils.getFederationMembers(6), + Instant.ofEpochMilli(1000), + 0L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); Federation genesisFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(6), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + genesisFedArgs ); BridgeSupport bridgeSupport = getBridgeSupportWithMocksForFederationTests(true, activeFederation, genesisFederation, null, null, null, null); @@ -1810,17 +1827,22 @@ void getFederationMethods_genesis() throws IOException { @Test void getFederationMethods_active() throws IOException { + FederationArgs activeFedArgs = new FederationArgs(FederationTestUtils.getFederationMembers(3), + Instant.ofEpochMilli(1000), + 0L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + ); Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + activeFedArgs + ); + + FederationArgs genesisFedArgs = new FederationArgs(FederationTestUtils.getFederationMembers(6), + Instant.ofEpochMilli(1000), + 0L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); Federation genesisFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(6), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + genesisFedArgs ); BridgeSupport bridgeSupport = getBridgeSupportWithMocksForFederationTests( false, @@ -1846,17 +1868,23 @@ void getFederationMethods_active() throws IOException { @Test void getFederationMethods_newActivated() throws IOException { + FederationArgs newFederationArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(3), + Instant.ofEpochMilli(1000), + 15L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + ); Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 15L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + newFederationArgs + ); + + FederationArgs oldFedArgs = new FederationArgs(FederationTestUtils.getFederationMembers(6), + Instant.ofEpochMilli(1000), + 0L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); Federation oldFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(6), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + oldFedArgs ); Block mockedBlock = mock(Block.class); @@ -1886,17 +1914,24 @@ void getFederationMethods_newActivated() throws IOException { @Test void getFederationMethods_newNotActivated() throws IOException { + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs newFederationArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(3), + Instant.ofEpochMilli(1000), + 15L, + btcParams + ); Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 15L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + newFederationArgs + ); + + FederationArgs oldFedArgs = new FederationArgs(FederationTestUtils.getFederationMembers(6), + Instant.ofEpochMilli(1000), + 0L, + btcParams ); Federation oldFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(6), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + oldFedArgs ); Block mockedBlock = mock(Block.class); @@ -1939,18 +1974,25 @@ void getRetiringFederationMethods_none() throws IOException { @Test void getRetiringFederationMethods_presentNewInactive() throws IOException { + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs mockedNewFedArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(2), + Instant.ofEpochMilli(1000), + 10L, + btcParams + ); Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(2), - Instant.ofEpochMilli(2000), - 10L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedNewFedArgs ); + FederationArgs mockedOldFedArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(4), + Instant.ofEpochMilli(1000), + 0L, + btcParams + ); Federation mockedOldFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(4), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedOldFedArgs ); Block mockedBlock = mock(Block.class); @@ -1976,18 +2018,25 @@ void getRetiringFederationMethods_presentNewInactive() throws IOException { @Test void getRetiringFederationMethods_presentNewActive() throws IOException { + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs mockedNewFedArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(2), + Instant.ofEpochMilli(1000), + 10L, + btcParams + ); Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(2), - Instant.ofEpochMilli(2000), - 10L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedNewFedArgs ); + FederationArgs mockedOldFedArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(4), + Instant.ofEpochMilli(1000), + 0L, + btcParams + ); Federation mockedOldFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(4), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedOldFedArgs ); Block mockedBlock = mock(Block.class); @@ -2192,19 +2241,26 @@ void createFederation_pendingExists() throws IOException, BridgeIllegalArgumentE @Test void createFederation_withPendingActivation() throws IOException, BridgeIllegalArgumentException { VotingMocksProvider mocksProvider = new VotingMocksProvider("create", new byte[][]{}, false); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs mockedNewFedArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(2), + Instant.ofEpochMilli(2000), + 10L, + btcParams + ); Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(2), - Instant.ofEpochMilli(2000), - 10L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedNewFedArgs ); + FederationArgs mockedOldFedArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(4), + Instant.ofEpochMilli(1000), + 0L, + btcParams + ); Federation mockedOldFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(4), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedOldFedArgs ); Block mockedBlock = mock(Block.class); @@ -2233,19 +2289,26 @@ void createFederation_withPendingActivation() throws IOException, BridgeIllegalA @Test void createFederation_withExistingRetiringFederation() throws IOException, BridgeIllegalArgumentException { VotingMocksProvider mocksProvider = new VotingMocksProvider("create", new byte[][]{}, false); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs mockedNewFedArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(2), + Instant.ofEpochMilli(2000), + 10L, + btcParams + ); Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(2), - Instant.ofEpochMilli(2000), - 10L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedNewFedArgs ); + FederationArgs mockedOldFedArgs = new FederationArgs( + FederationTestUtils.getFederationMembers(4), + Instant.ofEpochMilli(1000), + 0L, + btcParams + ); Federation mockedOldFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(4), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedOldFedArgs ); Block mockedBlock = mock(Block.class); @@ -2763,7 +2826,7 @@ void rollbackFederation_noPendingFederation() throws IOException, BridgeIllegalA @Test void commitFederation_ok() throws IOException, BridgeIllegalArgumentException { - + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); PendingFederation pendingFederation = new PendingFederation(FederationTestUtils.getFederationMembersWithKeys(Arrays.asList( BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")), @@ -2788,11 +2851,13 @@ void commitFederation_ok() throws IOException, BridgeIllegalArgumentException { BtcECKey.fromPublicOnly(Hex.decode("03c67ad63527012fd4776ae892b5dc8c56f80f1be002dc65cd520a2efb64e37b49")) ) ); - Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation( - expectedFederationMembers, + FederationArgs expectedFedArgs = new FederationArgs(expectedFederationMembers, Instant.ofEpochMilli(15005L), 15L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + btcParams + ); + Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation( + expectedFedArgs ); List newFederationMembers = @@ -2803,11 +2868,13 @@ void commitFederation_ok() throws IOException, BridgeIllegalArgumentException { BtcECKey.fromPublicOnly(Hex.decode("026192d8ab41bd402eb0431457f6756a3f3ce15c955c534d2b87f1e0372d8ba338")) ) ); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - newFederationMembers, + FederationArgs newFederationArgs = new FederationArgs(newFederationMembers, Instant.ofEpochMilli(5005L), 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + btcParams + ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs ); BridgeEventLogger eventLoggerMock = mock(BridgeEventLogger.class); @@ -2958,12 +3025,14 @@ void getActiveFederationWallet() throws IOException { BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) ) ); - Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation( - expectedFederationMembers, + FederationArgs expectedFederationArgs = new FederationArgs(expectedFederationMembers, Instant.ofEpochMilli(5005L), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); + Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation( + expectedFederationArgs + ); BridgeSupport bridgeSupport = getBridgeSupportWithMocksForFederationTests( false, @@ -2994,17 +3063,29 @@ void getActiveFederationWallet() throws IOException { @Test void getRetiringFederationWallet_nonEmpty() throws IOException { + FederationArgs mockedFedArgs = new FederationArgs(FederationTestUtils.getFederationMembers(2), + Instant.ofEpochMilli(2000), + 10L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + ); Federation mockedNewFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(2), - Instant.ofEpochMilli(2000), - 10L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + mockedFedArgs ); - Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation(FederationTestUtils.getFederationMembersWithBtcKeys(Arrays.asList(new BtcECKey[]{ + List expectedFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys( + Arrays.asList(new BtcECKey[]{ BtcECKey.fromPublicOnly(Hex.decode("036bb9eab797eadc8b697f0e82a01d01cabbfaaca37e5bafc06fdc6fdd38af894a")), - BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) - })), Instant.ofEpochMilli(5005L), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); + BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) + })); + FederationArgs expectedFederationArgs = new FederationArgs( + expectedFederationMembers, + Instant.ofEpochMilli(5005L), + 0L, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + ); + Federation expectedFederation = FederationFactory.buildStandardMultiSigFederation( + expectedFederationArgs + ); Block mockedBlock = mock(Block.class); when(mockedBlock.getNumber()).thenReturn(25L); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index f10717f5576..1bce4b85561 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -8,6 +8,7 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.flyover.FlyoverTxResponseCodes; @@ -240,13 +241,12 @@ void registerBtcTransaction_beforeRskip199_rejectsExternalCalls() ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); doReturn(false).when(activations).isActive(eq(RSKIP199), anyLong()); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(3), + FederationArgs activeFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); + 0L, btcParams); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation(activeFederationArgs); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); when(bridgeSupportMock.getActiveFederation()).thenReturn(activeFederation); @@ -281,18 +281,18 @@ void registerBtcTransaction_beforeRskip199_acceptsCallFromFederationMember() ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); doReturn(false).when(activations).isActive(eq(RSKIP199), anyLong()); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); BtcECKey fed1Key = new BtcECKey(); RskAddress fed1Address = new RskAddress(ECKey.fromPublicOnly(fed1Key.getPubKey()).getAddress()); List federationKeys = Arrays.asList(fed1Key, new BtcECKey(), new BtcECKey()); federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithKeys(federationKeys), + FederationArgs activeFederationArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithKeys(federationKeys), Instant.ofEpochMilli(1000), 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); + btcParams); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation(activeFederationArgs); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); when(bridgeSupportMock.getActiveFederation()).thenReturn(activeFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java index ff0b3ca379e..b3afe72db5f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsLegacyTest.java @@ -7,6 +7,7 @@ import java.time.Instant; import java.util.List; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.federation.FederationMember; import org.bouncycastle.util.encoders.Hex; @@ -457,14 +458,12 @@ void getUTXOsSentToAddress_after_RSKIP293() { @Test void calculatePegoutTxSize_before_rskip_271() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(false); + NetworkParameters btcParams = bridgeConstantsRegtest.getBtcParams(); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = FederationFactory.buildStandardMultiSigFederation( - FederationMember.getFederationMembersFromKeys(keys), - Instant.now(), - 0, - bridgeConstantsRegtest.getBtcParams() - ); + FederationArgs federationArgs = new FederationArgs(FederationMember.getFederationMembersFromKeys(keys), + Instant.now(), 0, btcParams); + Federation federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); int pegoutTxSize = BridgeUtilsLegacy.calculatePegoutTxSize(activations, federation, 2, 2); @@ -479,14 +478,13 @@ void calculatePegoutTxSize_before_rskip_271() { @Test void calculatePegoutTxSize_after_rskip_271() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); + NetworkParameters btcParams = bridgeConstantsRegtest.getBtcParams(); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = FederationFactory.buildStandardMultiSigFederation( - FederationMember.getFederationMembersFromKeys(keys), - Instant.now(), - 0, - bridgeConstantsRegtest.getBtcParams() - ); + + FederationArgs federationArgs = new FederationArgs(FederationMember.getFederationMembersFromKeys(keys), + Instant.now(), 0, btcParams); + Federation federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); Assertions.assertThrows(DeprecatedMethodCallException.class, () -> BridgeUtilsLegacy.calculatePegoutTxSize(activations, federation, 2, 2)); } @@ -494,14 +492,12 @@ void calculatePegoutTxSize_after_rskip_271() { @Test void calculatePegoutTxSize_ZeroInput_ZeroOutput() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(false); + NetworkParameters btcParams = bridgeConstantsRegtest.getBtcParams(); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = FederationFactory.buildStandardMultiSigFederation( - FederationMember.getFederationMembersFromKeys(keys), - Instant.now(), - 0, - bridgeConstantsRegtest.getBtcParams() - ); + FederationArgs federationArgs = new FederationArgs(FederationMember.getFederationMembersFromKeys(keys), + Instant.now(), 0, btcParams); + Federation federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); Assertions.assertThrows(IllegalArgumentException.class, () -> BridgeUtilsLegacy.calculatePegoutTxSize(activations, federation, 0, 0)); } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index 8026fb61dff..e54aabe6ec0 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -470,12 +470,15 @@ void isInputSignedByThisFederator_isSigned() { // Arrange BtcECKey federator1Key = new BtcECKey(); BtcECKey federator2Key = new BtcECKey(); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(Arrays.asList(federator1Key, federator2Key)), Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); // Create a tx from the Fed to a random btc address BtcTransaction tx = new BtcTransaction(networkParameters); @@ -518,12 +521,15 @@ void isInputSignedByThisFederator_isSignedByAnotherFederator() { // Arrange BtcECKey federator1Key = new BtcECKey(); BtcECKey federator2Key = new BtcECKey(); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(Arrays.asList(federator1Key, federator2Key)), Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); // Create a tx from the Fed to a random btc address BtcTransaction tx = new BtcTransaction(networkParameters); @@ -566,12 +572,15 @@ void isInputSignedByThisFederator_notSigned() { // Arrange BtcECKey federator1Key = new BtcECKey(); BtcECKey federator2Key = new BtcECKey(); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(Arrays.asList(federator1Key, federator2Key)), Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); // Create a tx from the Fed to a random btc address BtcTransaction tx = new BtcTransaction(networkParameters); @@ -912,12 +921,15 @@ void testCalculatePegoutTxSize_ZeroInput_ZeroOutput() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); Assertions.assertThrows(IllegalArgumentException.class, () -> BridgeUtils.calculatePegoutTxSize(activations, federation, 0, 0)); } @@ -928,12 +940,15 @@ void testCalculatePegoutTxSize_2Inputs_2Outputs() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); int inputSize = 2; int outputSize = 2; @@ -953,12 +968,15 @@ void testCalculatePegoutTxSize_9Inputs_2Outputs() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); int inputSize = 9; int outputSize = 2; @@ -978,12 +996,15 @@ void testCalculatePegoutTxSize_10Inputs_20Outputs() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); // Create a pegout tx with 10 inputs and 20 outputs int inputSize = 10; @@ -1006,12 +1027,15 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs() { when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); List keys = PegTestUtils.createRandomBtcECKeys(13); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); // Create a pegout tx with 50 inputs and 200 outputs int inputSize = 50; @@ -1047,13 +1071,16 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs_erpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, - 500L, + 500L + ); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + erpFederationArgs, activations ); @@ -1091,13 +1118,16 @@ void testCalculatePegoutTxSize_100Inputs_50Outputs_erpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, - 500L, + 500L + ); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + erpFederationArgs, activations ); @@ -1125,12 +1155,15 @@ void getRegularPegoutTxSize_has_proper_calculations() { BtcECKey key2 = new BtcECKey(); BtcECKey key3 = new BtcECKey(); List keys = Arrays.asList(key1, key2, key3); - Federation fed = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationMember.getFederationMembersFromKeys(keys), Instant.now(), 0, networkParameters ); + Federation fed = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); // Create a pegout tx with two inputs and two outputs int inputs = 2; @@ -1169,11 +1202,15 @@ private void test_getSpendWallet(boolean isFlyoverCompatible) throws UTXOProvide BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) ) ); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( federationMembers, Instant.ofEpochMilli(5005L), 0L, - networkParameters); + networkParameters + ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); Context mockedBtcContext = mock(Context.class); when(mockedBtcContext.getParams()).thenReturn(networkParameters); @@ -1206,11 +1243,14 @@ private void test_getNoSpendWallet(boolean isFlyoverCompatible) { BtcECKey.fromPublicOnly(Hex.decode("031da807c71c2f303b7f409dd2605b297ac494a563be3b9ca5f52d95a43d183cc5")) ) ); - Federation federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( federationMembers, Instant.ofEpochMilli(5005L), 0L, - networkParameters); + networkParameters + ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs); Context mockedBtcContext = mock(Context.class); when(mockedBtcContext.getParams()).thenReturn(networkParameters); @@ -1434,13 +1474,16 @@ private Genesis getGenesisInstance(TrieStore trieStore) { private ErpFederation createErpFederation() { Federation genesisFederation = bridgeConstantsRegtest.getGenesisFederation(); - return FederationFactory.buildNonStandardErpFederation( + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( genesisFederation.getMembers(), genesisFederation.getCreationTime(), genesisFederation.getCreationBlockNumber(), genesisFederation.getBtcParams(), bridgeConstantsRegtest.getErpFedPubKeysList(), - bridgeConstantsRegtest.getErpFedActivationDelay(), + bridgeConstantsRegtest.getErpFedActivationDelay() + ); + return FederationFactory.buildNonStandardErpFederation( + erpFederationArgs, activations ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java b/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java index fb212ffd17b..74a00696666 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FederationSupportTest.java @@ -23,10 +23,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationMember; -import co.rsk.peg.federation.FederationTestUtils; +import co.rsk.peg.federation.*; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; @@ -170,12 +167,14 @@ void getFederatorPublicKeys() { ECKey rskKey1 = new ECKey(); ECKey mstKey1 = new ECKey(); + List members = Arrays.asList( + new FederationMember(btcKey0, rskKey0, mstKey0), + new FederationMember(btcKey1, rskKey1, mstKey1) + ); + FederationArgs federationArgs = new FederationArgs(members, Instant.ofEpochMilli(123), 456, + NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); Federation theFederation = FederationFactory.buildStandardMultiSigFederation( - Arrays.asList( - new FederationMember(btcKey0, rskKey0, mstKey0), - new FederationMember(btcKey1, rskKey1, mstKey1) - ), Instant.ofEpochMilli(123), 456, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) + federationArgs ); when(provider.getNewFederation()).thenReturn(theFederation); @@ -245,12 +244,14 @@ private Federation getNewFakeFederation(long creationBlockNumber) { true ); List members = FederationTestUtils.getFederationMembersWithBtcKeys(keys); - - return FederationFactory.buildStandardMultiSigFederation( - members, + FederationArgs federationArgs = new FederationArgs(members, Instant.ofEpochMilli(123), creationBlockNumber, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); + + return FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java index c0da2ea3725..58bb82376ca 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java @@ -42,23 +42,17 @@ class FlyoverCompatibleBtcWalletWithStorageTest { @BeforeEach void setup() { + List fedMembers = FederationTestUtils.getFederationMembers(3); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); - federation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); + FederationArgs federationArgs = new FederationArgs(fedMembers, Instant.ofEpochMilli(1000), 0L, btcParams); + federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); - erpFederation = FederationFactory.buildNonStandardErpFederation( - FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST), - erpFedKeys, - 5063, - mock(ActivationConfig.ForBlock.class) - ); + long activationDelay = 5063; + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000), 0L, btcParams, + erpFedKeys, activationDelay); + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); federationList = Collections.singletonList(federation); erpFederationList = Collections.singletonList(erpFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java index 9a7e63f76ef..f1c2c936c3a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java @@ -41,25 +41,32 @@ class FlyoverCompatibleBtcWallextWithSingleScriptTest { @BeforeEach void setup() { - federation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); + federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - erpFederation = FederationFactory.buildNonStandardErpFederation( + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembers(3), Instant.ofEpochMilli(1000), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST), erpFedKeys, - 5063, + 5063 + ); + erpFederation = FederationFactory.buildNonStandardErpFederation( + erpFederationArgs, activations ); diff --git a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java index 6e030b97322..31fd5d1ad8a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java @@ -26,10 +26,7 @@ import co.rsk.config.BridgeConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; -import co.rsk.peg.federation.ErpFederation; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationTestUtils; +import co.rsk.peg.federation.*; import co.rsk.peg.simples.SimpleRskTransaction; import org.bouncycastle.util.encoders.Hex; import org.ethereum.core.Transaction; @@ -302,24 +299,21 @@ public static Federation createFederation(BridgeConstants bridgeConstants, Strin public static Federation createFederation(BridgeConstants bridgeConstants, List federationKeys) { federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - return FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys), - Instant.ofEpochMilli(1000L), - 0L, - bridgeConstants.getBtcParams() - ); + List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys); + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + FederationArgs federationArgs = new FederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcParams); + return FederationFactory.buildStandardMultiSigFederation(federationArgs); } public static ErpFederation createP2shErpFederation(BridgeConstants bridgeConstants, List federationKeys) { federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - return FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys), - Instant.ofEpochMilli(1000L), - 0L, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys); + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcParams, + erpPubKeys, activationDelay); + return FederationFactory.buildP2shErpFederation(erpFederationArgs); } public static BtcTransaction createBtcTransactionWithOutputToAddress(NetworkParameters networkParameters, Coin amount, Address btcAddress) { diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java index 5b62e08db08..e818e211175 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java @@ -7,10 +7,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.peg.federation.ErpFederation; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationTestUtils; +import co.rsk.peg.federation.*; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; @@ -66,9 +63,7 @@ void test_sentFromP2SHErpFed() { federator3PublicKey, federator4PublicKey, federator5PublicKey, federator6PublicKey, federator7PublicKey, federator8PublicKey ); - - // Arrange - ErpFederation activeFederation = FederationFactory.buildP2shErpFederation( + ErpFederationArgs activeErpFedArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), bridgeMainnetConstants.getGenesisFederation().getCreationTime(), 5L, @@ -77,18 +72,25 @@ void test_sentFromP2SHErpFed() { bridgeMainnetConstants.getErpFedActivationDelay() ); + // Arrange + ErpFederation activeFederation = FederationFactory.buildP2shErpFederation( + activeErpFedArgs + ); + List fedKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - ErpFederation p2shRetiringFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), + ErpFederationArgs retiringErpFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, bridgeMainnetConstants.getErpFedPubKeysList(), bridgeMainnetConstants.getErpFedActivationDelay() ); + ErpFederation p2shRetiringFederation = FederationFactory.buildP2shErpFederation( + retiringErpFedArgs + ); // Create a migrationTx from the p2sh erp fed Coin minimumPeginTxValue = bridgeMainnetConstants.getMinimumPeginTxValue(activations); @@ -136,12 +138,15 @@ void test_sentFromOldFed(ActivationConfig.ForBlock activations, PegTxType expect ); // Arrange - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( bridgeRegTestConstants.getGenesisFederation().getMembers(), bridgeRegTestConstants.getGenesisFederation().getCreationTime(), 5L, bridgeRegTestConstants.getGenesisFederation().getBtcParams() ); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); Federation retiredFederation = createFederation(bridgeRegTestConstants, REGTEST_OLD_FEDERATION_PRIVATE_KEYS); @@ -340,7 +345,7 @@ void test_pegin( new String[]{"fa04", "fa05", "fa06"}, true ); - ErpFederation activeFederation = FederationFactory.buildP2shErpFederation( + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(activeFedKeys), Instant.ofEpochMilli(1000L), 0L, @@ -348,6 +353,9 @@ void test_pegin( erpFedKeys, 100L ); + ErpFederation activeFederation = FederationFactory.buildP2shErpFederation( + erpFederationArgs + ); BtcTransaction peginTx = new BtcTransaction(btcMainnetParams); peginTx.addInput(BitcoinTestUtils.createHash(1), 0, new Script(new byte[]{})); @@ -378,12 +386,14 @@ void test_pegout_tx() { new String[]{"fa01", "fa02", "fa03"}, true ); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), + FederationArgs federationArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams ); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); // Create a pegoutBtcTx from active fed to a user btc address Address userAddress = BitcoinTestUtils.createP2PKHAddress(btcMainnetParams, "user"); @@ -419,14 +429,17 @@ void test_migration_tx() { List retiringFedKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true - );; + ); - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedKeys), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams ); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); BtcTransaction migrationTx = new BtcTransaction(btcMainnetParams); migrationTx.addInput(BitcoinTestUtils.createHash(1), 0, retiringFederation.getRedeemScript()); @@ -459,12 +472,14 @@ void test_migration_to_p2shFed_tx() { new String[]{"fa01", "fa02", "fa03"}, true ); - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedKeys), + FederationArgs federationArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedKeys), Instant.ofEpochMilli(1000L), 0L, btcMainnetParams ); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); List activeFedKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa04", "fa05", "fa06"}, true diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java index da1c77a3e98..a47f5146df7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java @@ -199,20 +199,19 @@ void testIsValidPegInTx_value_between_old_and_new_after_iris() { @Test void testIsValidPegInTxForTwoFederations() { - Context btcContext = new Context(networkParameters); when(activations.isActive(any(ConsensusRule.class))).thenReturn(false); + Context btcContext = new Context(networkParameters); + NetworkParameters btcParams = btcContext.getParams(); + List federation1Keys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ); federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation federation1 = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); + List fed1Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys); + FederationArgs federation1Args = new FederationArgs(fed1Members, Instant.ofEpochMilli(1000L), 0L, btcParams); + Federation federation1 = FederationFactory.buildStandardMultiSigFederation(federation1Args); List federation2Keys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fb01")), @@ -220,12 +219,9 @@ void testIsValidPegInTxForTwoFederations() { BtcECKey.fromPrivate(Hex.decode("fb03")) ); federation2Keys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation federation2 = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), - Instant.ofEpochMilli(2000L), - 0L, - networkParameters - ); + List fed2Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys); + FederationArgs federation2Args = new FederationArgs(fed2Members, Instant.ofEpochMilli(1000L), 0L, btcParams); + Federation federation2 = FederationFactory.buildStandardMultiSigFederation(federation2Args); Address address1 = federation1.getAddress(); Address address2 = federation2.getAddress(); @@ -528,29 +524,27 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverFederation_afterRskip201_notPegi @Test void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_beforeRskip201_isPegin() { - Context btcContext = new Context(networkParameters); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(false); + Context btcContext = new Context(networkParameters); + NetworkParameters btcParams = btcContext.getParams(); + Federation activeFederation = bridgeConstantsRegtest.getGenesisFederation(); - List erpFederationKeys = Arrays.asList( + List fedMembers = activeFederation.getMembers(); + List erpPubKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ); - erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); + erpPubKeys.sort(BtcECKey.PUBKEY_COMPARATOR); + long activationDelay = 500L; - Script erpRedeemScript = ErpFederationRedeemScriptParser.createErpRedeemScript( - activeFederation.getRedeemScript(), - erpFederation.getRedeemScript(), - 500L - ); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcParams, + erpPubKeys, activationDelay); + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + + Script redeemScript = erpFederation.getRedeemScript(); Script flyoverErpRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( - erpRedeemScript, + redeemScript, Sha256Hash.of(PegTestUtils.createHash(1).getBytes()) ); @@ -581,12 +575,10 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_afterRskip201_notP BtcECKey.fromPrivate(Hex.decode("fa02")) ); erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); + + List erpFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys); + FederationArgs args = new FederationArgs(erpFedMembers, Instant.ofEpochMilli(1000L), 0L, networkParameters); + Federation erpFederation = FederationFactory.buildStandardMultiSigFederation(args); Script erpRedeemScript = ErpFederationRedeemScriptParser.createErpRedeemScript( activeFederation.getRedeemScript(), @@ -625,12 +617,15 @@ void testIsValidPegInTx_hasChangeUtxoFromErpFederation_beforeRskip201_isPegin() BtcECKey.fromPrivate(Hex.decode("fa02")) ); erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); Script erpRedeemScript = ErpFederationRedeemScriptParser.createErpRedeemScript( activeFederation.getRedeemScript(), @@ -660,12 +655,15 @@ void testIsValidPegInTx_hasChangeUtxoFromErpFederation_afterRskip201_notPegin() BtcECKey.fromPrivate(Hex.decode("fa02")) ); erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); Script erpRedeemScript = ErpFederationRedeemScriptParser.createErpRedeemScript( activeFederation.getRedeemScript(), @@ -695,12 +693,15 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverRetiredFederation_beforeRskip201 BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); // Create a tx from the retired fast bridge fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -742,12 +743,15 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverRetiredFederation_afterRskip201_ BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); // Create a tx from the retired fast bridge fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -789,28 +793,30 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_beforeRskip BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), BtcECKey.fromPrivate(Hex.decode("fa04")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, - 500L, - activations + 500L ); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired fast bridge fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -852,12 +858,15 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), @@ -865,15 +874,15 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, - 500L, - activations + 500L ); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired fast bridge fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -914,12 +923,15 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), @@ -927,15 +939,15 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, - 500L, - activations + 500L ); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired erp fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -972,26 +984,31 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_afterRskip201_notP BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs retiredFedArgs = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + retiredFedArgs + ); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), BtcECKey.fromPrivate(Hex.decode("fa04")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederationArgs erpFedArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, - 500L, + 500L + ); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + erpFedArgs, activations ); @@ -1234,14 +1251,16 @@ private void testIsValidPegInTx_fromP2shErpScriptSender( List emergencyKeys = PegTestUtils.createRandomBtcECKeys(3); long activationDelay = 256L; - Federation p2shErpFederation = FederationFactory.buildP2shErpFederation( - activeFederation.getMembers(), + ErpFederationArgs args = new ErpFederationArgs(activeFederation.getMembers(), activeFederation.getCreationTime(), activeFederation.getCreationBlockNumber(), networkParameters, emergencyKeys, activationDelay ); + Federation p2shErpFederation = FederationFactory.buildP2shErpFederation( + args + ); Script flyoverP2shErpRedeemScript = FastBridgeP2shErpRedeemScriptParser.createFastBridgeP2shErpRedeemScript( p2shErpFederation.getRedeemScript(), @@ -1300,7 +1319,7 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - ErpFederation retiredFederation = FederationFactory.buildP2shErpFederation( + ErpFederationArgs retiredFedArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, @@ -1308,20 +1327,25 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay() ); + ErpFederation retiredFederation = FederationFactory.buildP2shErpFederation( + retiredFedArgs + ); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay() ); + Federation activeFederation = FederationFactory.buildP2shErpFederation( + activeFedArgs + ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1370,28 +1394,32 @@ void testIsMigrationTx_sending_funds_from_retiring_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(retiringFed), + ErpFederationArgs retiringFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFed), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay() ); + Federation retiringFederation = FederationFactory.buildP2shErpFederation( + retiringFedArgs + ); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay() ); + Federation activeFederation = FederationFactory.buildP2shErpFederation( + activeFedArgs + ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1430,26 +1458,30 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_p2sh_fe BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), + FederationArgs retiredFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams() ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + retiredFedArgs + ); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay() ); + Federation activeFederation = FederationFactory.buildP2shErpFederation( + activeFedArgs + ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1498,26 +1530,30 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_p2sh_f BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), + FederationArgs retiringFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams() ); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + retiringFedArgs + ); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay() ); + Federation activeFederation = FederationFactory.buildP2shErpFederation( + activeFedArgs + ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1556,24 +1592,28 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_standar BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), + FederationArgs retiredFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams() ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + retiredFedArgs + ); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + FederationArgs activeFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams() ); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + activeFedArgs + ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1622,24 +1662,29 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_standa BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs retiringFedArgs = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams() ); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + retiringFedArgs + ); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + FederationArgs activeFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(1000L), 1L, bridgeConstantsMainnet.getBtcParams() ); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + activeFedArgs + ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1675,35 +1720,43 @@ void testIsMigrationTx() { BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + + FederationArgs activeFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(2000L), 2L, networkParameters ); + Federation activeFederation = FederationFactory.buildStandardMultiSigFederation( + activeFedArgs + ); List retiringFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fb01")), BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), + + FederationArgs retiringFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), Instant.ofEpochMilli(1000L), 1L, networkParameters ); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + retiringFedArgs + ); List retiredFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fc01")), BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), + FederationArgs retiredFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), Instant.ofEpochMilli(1000L), 1L, networkParameters ); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( + retiredFedArgs + ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1834,12 +1887,14 @@ void testIsPegOutTx() { BtcECKey.fromPrivate(Hex.decode("fa02")), BtcECKey.fromPrivate(Hex.decode("fa03")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - Federation federation2 = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + FederationArgs args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), Instant.ofEpochMilli(2000L), 2L, bridgeConstantsRegtest.getBtcParams() ); + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( + args + ); List federationPrivateKeys = BridgeRegTestConstants.REGTEST_FEDERATION_PRIVATE_KEYS; Address randomAddress = PegTestUtils.createRandomP2PKHBtcAddress(bridgeConstantsRegtest.getBtcParams()); @@ -1871,12 +1926,14 @@ void testIsPegOutTx_fromFlyoverFederation() { BtcECKey.fromPrivate(Hex.decode("fa03")) ); flyoverFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation flyoverFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(flyoverFederationKeys), + FederationArgs args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(flyoverFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation flyoverFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -1929,12 +1986,14 @@ void testIsPegOutTx_fromErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa03")) ); defaultFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), + FederationArgs args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), @@ -1942,14 +2001,15 @@ void testIsPegOutTx_fromErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa05")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), + ErpFederationArgs erpArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, - 500L, + 500L + ); + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( + erpArgs, activations ); @@ -2005,12 +2065,14 @@ void testIsPegOutTx_fromFlyoverErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa03")) ); defaultFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), + FederationArgs args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters ); + Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation( + args + ); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), @@ -2019,13 +2081,15 @@ void testIsPegOutTx_fromFlyoverErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), + ErpFederationArgs erpArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, networkParameters, erpFederationPublicKeys, - 500L, + 500L + ); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + erpArgs, activations ); @@ -2119,9 +2183,14 @@ void testChangeBetweenFederations() { .map(BtcECKey::fromPrivate) .sorted(BtcECKey.PUBKEY_COMPARATOR) .collect(Collectors.toList()); - Federation federation1 = FederationFactory.buildStandardMultiSigFederation( + FederationArgs args1 = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), - Instant.ofEpochMilli(1000L), 0L, networkParameters + Instant.ofEpochMilli(1000L), + 0L, + networkParameters + ); + Federation federation1 = FederationFactory.buildStandardMultiSigFederation( + args1 ); List federation2Keys = Stream.of("fb01", "fb02", "fb03") @@ -2130,12 +2199,14 @@ void testChangeBetweenFederations() { .sorted(BtcECKey.PUBKEY_COMPARATOR) .collect(Collectors.toList()); List federation2Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys); - Federation federation2 = FederationFactory.buildStandardMultiSigFederation( - federation2Members, + FederationArgs args2 = new FederationArgs(federation2Members, Instant.ofEpochMilli(2000L), 0L, networkParameters ); + Federation federation2 = FederationFactory.buildStandardMultiSigFederation( + args2 + ); Address federation2Address = federation2.getAddress(); 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 008bc5cf84b..686b2819a91 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java @@ -10,10 +10,7 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.peg.federation.ErpFederation; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationTestUtils; +import co.rsk.peg.federation.*; import co.rsk.test.builders.BridgeSupportBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -207,14 +204,12 @@ void test_getTransactionType_pegin_output_to_retiring_fed_and_other_addresses() List signers = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - ErpFederation activeFed = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(signers), - Instant.ofEpochMilli(1000L), - 0L, - btcMainnetParams, - bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay() - ); + List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(signers); + List erpPubKeys = bridgeMainnetConstants.getErpFedPubKeysList(); + long activationDelay = bridgeMainnetConstants.getErpFedActivationDelay(); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, + erpPubKeys, activationDelay); + ErpFederation activeFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); BtcTransaction btcTransaction = new BtcTransaction(btcMainnetParams); @@ -609,14 +604,13 @@ void test_getTransactionType_flyover_segwit() { List signers = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - ErpFederation activeFed = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(signers), - Instant.ofEpochMilli(1000L), - 0L, - btcTestNetParams, - bridgeTestNetConstants.getErpFedPubKeysList(), - bridgeTestNetConstants.getErpFedActivationDelay() - ); + List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(signers); + List erpPubKeys = bridgeTestNetConstants.getErpFedPubKeysList(); + long activationDelay = bridgeTestNetConstants.getErpFedActivationDelay(); + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcTestNetParams, + erpPubKeys, activationDelay); + ErpFederation activeFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); String segwitTxHex = "020000000001011f668117f2ca3314806ade1d99ae400f5413d7e9d4bfcbd11d52645e060e22fb0100000000fdffffff0300000000000000001b6a1952534b5401a27c6f697954357247e78f9900023cfe01a9d49c0412030000000000160014b413f59a7ee6e34321140e83ea661e0484a79bc2988708000000000017a9145e6cf80958803e9b3c81cd90422152520d2a505c870247304402203fce49b39f79581d93720f462b5f33f9174e66dc6efb635d4f41aacb33b08d0302201221aec5db31e269454fcc7a4df2936ccedd566ccf48828d4f97050954f196540121021831c5ba44b739521d635e521560525672087e4d5db053801f4aeb60e782f6d6d0f02400"; diff --git a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java index cab9a9076b0..c46051a438f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java @@ -9,10 +9,7 @@ import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.peg.federation.ErpFederation; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; -import co.rsk.peg.federation.FederationMember; +import co.rsk.peg.federation.*; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -67,14 +64,17 @@ void test_each_input_sighash_is_unique(NetworkParameters networkParameters) { List fedMembers = fedSigners.stream().map(FedSigner::getFed).collect(Collectors.toList()); List erpFedPubKeys = erpFedSigners.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - fedMembers, + + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.now(), 0L, networkParameters, erpFedPubKeys, erpFedActivationDelay ); + ErpFederation fed = FederationFactory.buildP2shErpFederation( + erpFederationArgs + ); List utxos = new ArrayList<>(); for (int i = 0; i < 7; i++) { @@ -140,14 +140,16 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), erpFedActivationDelay ); + ErpFederation fed = FederationFactory.buildP2shErpFederation( + erpFederationArgs + ); List utxos = new ArrayList<>(); BtcTransaction peginTx = new BtcTransaction(networkParameters); @@ -236,14 +238,16 @@ void test_sighash_is_equal_for_signed_input_and_unsigned_input(NetworkParameters when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), erpFedActivationDelay ); + ErpFederation fed = FederationFactory.buildP2shErpFederation( + erpFederationArgs + ); List utxos = new ArrayList<>(); for (int i = 0; i < 7; i++) { @@ -297,14 +301,16 @@ void test_each_input_sighash_is_unique_using_real_tx_testnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), erpFedActivationDelay ); + ErpFederation fed = FederationFactory.buildP2shErpFederation( + erpFederationArgs + ); Address expectedAddress = Address.fromBase58( networkParameters, @@ -383,14 +389,16 @@ void test_each_input_sighash_is_unique_for_a_signed_erp_tx_testnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), Instant.now(), 0L, networkParameters, fedPubKeys, erpFedActivationDelay ); + ErpFederation fed = FederationFactory.buildP2shErpFederation( + erpFederationArgs + ); Address expectedAddress = Address.fromBase58( networkParameters, @@ -473,14 +481,16 @@ void test_redeemScript_can_be_obtained_from_input() { FedSigner::getFed ).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - fedMembers, + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.now(), 0L, networkParameters, erpPubKeys, erpFedActivationDelay ); + ErpFederation fed = FederationFactory.buildP2shErpFederation( + erpFederationArgs + ); Address expectedAddress = Address.fromBase58( networkParameters, diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index ad63b28ab1b..da83208733f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -129,29 +129,19 @@ private void testChangePowpeg( theseKeys.getRight() ) ).collect(Collectors.toList()); + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); Federation originalPowpeg; + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(originalPowpegMembers, Instant.now(), 0, btcParams, + erpPubKeys, activationDelay); switch (oldPowPegFederationType) { case legacyErp: - originalPowpeg = FederationFactory.buildNonStandardErpFederation( - originalPowpegMembers, - Instant.now(), - 0, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); + originalPowpeg = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); break; case p2shErp: - originalPowpeg = FederationFactory.buildP2shErpFederation( - originalPowpegMembers, - Instant.now(), - 0, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + originalPowpeg = FederationFactory.buildP2shErpFederation(erpFederationArgs); // TODO: CHECK REDEEMSCRIPT break; default: diff --git a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java index 7b7d700ecd9..03d9bec45bd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java @@ -92,16 +92,22 @@ void setup() { @Test void first_output_pay_fees() { - Federation federation = FederationFactory.buildStandardMultiSigFederation( - FederationMember.getFederationMembersFromKeys(Arrays.asList( + List members = FederationMember.getFederationMembersFromKeys( + Arrays.asList( new BtcECKey(), new BtcECKey(), - new BtcECKey()) - ), + new BtcECKey() + ) + ); + FederationArgs federationArgs = new FederationArgs( + members, Instant.now(), 0, networkParameters ); + Federation federation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); List utxos = Arrays.asList( new UTXO( @@ -167,17 +173,24 @@ void build_pegout_tx_from_erp_federation() { // Use mainnet constants to test a real situation BridgeConstants bridgeConstants = BridgeMainNetConstants.getInstance(); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( - FederationMember.getFederationMembersFromKeys(Arrays.asList( + List members = FederationMember.getFederationMembersFromKeys( + Arrays.asList( new BtcECKey(), new BtcECKey(), - new BtcECKey()) - ), + new BtcECKey() + ) + ); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( + members, Instant.now(), 0, bridgeConstants.getBtcParams(), bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), + bridgeConstants.getErpFedActivationDelay() + ); + + Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + erpFederationArgs, activations ); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java index 94009852beb..5b0a059794c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java @@ -172,35 +172,22 @@ void p2shErpFederation_haveP2shFedFormat() { } private Federation createStandardMultisigFederation() { - return FederationFactory.buildStandardMultiSigFederation( - federationMembers, - creationTime, - creationBlockNumber, - networkParameters - ); + FederationArgs federationArgs = new FederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters); + return FederationFactory.buildStandardMultiSigFederation(federationArgs); } private ErpFederation createNonStandardErpFederation() { - return FederationFactory.buildNonStandardErpFederation( - federationMembers, - creationTime, - creationBlockNumber, - networkParameters, - emergencyKeys, - activationDelayValue, - activations + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters, + emergencyKeys, activationDelayValue ); + return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } private ErpFederation createP2shErpFederation() { - return FederationFactory.buildP2shErpFederation( - federationMembers, - creationTime, - creationBlockNumber, - networkParameters, - emergencyKeys, - activationDelayValue + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters, + emergencyKeys, activationDelayValue ); + return FederationFactory.buildP2shErpFederation(erpFederationArgs); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationTestUtils.java index 243dacb3514..2b42e4391a2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationTestUtils.java @@ -41,12 +41,15 @@ public class FederationTestUtils { public static Federation getFederation(Integer... federationMemberPks) { - return FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( getFederationMembersFromPks(federationMemberPks), ZonedDateTime.parse("2017-06-10T02:30:01Z").toInstant(), 0L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); + return FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); } public static List getFederationMembers(int memberCount) { diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java index 1d7c92f6355..efa05b546bb 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java @@ -95,15 +95,9 @@ private ErpFederation createDefaultNonStandardErpFederation() { Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - return FederationFactory.buildNonStandardErpFederation( - standardMembers, - creationTime, - creationBlockNumber, - networkParameters, - emergencyKeys, - activationDelayValue, - activations - ); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(standardMembers, creationTime, creationBlockNumber, networkParameters, + emergencyKeys, activationDelayValue); + return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } @Test @@ -257,43 +251,30 @@ void testEquals_basic() { @Test void testEquals_same() { - ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation( - federation.getMembers(), - federation.getCreationTime(), - federation.getCreationBlockNumber(), - federation.getBtcParams(), - federation.getErpPubKeys(), - federation.getActivationDelay(), - activations + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), + federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay() ); + ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); assertEquals(federation, otherFederation); } @Test void testEquals_differentCreationTime() { - ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation( - federation.getMembers(), - federation.getCreationTime().plus(1, ChronoUnit.MILLIS), - federation.getCreationBlockNumber(), - federation.getBtcParams(), - federation.getErpPubKeys(), - federation.getActivationDelay(), - activations + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime().plus(1, ChronoUnit.MILLIS), + federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay() ); + ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + assertEquals(federation, otherFederation); } @Test void testEquals_differentCreationBlockNumber() { - ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation( - federation.getMembers(), - federation.getCreationTime(), - federation.getCreationBlockNumber() + 1, - federation.getBtcParams(), - federation.getErpPubKeys(), - federation.getActivationDelay(), - activations + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber() + 1, + federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay() ); + ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + assertEquals(federation, otherFederation); } @@ -691,6 +672,7 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { // prior to RSKIP293 enforces the CSV value to be encoded using 2 bytes. // The hardcoded script has a 3 byte long CSV value when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); List standardMultisigKeys = Arrays.stream(new String[]{ "0208f40073a9e43b3e9103acec79767a6de9b0409749884e989960fee578012fce", @@ -710,18 +692,10 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { List federationMembersWithBtcKeys = FederationTestUtils.getFederationMembersWithBtcKeys(standardMultisigKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); - NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federationMembersWithBtcKeys, creationTime, 1, btcParams, + emergencyMultisigKeys, activationDelay); - assertThrows(ErpFederationCreationException.class, - () -> FederationFactory.buildNonStandardErpFederation( - federationMembersWithBtcKeys, - creationTime, - 1, - btcParams, - emergencyMultisigKeys, - activationDelay, - activations - )); + assertThrows(ErpFederationCreationException.class, () -> FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations)); } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java index ddebc7fc07e..185cbabe3ac 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java @@ -81,15 +81,11 @@ private ErpFederation createDefaultP2shErpFederation() { List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(defaultKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - - return FederationFactory.buildP2shErpFederation( - standardMembers, - creationTime, - creationBlockNumber, - networkParameters, - emergencyKeys, - activationDelayValue + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(standardMembers, creationTime, creationBlockNumber, networkParameters, + emergencyKeys, activationDelayValue ); + + return FederationFactory.buildP2shErpFederation(erpFederationArgs); } private void createAndValidateFederation() { @@ -227,14 +223,10 @@ void testEquals_basic() { @Test void testEquals_same() { - ErpFederation otherFederation = FederationFactory.buildP2shErpFederation( - federation.getMembers(), - federation.getCreationTime(), - federation.getCreationBlockNumber(), - federation.getBtcParams(), - federation.getErpPubKeys(), - federation.getActivationDelay() + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams(), + federation.getErpPubKeys(), federation.getActivationDelay() ); + ErpFederation otherFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); assertEquals(federation, otherFederation); } @@ -338,28 +330,20 @@ void getRedeemScript(BridgeConstants bridgeConstants) { @Test void getStandardRedeemScript() { + NetworkParameters btcParams = BridgeRegTestConstants.getInstance().getBtcParams(); List members = FederationMember.getFederationMembersFromKeys( Arrays.asList(new BtcECKey(), new BtcECKey(), new BtcECKey()) ); Instant creationTime = Instant.now(); int creationBlock = 0; - NetworkParameters btcParams = BridgeRegTestConstants.getInstance().getBtcParams(); + FederationArgs federationArgs = new FederationArgs(members, creationTime, creationBlock, btcParams); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(members, creationTime, creationBlock, btcParams, + Arrays.asList(new BtcECKey(), new BtcECKey()), + 10_000); // Create a standard multisig powpeg and then a p2sh valid one. Both of them should produce the same default redeem script - StandardMultisigFederation standardMultisigFed = FederationFactory.buildStandardMultiSigFederation( - members, - creationTime, - creationBlock, - btcParams - ); - ErpFederation p2shFed = FederationFactory.buildP2shErpFederation( - members, - creationTime, - creationBlock, - btcParams, - Arrays.asList(new BtcECKey(), new BtcECKey()), - 10_000 - ); + StandardMultisigFederation standardMultisigFed = FederationFactory.buildStandardMultiSigFederation(federationArgs); + ErpFederation p2shFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); assertEquals(standardMultisigFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); Assertions.assertNotEquals(p2shFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); @@ -463,14 +447,12 @@ void getErpRedeemScript_compareOtherImplementation_P2SHERPFederation() throws IO for (RawGeneratedRedeemScript generatedScript : generatedScripts) { // Skip test cases with invalid redeem script that exceed the maximum size if (generatedScript.script.getProgram().length <= MAX_SCRIPT_ELEMENT_SIZE) { - Federation erpFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersWithBtcKeys(generatedScript.mainFed), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 1, + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(generatedScript.mainFed), + ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 1, NetworkParameters.fromID(NetworkParameters.ID_TESTNET), generatedScript.emergencyFed, - generatedScript.timelock - ); + generatedScript.timelock); + Federation erpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); Script rskjScript = erpFederation.getRedeemScript(); Script alternativeScript = generatedScript.script; @@ -496,14 +478,11 @@ void spendFromP2shErpFed( true ); - ErpFederation p2shErpFed = FederationFactory.buildP2shErpFederation( - FederationMember.getFederationMembersFromKeys(defaultKeys), - ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 0L, - networkParameters, - emergencyKeys, - activationDelay + ErpFederationArgs erpFederationArgs = new ErpFederationArgs( + FederationMember.getFederationMembersFromKeys(defaultKeys), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), + 0L, networkParameters, emergencyKeys, activationDelay ); + ErpFederation p2shErpFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); Coin value = Coin.valueOf(1_000_000); Coin fee = Coin.valueOf(10_000); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java index c36c00bcc07..a2de74b9797 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java @@ -418,32 +418,21 @@ private void testBuildFederation( ); Federation expectedFederation; + List fedMembers = FederationTestUtils.getFederationMembersFromPks(privateKeys); + NetworkParameters btcParams = bridgeConstants.getBtcParams(); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, btcParams); + + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, 0L, btcParams, + erpPubKeys, activationDelay); + if (isRskip353Active) { - expectedFederation = FederationFactory.buildP2shErpFederation( - FederationTestUtils.getFederationMembersFromPks(privateKeys), - creationTime, - 0L, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + expectedFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); } else if (isRskip201Active) { - expectedFederation = FederationFactory.buildNonStandardErpFederation( - FederationTestUtils.getFederationMembersFromPks(privateKeys), - creationTime, - 0L, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay(), - activations - ); + expectedFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } else { - expectedFederation = FederationFactory.buildStandardMultiSigFederation( - FederationTestUtils.getFederationMembersFromPks(privateKeys), - creationTime, - 0L, - bridgeConstants.getBtcParams() - ); + expectedFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); } assertEquals(expectedFederation, builtFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java index b47dcb3d77d..dc7c72fd485 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java @@ -85,14 +85,10 @@ void createInvalidFederation_aboveMaxScriptSigSize() { Instant creationTime = federation.getCreationTime(); long creationBlockNumber = federation.getCreationBlockNumber(); NetworkParameters networkParameters = federation.getBtcParams(); + FederationArgs federationArgs = new FederationArgs(newMembers, creationTime, creationBlockNumber, networkParameters); ScriptCreationException exception = assertThrows(ScriptCreationException.class, - () -> FederationFactory.buildStandardMultiSigFederation( - newMembers, - creationTime, - creationBlockNumber, - networkParameters - )); + () -> FederationFactory.buildStandardMultiSigFederation(federationArgs)); assertEquals(ABOVE_MAX_SCRIPT_ELEMENT_SIZE, exception.getReason()); } @@ -126,46 +122,58 @@ void testEquals_basic() { @Test void testEquals_same() { - Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams() ); + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); assertEquals(federation, otherFederation); } @Test void testEquals_differentCreationTime() { - Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( federation.getMembers(), federation.getCreationTime().plus(1, ChronoUnit.MILLIS), federation.getCreationBlockNumber(), networkParameters ); + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); assertEquals(federation, otherFederation); } @Test void testEquals_differentCreationBlockNumber() { - Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber() + 1, networkParameters ); + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); assertEquals(federation, otherFederation); } @Test void testEquals_differentNetworkParameters() { - Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), NetworkParameters.fromID(NetworkParameters.ID_REGTEST) ); + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); // Different network parameters will result in a different address assertNotEquals(federation, otherFederation); } @@ -176,14 +184,17 @@ void testEquals_differentNumberOfMembers() { List newKeys = federation.getBtcPublicKeys(); newKeys.remove(14); List newMembers = FederationTestUtils.getFederationMembersWithKeys(newKeys); - - Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( newMembers, federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams() ); + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); + Assertions.assertNotEquals(federation, otherFederation); } @@ -200,13 +211,17 @@ void testEquals_differentMembers() { Instant creationTime = federation.getCreationTime(); long creationBlockNumber = federation.getCreationBlockNumber(); - Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + FederationArgs federationArgs = new FederationArgs( differentMembers, creationTime, creationBlockNumber, networkParameters ); + Federation otherFederation = FederationFactory.buildStandardMultiSigFederation( + federationArgs + ); + assertNotEquals(federation, otherFederation); } diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java index fa5c6135605..8a675d8fd31 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/ActiveFederationTest.java @@ -22,6 +22,7 @@ import co.rsk.bitcoinj.store.BtcBlockStore; import co.rsk.peg.*; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationFactory; import co.rsk.peg.federation.FederationMember; import org.ethereum.TestUtils; @@ -116,12 +117,15 @@ private BridgeStorageProviderInitializer buildInitializer(boolean genesis) { if (!genesis) { int numFederators = Helper.randomInRange(minFederators, maxFederators); List members = getNRandomFederationMembers(numFederators); + FederationArgs federationArgs = new FederationArgs( + members, + Instant.ofEpochMilli(TestUtils.generateLong(String.valueOf(executionIndex))), + Helper.randomInRange(1, 10), + networkParameters + ); federation = FederationFactory.buildStandardMultiSigFederation( - members, - Instant.ofEpochMilli(TestUtils.generateLong(String.valueOf(executionIndex))), - Helper.randomInRange(1, 10), - networkParameters + federationArgs ); provider.setNewFederation(federation); } else { diff --git a/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java index 87621156339..139d9bd7ae4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/performance/RetiringFederationTest.java @@ -22,6 +22,7 @@ import co.rsk.peg.Bridge; import co.rsk.peg.BridgeStorageProvider; import co.rsk.peg.federation.Federation; +import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationFactory; import org.ethereum.core.CallTransaction; import org.ethereum.core.Repository; @@ -104,11 +105,14 @@ private BridgeStorageProviderInitializer buildInitializer(boolean present) { return (BridgeStorageProvider provider, Repository repository, int executionIndex, BtcBlockStore blockStore) -> { if (present) { int numFederators = Helper.randomInRange(minFederators, maxFederators); + FederationArgs federationArgs = new FederationArgs( + ActiveFederationTest.getNRandomFederationMembers(numFederators), + Instant.ofEpochMilli(random.nextLong()), + Helper.randomInRange(1, 10), + networkParameters + ); retiringFederation = FederationFactory.buildStandardMultiSigFederation( - ActiveFederationTest.getNRandomFederationMembers(numFederators), - Instant.ofEpochMilli(random.nextLong()), - Helper.randomInRange(1, 10), - networkParameters + federationArgs ); provider.setNewFederation(bridgeConstants.getGenesisFederation()); provider.setOldFederation(retiringFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index bf61c46ca02..3c5998c905d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -23,11 +23,8 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.*; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.*; import co.rsk.peg.PegTestUtils; -import co.rsk.peg.federation.FederationMember; -import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.pegin.RejectedPeginReason; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -226,28 +223,20 @@ void logCommitFederation(boolean isRSKIP383Active) { ); List oldFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(oldFederationKeys); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs oldFedArgs = new FederationArgs(oldFederationMembers, Instant.ofEpochMilli(15005L), 15L, btcParams); - Federation oldFederation = FederationFactory.buildStandardMultiSigFederation( - oldFederationMembers, - Instant.ofEpochMilli(15005L), - 15L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); + Federation oldFederation = FederationFactory.buildStandardMultiSigFederation(oldFedArgs); List newFederationKeys = Arrays.asList( BtcECKey.fromPublicOnly(Hex.decode("0346cb6b905e4dee49a862eeb2288217d06afcd4ace4b5ca77ebedfbc6afc1c19d")), BtcECKey.fromPublicOnly(Hex.decode("0269a0dbe7b8f84d1b399103c466fb20531a56b1ad3a7b44fe419e74aad8c46db7")), BtcECKey.fromPublicOnly(Hex.decode("026192d8ab41bd402eb0431457f6756a3f3ce15c955c534d2b87f1e0372d8ba338")) ); - List newFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(newFederationKeys); + FederationArgs newFedArgs = new FederationArgs(newFederationMembers, Instant.ofEpochMilli(15005L), 15L, btcParams); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - newFederationMembers, - Instant.ofEpochMilli(5005L), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation(newFedArgs); // Act eventLogger.logCommitFederation(executionBlock, oldFederation, newFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java index 9d138a9d607..52c8419f8a5 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java @@ -24,11 +24,8 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.*; -import co.rsk.peg.federation.Federation; -import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.*; import co.rsk.peg.PegTestUtils; -import co.rsk.peg.federation.FederationMember; -import co.rsk.peg.federation.FederationTestUtils; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -211,24 +208,20 @@ void testLogCommitFederationBeforeRskip146() { ); List oldFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(oldFederationKeys); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs oldFedArgs = new FederationArgs(oldFederationMembers, Instant.ofEpochMilli(15005L), 15L, btcParams); - Federation oldFederation = FederationFactory.buildStandardMultiSigFederation(oldFederationMembers, - Instant.ofEpochMilli(15005L), 15L, NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); + Federation oldFederation = FederationFactory.buildStandardMultiSigFederation(oldFedArgs); List newFederationKeys = Arrays.asList( BtcECKey.fromPublicOnly(Hex.decode("0346cb6b905e4dee49a862eeb2288217d06afcd4ace4b5ca77ebedfbc6afc1c19d")), BtcECKey.fromPublicOnly(Hex.decode("0269a0dbe7b8f84d1b399103c466fb20531a56b1ad3a7b44fe419e74aad8c46db7")), BtcECKey.fromPublicOnly(Hex.decode("026192d8ab41bd402eb0431457f6756a3f3ce15c955c534d2b87f1e0372d8ba338")) ); - List newFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(newFederationKeys); + FederationArgs newFedArgs = new FederationArgs(newFederationMembers, Instant.ofEpochMilli(15005L), 15L, btcParams); - Federation newFederation = FederationFactory.buildStandardMultiSigFederation( - newFederationMembers, - Instant.ofEpochMilli(5005L), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); + Federation newFederation = FederationFactory.buildStandardMultiSigFederation(newFedArgs); // Act eventLogger.logCommitFederation(executionBlock, oldFederation, newFederation); From 01b4242d3d6db874ed990bec7227fb084b9635b0 Mon Sep 17 00:00:00 2001 From: julia zack Date: Tue, 9 Jan 2024 16:47:07 -0300 Subject: [PATCH 045/137] Create a method to build an ErpFederationArgs object from federation args and erp values. Use it whenever possible. --- .../co/rsk/peg/BridgeSerializationUtils.java | 16 +- .../rsk/peg/federation/ErpFederationArgs.java | 5 + .../co/rsk/peg/federation/Federation.java | 5 + .../rsk/peg/federation/PendingFederation.java | 5 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 12 +- .../BridgeStorageProviderFederationTests.java | 5 +- .../co/rsk/peg/BridgeStorageProviderTest.java | 69 ++--- ...idgeSupportRegisterBtcTransactionTest.java | 12 +- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 24 +- ...verCompatibleBtcWalletWithStorageTest.java | 3 +- ...patibleBtcWallextWithSingleScriptTest.java | 28 +- .../test/java/co/rsk/peg/PegTestUtils.java | 10 +- .../PegUtilsLegacyGetTransactionTypeTest.java | 47 ++-- .../java/co/rsk/peg/PegUtilsLegacyTest.java | 239 ++++++------------ .../test/java/co/rsk/peg/PegUtilsTest.java | 10 +- .../test/java/co/rsk/peg/PocSighashTest.java | 81 +++--- .../java/co/rsk/peg/PowpegMigrationTest.java | 5 +- .../peg/federation/FederationFactoryTest.java | 10 +- .../peg/federation/P2shErpFederationTest.java | 24 +- .../peg/federation/PendingFederationTest.java | 3 +- 20 files changed, 223 insertions(+), 390 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 8d179c4e11d..c22132e1b78 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -323,15 +323,11 @@ public static ErpFederation deserializeLegacyErpFederation( FederationMember::deserialize ); - List fedMembers = federation.getMembers(); - Instant creationTime = federation.getCreationTime(); - long creationBlockNumber = federation.getCreationBlockNumber(); - NetworkParameters btcParams = federation.getBtcParams(); + FederationArgs federationArgs = federation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } @@ -345,15 +341,11 @@ public static ErpFederation deserializeP2shErpFederation( FederationMember::deserialize ); - List fedMembers = federation.getMembers(); - Instant creationTime = federation.getCreationTime(); - long creationBlockNumber = federation.getCreationBlockNumber(); - NetworkParameters btcParams = federation.getBtcParams(); + FederationArgs federationArgs = federation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); return FederationFactory.buildP2shErpFederation(erpFederationArgs); } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java index d1ea623805b..1fae0ebcffd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java @@ -26,6 +26,11 @@ public ErpFederationArgs( this.activationDelay = activationDelay; } + public static ErpFederationArgs fromFederationArgs(FederationArgs federationArgs, List erpPubKeys, long activationDelay){ + return new ErpFederationArgs(federationArgs.members, federationArgs.creationTime, + federationArgs.creationBlockNumber, federationArgs.btcParams, erpPubKeys, activationDelay); + } + private void validateEmergencyKeys(List erpPubKeys) { if (erpPubKeys == null || erpPubKeys.isEmpty()) { String message = "Emergency keys are not provided"; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java index 7609e1bd12c..b5e0fa9d3f3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java @@ -39,6 +39,7 @@ */ public abstract class Federation { + protected final FederationArgs federationArgs; protected final List members; protected final Instant creationTime; protected final long creationBlockNumber; @@ -56,6 +57,7 @@ protected Federation( // Sorting members ensures same order of federation members for same members // Immutability provides protection against unwanted modification, thus making the Federation instance // effectively immutable + this.federationArgs = federationArgs; this.members = Collections.unmodifiableList(federationArgs.members.stream().sorted(FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR).collect(Collectors.toList())); this.creationTime = federationArgs.creationTime.truncatedTo(ChronoUnit.MILLIS); this.creationBlockNumber = federationArgs.creationBlockNumber; @@ -67,6 +69,9 @@ public int getFormatVersion() { return formatVersion; } + public FederationArgs getArgs() { + return federationArgs; + } public List getMembers() { // Safe to return members since // both list and instances are immutable diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index b98fe67438a..92e8efb0963 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -108,16 +108,17 @@ public Federation buildFederation( } NetworkParameters btcParams = bridgeConstants.getBtcParams(); + FederationArgs federationArgs = new FederationArgs(members, creationTime, blockNumber, btcParams); if (shouldBuildStandardMultisigFederation(activations)){ - FederationArgs federationArgs = new FederationArgs(members, creationTime, blockNumber, btcParams); return FederationFactory.buildStandardMultiSigFederation(federationArgs); } // should build and erp federation due to activations List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(members, creationTime, blockNumber, btcParams, erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); + if (shouldBuildNonStandardErpFederation(activations)) { logger.info("[buildFederation] Going to create an ERP Federation"); return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 8362cd83abb..81529b80f82 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -1138,16 +1138,12 @@ private void testSerializeAndDeserializeFederation( Federation testFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); byte[] serializedTestFederation = BridgeSerializationUtils.serializeFederation(testFederation); - Federation deserializedTestFederation = BridgeSerializationUtils.deserializeStandardMultisigFederation( - serializedTestFederation, - bridgeConstants.getBtcParams() - ); + Federation deserializedTestFederation = + BridgeSerializationUtils.deserializeStandardMultisigFederation(serializedTestFederation, bridgeConstants.getBtcParams()); + FederationArgs deserializedTestFederationArgs = deserializedTestFederation.getArgs(); ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(members, creationTime, creationBlockNumber, btcParams, - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + ErpFederationArgs.fromFederationArgs(deserializedTestFederationArgs, bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay()); Federation testErpFederation = FederationFactory.buildNonStandardErpFederation( erpFederationArgs, activations diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index 2efe898ad8b..68d4611a30e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -612,10 +612,11 @@ private Federation createFederation(int version) { return FederationFactory.buildStandardMultiSigFederation(federationArgs); } + // version should be erp List erpPubKeys = bridgeConstantsRegtest.getErpFedPubKeysList(); long activationDelay = bridgeConstantsRegtest.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(members, Instant.now(), 1L, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); + if (version == NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) { return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 7739c5cae06..2fe228327c9 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -405,17 +405,13 @@ void getNewFederation_multiKeyVersion() { void getNewFederation_erp_and_p2sh_erp_feds() { ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); Federation newFederation = buildMockFederation(100, 200, 300); - - List fedMembers = newFederation.getMembers(); - Instant creationTime = newFederation.getCreationTime(); - long creationBlockNumber = newFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + FederationArgs federationArgs = newFederation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); @@ -532,17 +528,13 @@ void saveNewFederation_postMultiKey() { void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); Federation newFederation = buildMockFederation(100, 200, 300); - - List fedMembers = newFederation.getMembers(); - Instant creationTime = newFederation.getCreationTime(); - long creationBlockNumber = newFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + FederationArgs federationArgs = newFederation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); testSaveNewFederationPostMultiKey(erpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); @@ -551,17 +543,13 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { @Test void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { Federation newFederation = buildMockFederation(100, 200, 300); - - List fedMembers = newFederation.getMembers(); - Instant creationTime = newFederation.getCreationTime(); - long creationBlockNumber = newFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + FederationArgs federationArgs = newFederation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); testSaveNewFederationPostMultiKey(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activationsAllForks); @@ -667,16 +655,13 @@ void getOldFederation_multiKeyVersion() { @Test void getOldFederation_nonStandard_feds() { Federation oldFederation = buildMockFederation(100, 200, 300); - List fedMembers = oldFederation.getMembers(); - Instant creationTime = oldFederation.getCreationTime(); - long creationBlockNumber = oldFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + FederationArgs federationArgs = oldFederation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); // this should get non-standard hardcoded fed ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); @@ -696,17 +681,13 @@ void getOldFederation_nonStandard_feds() { @Test void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { Federation oldFederation = buildMockFederation(100, 200, 300); - - List fedMembers = oldFederation.getMembers(); - Instant creationTime = oldFederation.getCreationTime(); - long creationBlockNumber = oldFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + FederationArgs federationArgs = oldFederation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @@ -822,16 +803,13 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); Federation oldFederation = buildMockFederation(100, 200, 300); - List fedMembers = oldFederation.getMembers(); - Instant creationTime = oldFederation.getCreationTime(); - long creationBlockNumber = oldFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + FederationArgs federationArgs = oldFederation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); testSaveOldFederation(erpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); @@ -839,18 +817,13 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { @Test void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { - Federation oldFederation = buildMockFederation(100, 200, 300); - List fedMembers = oldFederation.getMembers(); - Instant creationTime = oldFederation.getCreationTime(); - long creationBlockNumber = oldFederation.getCreationBlockNumber(); BridgeConstants bridgeConstants = bridgeTestnetInstance; - NetworkParameters btcParams = bridgeConstants.getBtcParams(); + + FederationArgs federationArgs = oldFederation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, creationBlockNumber, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); testSaveOldFederation(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activationsAllForks); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index a5b77540b21..f9e07fc66b9 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -354,10 +354,13 @@ void init() throws IOException { retiringFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); List retiringFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedSigners); + Instant creationTime = Instant.ofEpochMilli(1000L); + long retiringFedCreationBlockNumber = 1; List erpPubKeys = bridgeMainnetConstants.getErpFedPubKeysList(); long activationDelay = bridgeMainnetConstants.getErpFedActivationDelay(); - ErpFederationArgs retiringFedArgs = new ErpFederationArgs(retiringFedMembers, Instant.ofEpochMilli(1000L), 1, btcParams, - erpPubKeys, activationDelay); + + ErpFederationArgs retiringFedArgs = + new ErpFederationArgs(retiringFedMembers, creationTime, retiringFedCreationBlockNumber, btcParams, erpPubKeys, activationDelay); retiringFederation = FederationFactory.buildP2shErpFederation(retiringFedArgs); activeFedSigners = BitcoinTestUtils.getBtcEcKeysFromSeeds( @@ -365,8 +368,9 @@ void init() throws IOException { ); activeFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFedSigners); - ErpFederationArgs activeFedArgs = new ErpFederationArgs(activeFedMembers, Instant.ofEpochMilli(1000L), 2L, btcParams, - erpPubKeys, activationDelay); + long activeFedCreationBlockNumber = 2L; + ErpFederationArgs activeFedArgs = + new ErpFederationArgs(activeFedMembers, creationTime, activeFedCreationBlockNumber, btcParams, erpPubKeys, activationDelay); activeFederation = FederationFactory.buildP2shErpFederation(activeFedArgs); mockFactory = mock(BtcBlockStoreWithCache.Factory.class); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index e54aabe6ec0..c9d2b62e611 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -1474,14 +1474,11 @@ private Genesis getGenesisInstance(TrieStore trieStore) { private ErpFederation createErpFederation() { Federation genesisFederation = bridgeConstantsRegtest.getGenesisFederation(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( - genesisFederation.getMembers(), - genesisFederation.getCreationTime(), - genesisFederation.getCreationBlockNumber(), - genesisFederation.getBtcParams(), - bridgeConstantsRegtest.getErpFedPubKeysList(), - bridgeConstantsRegtest.getErpFedActivationDelay() - ); + FederationArgs genesisFederationArgs = genesisFederation.getArgs(); + List erpPubKeys = bridgeConstantsRegtest.getErpFedPubKeysList(); + long activationDelay = bridgeConstantsRegtest.getErpFedActivationDelay(); + + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(genesisFederationArgs, erpPubKeys, activationDelay); return FederationFactory.buildNonStandardErpFederation( erpFederationArgs, activations @@ -1618,17 +1615,6 @@ private byte[] generatePrivKey() { return privKey; } - private void signWithErpFederation(Federation erpFederation, List privateKeys, TransactionInput txIn, BtcTransaction tx) { - signWithNecessaryKeys(erpFederation, privateKeys, txIn, tx); - // Add OP_0 prefix to make it a valid erp federation script - Script erpInputScript = new ScriptBuilder() - .number(ScriptOpCodes.OP_0) - .addChunks(txIn.getScriptSig().getChunks()) - .build(); - - txIn.setScriptSig(erpInputScript); - } - private void signWithNecessaryKeys( Federation federation, List privateKeys, diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java index 58bb82376ca..d6765f335e0 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java @@ -49,8 +49,7 @@ void setup() { federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); long activationDelay = 5063; - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000), 0L, btcParams, - erpFedKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFedKeys, activationDelay); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java index f1c2c936c3a..591c45ae855 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java @@ -41,15 +41,11 @@ class FlyoverCompatibleBtcWallextWithSingleScriptTest { @BeforeEach void setup() { - FederationArgs federationArgs = new FederationArgs( - FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST) - ); - federation = FederationFactory.buildStandardMultiSigFederation( - federationArgs - ); + List fedMembers = FederationTestUtils.getFederationMembers(3); + Instant creationTime = Instant.ofEpochMilli(1000); + NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, btcParams); + federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); @@ -57,18 +53,8 @@ void setup() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( - FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST), - erpFedKeys, - 5063 - ); - erpFederation = FederationFactory.buildNonStandardErpFederation( - erpFederationArgs, - activations - ); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFedKeys, 5063); + erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); federationList = Collections.singletonList(federation); erpFederationList = Collections.singletonList(erpFederation); diff --git a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java index 31fd5d1ad8a..deca10614d6 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java @@ -300,19 +300,23 @@ public static Federation createFederation(BridgeConstants bridgeConstants, Strin public static Federation createFederation(BridgeConstants bridgeConstants, List federationKeys) { federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys); + Instant creationTime = Instant.ofEpochMilli(1000L); NetworkParameters btcParams = bridgeConstants.getBtcParams(); - FederationArgs federationArgs = new FederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcParams); + + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, btcParams); return FederationFactory.buildStandardMultiSigFederation(federationArgs); } public static ErpFederation createP2shErpFederation(BridgeConstants bridgeConstants, List federationKeys) { federationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(federationKeys); + Instant creationTime = Instant.ofEpochMilli(1000L); NetworkParameters btcParams = bridgeConstants.getBtcParams(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcParams, - erpPubKeys, activationDelay); + + ErpFederationArgs erpFederationArgs = new + ErpFederationArgs(fedMembers, creationTime, 0L, btcParams, erpPubKeys, activationDelay); return FederationFactory.buildP2shErpFederation(erpFederationArgs); } diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java index e818e211175..45dcf06fe93 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java @@ -63,31 +63,26 @@ void test_sentFromP2SHErpFed() { federator3PublicKey, federator4PublicKey, federator5PublicKey, federator6PublicKey, federator7PublicKey, federator8PublicKey ); - ErpFederationArgs activeErpFedArgs = new ErpFederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys), - bridgeMainnetConstants.getGenesisFederation().getCreationTime(), - 5L, - bridgeMainnetConstants.getGenesisFederation().getBtcParams(), - bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay() - ); + + List federationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(standardKeys); + Federation genesisFederation = bridgeMainnetConstants.getGenesisFederation(); + List erpPubKeys = bridgeMainnetConstants.getErpFedPubKeysList(); + long activationDelay = bridgeMainnetConstants.getErpFedActivationDelay(); + + ErpFederationArgs activeErpFedArgs = + new ErpFederationArgs(federationMembers, genesisFederation.getCreationTime(), 5L, btcMainnetParams, erpPubKeys, activationDelay); // Arrange - ErpFederation activeFederation = FederationFactory.buildP2shErpFederation( - activeErpFedArgs - ); + ErpFederation activeFederation = FederationFactory.buildP2shErpFederation(activeErpFedArgs); List fedKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true ); - ErpFederationArgs retiringErpFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys), - Instant.ofEpochMilli(1000L), - 0L, - btcMainnetParams, - bridgeMainnetConstants.getErpFedPubKeysList(), - bridgeMainnetConstants.getErpFedActivationDelay() - ); + List retiringFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys); + Instant creationTime = Instant.ofEpochMilli(1000L); + ErpFederationArgs retiringErpFedArgs = + new ErpFederationArgs(retiringFedMembers, creationTime, 0L, btcMainnetParams, erpPubKeys, activationDelay); ErpFederation p2shRetiringFederation = FederationFactory.buildP2shErpFederation( retiringErpFedArgs ); @@ -345,17 +340,11 @@ void test_pegin( new String[]{"fa04", "fa05", "fa06"}, true ); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(activeFedKeys), - Instant.ofEpochMilli(1000L), - 0L, - btcMainnetParams, - erpFedKeys, - 100L - ); - ErpFederation activeFederation = FederationFactory.buildP2shErpFederation( - erpFederationArgs - ); + List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFedKeys); + Instant creationTime = Instant.ofEpochMilli(1000L); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(activeFedMembers, creationTime, 0L, btcMainnetParams, erpFedKeys, 100L); + ErpFederation activeFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); BtcTransaction peginTx = new BtcTransaction(btcMainnetParams); peginTx.addInput(BitcoinTestUtils.createHash(1), 0, new Script(new byte[]{})); diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java index a47f5146df7..b71ac5b9a60 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java @@ -37,6 +37,7 @@ class PegUtilsLegacyTest { private BridgeConstants bridgeConstantsRegtest; private BridgeConstants bridgeConstantsMainnet; private NetworkParameters networkParameters; + private final Instant creationTime = Instant.ofEpochMilli(1000L); @BeforeEach void setupConfig() { @@ -210,7 +211,7 @@ void testIsValidPegInTxForTwoFederations() { ); federation1Keys.sort(BtcECKey.PUBKEY_COMPARATOR); List fed1Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys); - FederationArgs federation1Args = new FederationArgs(fed1Members, Instant.ofEpochMilli(1000L), 0L, btcParams); + FederationArgs federation1Args = new FederationArgs(fed1Members, creationTime, 0L, btcParams); Federation federation1 = FederationFactory.buildStandardMultiSigFederation(federation1Args); List federation2Keys = Arrays.asList( @@ -220,7 +221,7 @@ void testIsValidPegInTxForTwoFederations() { ); federation2Keys.sort(BtcECKey.PUBKEY_COMPARATOR); List fed2Members = FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys); - FederationArgs federation2Args = new FederationArgs(fed2Members, Instant.ofEpochMilli(1000L), 0L, btcParams); + FederationArgs federation2Args = new FederationArgs(fed2Members, creationTime, 0L, btcParams); Federation federation2 = FederationFactory.buildStandardMultiSigFederation(federation2Args); Address address1 = federation1.getAddress(); @@ -527,10 +528,10 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_beforeRskip201_isP when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(false); Context btcContext = new Context(networkParameters); - NetworkParameters btcParams = btcContext.getParams(); Federation activeFederation = bridgeConstantsRegtest.getGenesisFederation(); - List fedMembers = activeFederation.getMembers(); + FederationArgs federationArgs = activeFederation.getArgs(); + List erpPubKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) @@ -538,8 +539,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_beforeRskip201_isP erpPubKeys.sort(BtcECKey.PUBKEY_COMPARATOR); long activationDelay = 500L; - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); Script redeemScript = erpFederation.getRedeemScript(); @@ -577,7 +577,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_afterRskip201_notP erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); List erpFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys); - FederationArgs args = new FederationArgs(erpFedMembers, Instant.ofEpochMilli(1000L), 0L, networkParameters); + FederationArgs args = new FederationArgs(erpFedMembers, creationTime, 0L, networkParameters); Federation erpFederation = FederationFactory.buildStandardMultiSigFederation(args); Script erpRedeemScript = ErpFederationRedeemScriptParser.createErpRedeemScript( @@ -619,7 +619,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpFederation_beforeRskip201_isPegin() erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 0L, networkParameters ); @@ -657,7 +657,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpFederation_afterRskip201_notPegin() erpFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 0L, networkParameters ); @@ -695,7 +695,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverRetiredFederation_beforeRskip201 retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 0L, networkParameters ); @@ -745,7 +745,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverRetiredFederation_afterRskip201_ retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); FederationArgs args = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 0L, networkParameters ); @@ -793,29 +793,17 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_beforeRskip BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - FederationArgs args = new FederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( - args - ); + List retiredFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys); + + FederationArgs retiredFederationArgs = new FederationArgs(retiredFederationMembers, creationTime, 0L, networkParameters); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation(retiredFederationArgs); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), BtcECKey.fromPrivate(Hex.decode("fa04")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters, - erpFederationPublicKeys, - 500L - ); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired fast bridge fed to the active fed @@ -858,15 +846,10 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - FederationArgs args = new FederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( - args - ); + + List retiredFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys); + FederationArgs retiredFederationArgs = new FederationArgs(retiredFederationMembers, creationTime, 0L, networkParameters); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation(retiredFederationArgs); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), @@ -874,14 +857,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters, - erpFederationPublicKeys, - 500L - ); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired fast bridge fed to the active fed @@ -923,15 +899,10 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - FederationArgs args = new FederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( - args - ); + + List retiredFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys); + FederationArgs retiredFederationArgs = new FederationArgs(retiredFederationMembers, creationTime, 0L, networkParameters); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation(retiredFederationArgs); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), @@ -939,14 +910,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters, - erpFederationPublicKeys, - 500L - ); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired erp fed to the active fed @@ -984,33 +948,18 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_afterRskip201_notP BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - FederationArgs retiredFedArgs = new FederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); - Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation( - retiredFedArgs - ); + + List retiredFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys); + FederationArgs retiredFedArgs = new FederationArgs(retiredFederationMembers, creationTime, 0L, networkParameters); + Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation(retiredFedArgs); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), BtcECKey.fromPrivate(Hex.decode("fa04")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpFedArgs = new ErpFederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters, - erpFederationPublicKeys, - 500L - ); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( - erpFedArgs, - activations - ); + ErpFederationArgs erpFedArgs = ErpFederationArgs.fromFederationArgs(retiredFedArgs, erpFederationPublicKeys, 500L); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFedArgs, activations); // Create a tx from the retired erp fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -1247,20 +1196,13 @@ private void testIsValidPegInTx_fromP2shErpScriptSender( Context btcContext = new Context(networkParameters); Federation activeFederation = bridgeConstantsRegtest.getGenesisFederation(); + FederationArgs activeFederationArgs = activeFederation.getArgs(); List emergencyKeys = PegTestUtils.createRandomBtcECKeys(3); long activationDelay = 256L; - ErpFederationArgs args = new ErpFederationArgs(activeFederation.getMembers(), - activeFederation.getCreationTime(), - activeFederation.getCreationBlockNumber(), - networkParameters, - emergencyKeys, - activationDelay - ); - Federation p2shErpFederation = FederationFactory.buildP2shErpFederation( - args - ); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(activeFederationArgs, emergencyKeys, activationDelay); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); Script flyoverP2shErpRedeemScript = FastBridgeP2shErpRedeemScriptParser.createFastBridgeP2shErpRedeemScript( p2shErpFederation.getRedeemScript(), @@ -1321,7 +1263,7 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() ErpFederationArgs retiredFedArgs = new ErpFederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), @@ -1337,7 +1279,7 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), @@ -1389,34 +1331,27 @@ void testIsMigrationTx_sending_funds_from_retiring_p2sh_fed_to_active_p2sh_fed() Context btcContext = new Context(networkParameters); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - List retiringFed = Stream.of( + List retiringFedKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fc01")), BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - ErpFederationArgs retiringFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFed), - Instant.ofEpochMilli(1000L), - 1L, - bridgeConstantsMainnet.getBtcParams(), - bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay() - ); - Federation retiringFederation = FederationFactory.buildP2shErpFederation( - retiringFedArgs - ); + List retiringFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiringFedKeys); + NetworkParameters btcParams = bridgeConstantsMainnet.getBtcParams(); + List erpPubKeys = bridgeConstantsMainnet.getErpFedPubKeysList(); + long activationDelay = bridgeConstantsMainnet.getErpFedActivationDelay(); + + ErpFederationArgs retiringFedArgs = + new ErpFederationArgs(retiringFedMembers, creationTime, 1L, btcParams, erpPubKeys, activationDelay); + Federation retiringFederation = FederationFactory.buildP2shErpFederation(retiringFedArgs); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - - ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), - 1L, - bridgeConstantsMainnet.getBtcParams(), - bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay() - ); + List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); + ErpFederationArgs activeFedArgs = + new ErpFederationArgs(activeFedMembers, creationTime, 1L, btcParams, erpPubKeys, activationDelay); Federation activeFederation = FederationFactory.buildP2shErpFederation( activeFedArgs ); @@ -1432,7 +1367,7 @@ void testIsMigrationTx_sending_funds_from_retiring_p2sh_fed_to_active_p2sh_fed() new TransactionOutPoint(networkParameters, 0, Sha256Hash.ZERO_HASH) ); migrationTx.addInput(migrationTxInput); - signWithNecessaryKeys(retiringFederation, retiringFed, migrationTxInput, migrationTx); + signWithNecessaryKeys(retiringFederation, retiringFedKeys, migrationTxInput, migrationTx); Wallet federationsWallet = new BridgeBtcWallet(btcContext, Arrays.asList(activeFederation, retiringFederation)); @@ -1459,7 +1394,7 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_p2sh_fe ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); FederationArgs retiredFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams() ); @@ -1473,7 +1408,7 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_p2sh_fe ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), @@ -1531,7 +1466,7 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_p2sh_f ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); FederationArgs retiringFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams() ); @@ -1545,7 +1480,7 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_p2sh_f ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams(), bridgeConstantsMainnet.getErpFedPubKeysList(), @@ -1593,7 +1528,7 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_standar ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); FederationArgs retiredFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams() ); @@ -1607,7 +1542,7 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_standar ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); FederationArgs activeFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams() ); @@ -1664,7 +1599,7 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_standa FederationArgs retiringFedArgs = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams() ); @@ -1678,7 +1613,7 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_standa ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); FederationArgs activeFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, bridgeConstantsMainnet.getBtcParams() ); @@ -1737,7 +1672,7 @@ void testIsMigrationTx() { ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); FederationArgs retiringFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, networkParameters ); @@ -1750,7 +1685,7 @@ void testIsMigrationTx() { BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); FederationArgs retiredFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 1L, networkParameters ); @@ -1927,7 +1862,7 @@ void testIsPegOutTx_fromFlyoverFederation() { ); flyoverFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); FederationArgs args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(flyoverFederationKeys), - Instant.ofEpochMilli(1000L), + creationTime, 0L, networkParameters ); @@ -1986,14 +1921,10 @@ void testIsPegOutTx_fromErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa03")) ); defaultFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - FederationArgs args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); - Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation( - args - ); + List federationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys); + + FederationArgs federationArgs = new FederationArgs(federationMembers, creationTime, 0L, networkParameters); + Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), @@ -2001,17 +1932,8 @@ void testIsPegOutTx_fromErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa05")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters, - erpFederationPublicKeys, - 500L - ); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation( - erpArgs, - activations - ); + ErpFederationArgs erpArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFederationPublicKeys, 500L); + ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpArgs, activations); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -2065,14 +1987,10 @@ void testIsPegOutTx_fromFlyoverErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa03")) ); defaultFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - FederationArgs args = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters - ); - Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation( - args - ); + + List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, networkParameters); + Federation defaultFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); List erpFederationPublicKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa03")), @@ -2081,17 +1999,8 @@ void testIsPegOutTx_fromFlyoverErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), - Instant.ofEpochMilli(1000L), - 0L, - networkParameters, - erpFederationPublicKeys, - 500L - ); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( - erpArgs, - activations - ); + ErpFederationArgs erpArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFederationPublicKeys, 500L); + Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpArgs, activations); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -2185,7 +2094,7 @@ void testChangeBetweenFederations() { .collect(Collectors.toList()); FederationArgs args1 = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), - Instant.ofEpochMilli(1000L), + creationTime, 0L, networkParameters ); 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 686b2819a91..88bb865a0e2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java @@ -205,10 +205,11 @@ void test_getTransactionType_pegin_output_to_retiring_fed_and_other_addresses() new String[]{"fa01", "fa02", "fa03"}, true ); List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(signers); + Instant creationTime = Instant.ofEpochMilli(1000L); List erpPubKeys = bridgeMainnetConstants.getErpFedPubKeysList(); long activationDelay = bridgeMainnetConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcMainnetParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(fedMembers, creationTime, 0L, btcMainnetParams, erpPubKeys, activationDelay); ErpFederation activeFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); @@ -605,11 +606,12 @@ void test_getTransactionType_flyover_segwit() { new String[]{"fa01", "fa02", "fa03"}, true ); List fedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(signers); + Instant creationTime = Instant.ofEpochMilli(1000L); List erpPubKeys = bridgeTestNetConstants.getErpFedPubKeysList(); long activationDelay = bridgeTestNetConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, Instant.ofEpochMilli(1000L), 0L, btcTestNetParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(fedMembers, creationTime, 0L, btcTestNetParams, erpPubKeys, activationDelay); ErpFederation activeFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); diff --git a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java index c46051a438f..3a1e0026534 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java @@ -63,15 +63,11 @@ void test_each_input_sighash_is_unique(NetworkParameters networkParameters) { when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); List fedMembers = fedSigners.stream().map(FedSigner::getFed).collect(Collectors.toList()); + Instant creationTime = Instant.now(); List erpFedPubKeys = erpFedSigners.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, - Instant.now(), - 0L, - networkParameters, - erpFedPubKeys, - erpFedActivationDelay - ); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(fedMembers, creationTime, 0L, networkParameters, erpFedPubKeys, erpFedActivationDelay); ErpFederation fed = FederationFactory.buildP2shErpFederation( erpFederationArgs ); @@ -133,27 +129,23 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam // Arrange int erpFedActivationDelay = 720; - List fedMembers = FedSigner.listOf("fed1", "fed2", "fed3", "fed4", "fed5", "fed6", "fed7"); - List erpFedMembers = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); + List fedSigners = FedSigner.listOf("fed1", "fed2", "fed3", "fed4", "fed5", "fed6", "fed7"); + List fedMembers = fedSigners.stream().map(FedSigner::getFed).collect(Collectors.toList()); + Instant creationTime = Instant.now(); + List erpSigners = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); + List erpPubKeys = erpSigners.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), - Instant.now(), - 0L, - networkParameters, - erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), - erpFedActivationDelay - ); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - erpFederationArgs - ); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(fedMembers, creationTime, 0L, networkParameters, erpPubKeys, erpFedActivationDelay); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); List utxos = new ArrayList<>(); BtcTransaction peginTx = new BtcTransaction(networkParameters); - peginTx.addOutput(Coin.valueOf(100_000), fed.getAddress()); + peginTx.addOutput(Coin.valueOf(100_000), p2shErpFederation.getAddress()); utxos.add(FedUtxo.of(peginTx, 0)); Address destinationAddress = PegTestUtils.createRandomP2PKHBtcAddress(networkParameters); @@ -164,8 +156,8 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam BtcTransaction pegOutTx = spendFromFed( networkParameters, erpFedActivationDelay, - fed, - fedMembers, + p2shErpFederation, + fedSigners, false, utxos, totalAmount.minus(Coin.valueOf(15_000)), @@ -180,7 +172,7 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam for (int i = 0; i < pegOutTx.getInputs().size(); i++) { Sha256Hash sighashFromSignedTx = pegOutTx.hashForSignature( i, - fed.getRedeemScript(), + p2shErpFederation.getRedeemScript(), BtcTransaction.SigHash.ALL, false ); @@ -189,7 +181,7 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam BtcTransaction peginTx2 = new BtcTransaction(networkParameters); - peginTx2.addOutput(Coin.valueOf(100_000), fed.getAddress()); + peginTx2.addOutput(Coin.valueOf(100_000), p2shErpFederation.getAddress()); utxos.add(FedUtxo.of(peginTx2, 0)); Coin alteredTxTotalAmount = utxos.stream().map(fedUtxo -> fedUtxo.btcTransaction.getOutput(fedUtxo.getOutputIdx()).getValue()).reduce(Coin.ZERO, Coin::add); @@ -198,8 +190,8 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam spendFromFed( networkParameters, erpFedActivationDelay, - fed, - fedMembers, + p2shErpFederation, + fedSigners, false, utxos, alteredTxTotalAmount.minus(Coin.valueOf(15_000)), @@ -231,23 +223,19 @@ void test_sighash_is_equal_for_signed_input_and_unsigned_input(NetworkParameters // Arrange int erpFedActivationDelay = 720; - List fedMembers = FedSigner.listOf("fed1", "fed2", "fed3"); - List erpFedMembers = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); + List fedSigners = FedSigner.listOf("fed1", "fed2", "fed3"); + List fedMembers = fedSigners.stream().map(FedSigner::getFed).collect(Collectors.toList()); + Instant creationTime = Instant.now(); + List erpSigners = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); + List erpPubKeys = erpSigners.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), - Instant.now(), - 0L, - networkParameters, - erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), - erpFedActivationDelay - ); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - erpFederationArgs - ); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(fedMembers, creationTime, 0L, networkParameters, erpPubKeys, erpFedActivationDelay); + ErpFederation fed = FederationFactory.buildP2shErpFederation(erpFederationArgs); List utxos = new ArrayList<>(); for (int i = 0; i < 7; i++) { @@ -265,7 +253,7 @@ void test_sighash_is_equal_for_signed_input_and_unsigned_input(NetworkParameters networkParameters, erpFedActivationDelay, fed, - fedMembers, + fedSigners, false, utxos, totalAmount.minus(Coin.valueOf(15_000)), @@ -381,21 +369,18 @@ void test_each_input_sighash_is_unique_for_a_signed_erp_tx_testnet() { NetworkParameters networkParameters = BridgeTestNetConstants.getInstance().getBtcParams(); int erpFedActivationDelay = 720; - List fedMembers = FedSigner.listOf("federator1", "federator2", "federator6"); + List fedSigners = FedSigner.listOf("federator1", "federator2", "federator6"); + List fedMembers = fedSigners.stream().map(FedSigner::getFed).collect(Collectors.toList()); + Instant creationTime = Instant.now(); List erpFedMembers = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); - List fedPubKeys = erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); + List erpPubKeys = erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), - Instant.now(), - 0L, - networkParameters, - fedPubKeys, - erpFedActivationDelay - ); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(fedMembers, creationTime, 0L, networkParameters, erpPubKeys, erpFedActivationDelay); ErpFederation fed = FederationFactory.buildP2shErpFederation( erpFederationArgs ); diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index da83208733f..7f72a8aeed2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -134,8 +134,9 @@ private void testChangePowpeg( long activationDelay = bridgeConstants.getErpFedActivationDelay(); Federation originalPowpeg; - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(originalPowpegMembers, Instant.now(), 0, btcParams, - erpPubKeys, activationDelay); + Instant creationTime = Instant.now(); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(originalPowpegMembers, creationTime, 0, btcParams, erpPubKeys, activationDelay); switch (oldPowPegFederationType) { case legacyErp: originalPowpeg = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java index 5b0a059794c..4d4a3eaef98 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java @@ -177,16 +177,14 @@ private Federation createStandardMultisigFederation() { } private ErpFederation createNonStandardErpFederation() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters, - emergencyKeys, activationDelayValue - ); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue); return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } private ErpFederation createP2shErpFederation() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters, - emergencyKeys, activationDelayValue - ); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue); return FederationFactory.buildP2shErpFederation(erpFederationArgs); } diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java index 185cbabe3ac..6f6732f30a8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java @@ -81,9 +81,8 @@ private ErpFederation createDefaultP2shErpFederation() { List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(defaultKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(standardMembers, creationTime, creationBlockNumber, networkParameters, - emergencyKeys, activationDelayValue - ); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(standardMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue); return FederationFactory.buildP2shErpFederation(erpFederationArgs); } @@ -223,9 +222,8 @@ void testEquals_basic() { @Test void testEquals_same() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), federation.getBtcParams(), - federation.getErpPubKeys(), federation.getActivationDelay() - ); + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime(), + federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay()); ErpFederation otherFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); assertEquals(federation, otherFederation); @@ -337,12 +335,12 @@ void getStandardRedeemScript() { Instant creationTime = Instant.now(); int creationBlock = 0; FederationArgs federationArgs = new FederationArgs(members, creationTime, creationBlock, btcParams); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(members, creationTime, creationBlock, btcParams, - Arrays.asList(new BtcECKey(), new BtcECKey()), - 10_000); // Create a standard multisig powpeg and then a p2sh valid one. Both of them should produce the same default redeem script StandardMultisigFederation standardMultisigFed = FederationFactory.buildStandardMultiSigFederation(federationArgs); + + List erpPubKeys = Arrays.asList(new BtcECKey(), new BtcECKey()); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, 10_000); ErpFederation p2shFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); assertEquals(standardMultisigFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); @@ -472,16 +470,16 @@ void spendFromP2shErpFed( new String[]{"fed1", "fed2", "fed3", "fed4", "fed5", "fed6", "fed7", "fed8", "fed9", "fed10"}, true ); + List federationMembers = FederationMember.getFederationMembersFromKeys(defaultKeys); + Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); List emergencyKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"erp1", "erp2", "erp3", "erp4"}, true ); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( - FederationMember.getFederationMembersFromKeys(defaultKeys), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), - 0L, networkParameters, emergencyKeys, activationDelay - ); + ErpFederationArgs erpFederationArgs = + new ErpFederationArgs(federationMembers, creationTime, 0L, networkParameters, emergencyKeys, activationDelay); ErpFederation p2shErpFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); Coin value = Coin.valueOf(1_000_000); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java index a2de74b9797..8df4e733763 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java @@ -424,8 +424,7 @@ private void testBuildFederation( List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, creationTime, 0L, btcParams, - erpPubKeys, activationDelay); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); if (isRskip353Active) { expectedFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); From eae2dd99569d9d6eff78e2a45577bb8505cf4b68 Mon Sep 17 00:00:00 2001 From: julia zack Date: Mon, 8 Jan 2024 13:50:11 -0300 Subject: [PATCH 046/137] Rename legacy / legacy erp / erp to non standard erp due to refactors --- .../co/rsk/peg/BridgeSerializationUtils.java | 2 +- .../co/rsk/peg/BridgeStorageProvider.java | 2 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 50 ++--- .../BridgeStorageProviderFederationTests.java | 32 +-- .../co/rsk/peg/BridgeStorageProviderTest.java | 32 +-- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 42 ++-- ...verCompatibleBtcWalletWithStorageTest.java | 27 ++- ...patibleBtcWallextWithSingleScriptTest.java | 24 +-- .../java/co/rsk/peg/PegUtilsLegacyTest.java | 58 ++--- .../java/co/rsk/peg/PowpegMigrationTest.java | 16 +- .../peg/ReleaseTransactionBuilderTest.java | 12 +- .../NonStandardErpFederationsTest.java | 198 +++++++++--------- 12 files changed, 247 insertions(+), 248 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index c22132e1b78..45c61a82d2e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -312,7 +312,7 @@ public static StandardMultisigFederation deserializeStandardMultisigFederation( FederationMember::deserialize ); } - public static ErpFederation deserializeLegacyErpFederation( + public static ErpFederation deserializeNonStandardErpFederation( byte[] data, BridgeConstants bridgeConstants, ActivationConfig.ForBlock activations diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 348896e43f2..ec67eb953f8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -1078,7 +1078,7 @@ private Federation deserializeFederationAccordingToVersion( ); } if (version == NON_STANDARD_ERP_FEDERATION.getFormatVersion()) { - return BridgeSerializationUtils.deserializeLegacyErpFederation( + return BridgeSerializationUtils.deserializeNonStandardErpFederation( data, bridgeConstants, activations diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 81529b80f82..1e3cc097e13 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -170,16 +170,16 @@ void serializeFederationOnlyBtcKeys() throws Exception { creationBlockNumber, btcParams ); - Federation federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); + Federation standardMultisigFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); - byte[] result = BridgeSerializationUtils.serializeFederationOnlyBtcKeys(federation); + byte[] result = BridgeSerializationUtils.serializeFederationOnlyBtcKeys(standardMultisigFederation); StringBuilder expectedBuilder = new StringBuilder(); expectedBuilder.append("f8d3"); // Outer list expectedBuilder.append("83abcdef"); // Creation time expectedBuilder.append("2a"); // Creation block number expectedBuilder.append("f8cc"); // Inner list - federation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { + standardMultisigFederation.getBtcPublicKeys().stream().sorted(BtcECKey.PUBKEY_COMPARATOR).forEach(key -> { expectedBuilder.append("a1"); expectedBuilder.append(ByteUtil.toHexString(key.getPubKey())); }); @@ -315,8 +315,8 @@ void serializeFederation_serializedKeysAreCompressedAndThree() { FederationArgs federationArgs = new FederationArgs(members, creationTime, creationBlockNumber, btcParams); - Federation testFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); - byte[] serializedFederation = BridgeSerializationUtils.serializeFederation(testFederation); + Federation testStandardMultisigFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); + byte[] serializedFederation = BridgeSerializationUtils.serializeFederation(testStandardMultisigFederation); RLPList serializedList = (RLPList) RLP.decode2(serializedFederation).get(0); Assertions.assertEquals(3, serializedList.size()); @@ -682,11 +682,11 @@ void serializeAndDeserializeFederationOnlyBtcKeysWithRealRLP() { )); FederationArgs federationArgs = new FederationArgs(members, Instant.ofEpochMilli(0xabcdef), 42L, networkParams); - Federation federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); + Federation standardMultisigFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); - byte[] result = BridgeSerializationUtils.serializeFederationOnlyBtcKeys(federation); + byte[] result = BridgeSerializationUtils.serializeFederationOnlyBtcKeys(standardMultisigFederation); Federation deserializedFederation = BridgeSerializationUtils.deserializeStandardMultisigFederationOnlyBtcKeys(result, networkParams); - MatcherAssert.assertThat(federation, is(deserializedFederation)); + MatcherAssert.assertThat(standardMultisigFederation, is(deserializedFederation)); } @Test @@ -1135,34 +1135,34 @@ private void testSerializeAndDeserializeFederation( FederationArgs federationArgs = new FederationArgs(members, creationTime, creationBlockNumber, btcParams); - Federation testFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); - byte[] serializedTestFederation = BridgeSerializationUtils.serializeFederation(testFederation); + Federation testStandardMultisigFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); + byte[] serializedTestStandardMultisigFederation = BridgeSerializationUtils.serializeFederation(testStandardMultisigFederation); - Federation deserializedTestFederation = - BridgeSerializationUtils.deserializeStandardMultisigFederation(serializedTestFederation, bridgeConstants.getBtcParams()); - FederationArgs deserializedTestFederationArgs = deserializedTestFederation.getArgs(); + Federation deserializedTestStandardMultisigFederation = + BridgeSerializationUtils.deserializeStandardMultisigFederation(serializedTestStandardMultisigFederation, bridgeConstants.getBtcParams()); + FederationArgs deserializedTestStandardMultisigFederationArgs = deserializedTestStandardMultisigFederation.getArgs(); ErpFederationArgs erpFederationArgs = - ErpFederationArgs.fromFederationArgs(deserializedTestFederationArgs, bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay()); - Federation testErpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederationArgs.fromFederationArgs(deserializedTestStandardMultisigFederationArgs, bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay()); + Federation testNonStandardErpFederation = FederationFactory.buildNonStandardErpFederation( erpFederationArgs, activations ); - byte[] serializedTestErpFederation = BridgeSerializationUtils.serializeFederation(testErpFederation); + byte[] serializedTestNonStandardErpFederation = BridgeSerializationUtils.serializeFederation(testNonStandardErpFederation); - Federation deserializedTestErpFederation = BridgeSerializationUtils.deserializeLegacyErpFederation( - serializedTestErpFederation, + ErpFederation deserializedTestNonStandardErpFederation = BridgeSerializationUtils.deserializeNonStandardErpFederation( + serializedTestNonStandardErpFederation, bridgeConstants, activations ); - Assertions.assertEquals(testFederation, deserializedTestFederation); - Assertions.assertEquals(testErpFederation, deserializedTestErpFederation); - assertNotEquals(testFederation, deserializedTestErpFederation); - assertNotEquals(testErpFederation, deserializedTestFederation); + Assertions.assertEquals(testStandardMultisigFederation, deserializedTestStandardMultisigFederation); + Assertions.assertEquals(testNonStandardErpFederation, deserializedTestNonStandardErpFederation); + assertNotEquals(testStandardMultisigFederation, deserializedTestNonStandardErpFederation); + assertNotEquals(testNonStandardErpFederation, deserializedTestStandardMultisigFederation); if (!isRskip284Active && networkId.equals(NetworkParameters.ID_TESTNET)) { - Assertions.assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, testErpFederation.getRedeemScript()); + Assertions.assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, testNonStandardErpFederation.getRedeemScript()); } if (isRskip353Active) { @@ -1175,8 +1175,8 @@ private void testSerializeAndDeserializeFederation( ); assertEquals(testP2shErpFederation, deserializedTestP2shErpFederation); - assertNotEquals(testFederation, deserializedTestP2shErpFederation); - assertNotEquals(testErpFederation, deserializedTestP2shErpFederation); + assertNotEquals(testStandardMultisigFederation, deserializedTestP2shErpFederation); + assertNotEquals(testNonStandardErpFederation, deserializedTestP2shErpFederation); } } } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index 68d4611a30e..548c962dd85 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -36,7 +36,7 @@ class BridgeStorageProviderFederationTests { private ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); @Test - void getNewFederation_should_return_P2shErpFederation() { + void getNewFederation_should_return_p2sh_erp_federation() { Federation federation = createFederation(P2SH_ERP_FEDERATION_FORMAT_VERSION); testGetNewFederation( @@ -46,7 +46,7 @@ void getNewFederation_should_return_P2shErpFederation() { } @Test - void getNewFederation_should_return_erp_federation() { + void getNewFederation_should_return_non_standard_erp_federation() { Federation federation = createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION); testGetNewFederation( NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, @@ -55,7 +55,7 @@ void getNewFederation_should_return_erp_federation() { } @Test - void getNewFederation_should_return_legacy_federation() { + void getNewFederation_should_return_standard_multisig_federation() { Federation federation = createFederation(STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION); testGetNewFederation( STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION, @@ -141,7 +141,7 @@ private void testGetNewFederation( } @Test - void getOldFederation_should_return_P2shErpFederation() { + void getOldFederation_should_return_p2sh_erp_federation() { Federation federation = createFederation(P2SH_ERP_FEDERATION_FORMAT_VERSION); testGetOldFederation( @@ -151,7 +151,7 @@ void getOldFederation_should_return_P2shErpFederation() { } @Test - void getOldFederation_should_return_erp_federation() { + void getOldFederation_should_return_non_standard_erp_federation() { Federation federation = createFederation(NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION); testGetOldFederation( NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, @@ -160,7 +160,7 @@ void getOldFederation_should_return_erp_federation() { } @Test - void getOldFederation_should_return_legacy_fed() { + void getOldFederation_should_return_standard_multisig_fed() { Federation federation = createFederation(STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION); testGetOldFederation( STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION, @@ -264,7 +264,7 @@ void saveNewFederation_before_RSKIP123_should_allow_to_save_any_fed_type() throw } @Test - void saveNewFederation_after_RSKIP123_should_save_legacy_fed_format() throws IOException { + void saveNewFederation_after_RSKIP123_should_save_standard_multisig_fed_format() throws IOException { activations = ActivationConfigsForTest.only(ConsensusRule.RSKIP123).forBlock(0); testSaveNewFederation( STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION, @@ -273,7 +273,7 @@ void saveNewFederation_after_RSKIP123_should_save_legacy_fed_format() throws IOE } @Test - void saveNewFederation_after_RSKIP201_should_save_legacy_fed_format() throws IOException { + void saveNewFederation_after_RSKIP201_should_save_standard_multisig_fed_format() throws IOException { activations = ActivationConfigsForTest.only( ConsensusRule.RSKIP123, ConsensusRule.RSKIP201 @@ -285,7 +285,7 @@ void saveNewFederation_after_RSKIP201_should_save_legacy_fed_format() throws IOE } @Test - void saveNewFederation_after_RSKIP353_should_save_legacy_fed_format() throws IOException { + void saveNewFederation_after_RSKIP353_should_save_standard_multisig_fed_format() throws IOException { activations = ActivationConfigsForTest.only( ConsensusRule.RSKIP123, ConsensusRule.RSKIP201, @@ -298,7 +298,7 @@ void saveNewFederation_after_RSKIP353_should_save_legacy_fed_format() throws IOE } @Test - void saveNewFederation_after_RSKIP201_should_save_erp_fed_format() throws IOException { + void saveNewFederation_after_RSKIP201_should_save_non_standard_erp_fed_format() throws IOException { activations = ActivationConfigsForTest.only( ConsensusRule.RSKIP123, ConsensusRule.RSKIP201 @@ -310,7 +310,7 @@ void saveNewFederation_after_RSKIP201_should_save_erp_fed_format() throws IOExce } @Test - void saveNewFederation_after_RSKIP353_should_save_erp_fed_format() throws IOException { + void saveNewFederation_after_RSKIP353_should_save_non_standard_erp_fed_format() throws IOException { activations = ActivationConfigsForTest.only( ConsensusRule.RSKIP123, ConsensusRule.RSKIP201, @@ -437,7 +437,7 @@ void saveOldFederation_before_RSKIP123_should_allow_to_save_any_fed_type() throw } @Test - void saveOldFederation_after_RSKIP123_should_save_legacy_fed_format() throws IOException { + void saveOldFederation_after_RSKIP123_should_save_standard_multisig_fed_format() throws IOException { activations = ActivationConfigsForTest.only(ConsensusRule.RSKIP123).forBlock(0); testSaveOldFederation( STANDARD_MULTISIG_FEDERATION_FORMAT_VERSION, @@ -446,7 +446,7 @@ void saveOldFederation_after_RSKIP123_should_save_legacy_fed_format() throws IOE } @Test - void saveOldFederation_after_RSKIP201_should_save_legacy_fed_format() throws IOException { + void saveOldFederation_after_RSKIP201_should_save_standard_multisig_fed_format() throws IOException { activations = ActivationConfigsForTest.only( ConsensusRule.RSKIP123, ConsensusRule.RSKIP201 @@ -458,7 +458,7 @@ void saveOldFederation_after_RSKIP201_should_save_legacy_fed_format() throws IOE } @Test - void saveOldFederation_after_RSKIP353_should_save_legacy_fed_format() throws IOException { + void saveOldFederation_after_RSKIP353_should_save_standard_multisig_fed_format() throws IOException { activations = ActivationConfigsForTest.only( ConsensusRule.RSKIP123, ConsensusRule.RSKIP201, @@ -471,7 +471,7 @@ void saveOldFederation_after_RSKIP353_should_save_legacy_fed_format() throws IOE } @Test - void saveOldFederation_after_RSKIP201_should_save_erp_fed_format() throws IOException { + void saveOldFederation_after_RSKIP201_should_save_non_standard_erp_fed_format() throws IOException { activations = ActivationConfigsForTest.only( ConsensusRule.RSKIP123, ConsensusRule.RSKIP201 @@ -483,7 +483,7 @@ void saveOldFederation_after_RSKIP201_should_save_erp_fed_format() throws IOExce } @Test - void saveOldFederation_after_RSKIP353_should_save_erp_fed_format() throws IOException { + void saveOldFederation_after_RSKIP353_should_save_non_standard_erp_fed_format() throws IOException { activations = ActivationConfigsForTest.only( ConsensusRule.RSKIP123, ConsensusRule.RSKIP201, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 2fe228327c9..e43cbba1b1b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -402,7 +402,7 @@ void getNewFederation_multiKeyVersion() { } @Test - void getNewFederation_erp_and_p2sh_erp_feds() { + void getNewFederation_non_standard_erp_and_p2sh_erp_feds() { ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); Federation newFederation = buildMockFederation(100, 200, 300); BridgeConstants bridgeConstants = bridgeTestnetInstance; @@ -412,10 +412,10 @@ void getNewFederation_erp_and_p2sh_erp_feds() { long activationDelay = bridgeConstants.getErpFedActivationDelay(); ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); - testGetNewFederationPostMultiKey(erpFederation); + testGetNewFederationPostMultiKey(nonStandardErpFederation); testGetNewFederationPostMultiKey(p2shErpFederation); } @@ -525,7 +525,7 @@ void saveNewFederation_postMultiKey() { } @Test - void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { + void saveNewFederation_postMultiKey_RSKIP_201_active_non_standard_erp_fed() { ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); Federation newFederation = buildMockFederation(100, 200, 300); BridgeConstants bridgeConstants = bridgeTestnetInstance; @@ -535,9 +535,9 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_erp_fed() { long activationDelay = bridgeConstants.getErpFedActivationDelay(); ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - testSaveNewFederationPostMultiKey(erpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); + testSaveNewFederationPostMultiKey(nonStandardErpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); } @Test @@ -653,7 +653,7 @@ void getOldFederation_multiKeyVersion() { } @Test - void getOldFederation_nonStandard_feds() { + void getOldFederation_non_standard_erp_feds() { Federation oldFederation = buildMockFederation(100, 200, 300); BridgeConstants bridgeConstants = bridgeTestnetInstance; @@ -665,17 +665,17 @@ void getOldFederation_nonStandard_feds() { // this should get non-standard hardcoded fed ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - testGetOldFederation(erpFederation, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + testGetOldFederation(nonStandardErpFederation, activations); // this should get non-standard with csv unsigned BE fed - erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - testGetOldFederation(erpFederation, activations); + nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + testGetOldFederation(nonStandardErpFederation, activations); // this should get non-standard fed activations = ActivationConfigsForTest.hop400().forBlock(0); - erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - testGetOldFederation(erpFederation, activations); + nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + testGetOldFederation(nonStandardErpFederation, activations); } @Test @@ -797,7 +797,7 @@ void saveOldFederation_postMultikey() { } @Test - void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { + void saveOldFederation_postMultikey_RSKIP_201_active_non_standard_erp_fed() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); @@ -811,8 +811,8 @@ void saveOldFederation_postMultikey_RSKIP_201_active_erp_fed() { ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - testSaveOldFederation(erpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + testSaveOldFederation(nonStandardErpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index c9d2b62e611..0df8d511596 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -163,16 +163,16 @@ void hasEnoughSignatures_several_inputs_all_signed() { } @Test - void hasEnoughSignatures_several_inputs_all_signed_erp_fed() { + void hasEnoughSignatures_several_inputs_all_signed_non_standard_erp_fed() { // Create 2 signatures byte[] sign1 = new byte[]{0x79}; byte[] sign2 = new byte[]{0x78}; - Federation erpFederation = createErpFederation(); + ErpFederation nonStandardErpFederation = createNonStandardErpFederation(); BtcTransaction btcTx = createPegOutTx( Arrays.asList(sign1, sign2), 3, - erpFederation, + nonStandardErpFederation, false ); @@ -195,16 +195,16 @@ void hasEnoughSignatures_several_inputs_all_signed_fast_bridge() { } @Test - void hasEnoughSignatures_several_inputs_all_signed_erp_fast_bridge() { + void hasEnoughSignatures_several_inputs_all_signed_non_standard_erp_fast_bridge() { // Create 2 signatures byte[] sign1 = new byte[]{0x79}; byte[] sign2 = new byte[]{0x78}; - Federation erpFederation = createErpFederation(); + ErpFederation nonStandardErpFederation = createNonStandardErpFederation(); BtcTransaction btcTx = createPegOutTxForFlyover( Arrays.asList(sign1, sign2), 3, - erpFederation + nonStandardErpFederation ); Assertions.assertTrue(BridgeUtils.hasEnoughSignatures(mock(Context.class), btcTx)); @@ -256,16 +256,16 @@ void countMissingSignatures_several_inputs_all_signed() { } @Test - void countMissingSignatures_several_inputs_all_signed_erp_fed() { + void countMissingSignatures_several_inputs_all_signed_non_standard_erp_fed() { // Create 2 signatures byte[] sign1 = new byte[]{0x79}; byte[] sign2 = new byte[]{0x78}; - Federation erpFederation = createErpFederation(); + ErpFederation nonStandardErpFederation = createNonStandardErpFederation(); BtcTransaction btcTx = createPegOutTx( Arrays.asList(sign1, sign2), 3, - erpFederation, + nonStandardErpFederation, false ); @@ -288,16 +288,16 @@ void countMissingSignatures_several_inputs_all_signed_fast_bridge() { } @Test - void countMissingSignatures_several_inputs_all_signed_erp_fast_bridge() { + void countMissingSignatures_several_inputs_all_signed_non_standard_erp_fast_bridge() { // Create 2 signatures byte[] sign1 = new byte[]{0x79}; byte[] sign2 = new byte[]{0x78}; - Federation erpFederation = createErpFederation(); + ErpFederation nonStandardErpFederation = createNonStandardErpFederation(); BtcTransaction btcTx = createPegOutTxForFlyover( Arrays.asList(sign1, sign2), 3, - erpFederation + nonStandardErpFederation ); Assertions.assertEquals(0, BridgeUtils.countMissingSignatures(mock(Context.class), btcTx)); @@ -1053,7 +1053,7 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs() { } @Test - void testCalculatePegoutTxSize_50Inputs_200Outputs_erpFederation() { + void testCalculatePegoutTxSize_50Inputs_200Outputs_nonStandardErpFederation() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); @@ -1079,7 +1079,7 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs_erpFederation() { erpFederationPublicKeys, 500L ); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation( erpFederationArgs, activations ); @@ -1087,9 +1087,9 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs_erpFederation() { // Create a pegout tx with 50 inputs and 200 outputs int inputSize = 50; int outputSize = 200; - BtcTransaction pegoutTx = createPegOutTx(inputSize, outputSize, erpFederation, defaultFederationKeys); + BtcTransaction pegoutTx = createPegOutTx(inputSize, outputSize, nonStandardErpFederation, defaultFederationKeys); - int pegoutTxSize = BridgeUtils.calculatePegoutTxSize(activations, erpFederation, inputSize, outputSize); + int pegoutTxSize = BridgeUtils.calculatePegoutTxSize(activations, nonStandardErpFederation, inputSize, outputSize); // The difference between the calculated size and a real tx size should be smaller than 3% in any direction int origTxSize = pegoutTx.bitcoinSerialize().length; @@ -1100,7 +1100,7 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs_erpFederation() { } @Test - void testCalculatePegoutTxSize_100Inputs_50Outputs_erpFederation() { + void testCalculatePegoutTxSize_100Inputs_50Outputs_nonStandardErpFederation() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); @@ -1126,7 +1126,7 @@ void testCalculatePegoutTxSize_100Inputs_50Outputs_erpFederation() { erpFederationPublicKeys, 500L ); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation( erpFederationArgs, activations ); @@ -1134,9 +1134,9 @@ void testCalculatePegoutTxSize_100Inputs_50Outputs_erpFederation() { // Create a pegout tx with 100 inputs and 50 outputs int inputSize = 100; int outputSize = 50; - BtcTransaction pegoutTx = createPegOutTx(inputSize, outputSize, erpFederation, defaultFederationKeys); + BtcTransaction pegoutTx = createPegOutTx(inputSize, outputSize, nonStandardErpFederation, defaultFederationKeys); - int pegoutTxSize = BridgeUtils.calculatePegoutTxSize(activations, erpFederation, inputSize, outputSize); + int pegoutTxSize = BridgeUtils.calculatePegoutTxSize(activations, nonStandardErpFederation, inputSize, outputSize); // The difference between the calculated size and a real tx size should be smaller than 3% in any direction int origTxSize = pegoutTx.bitcoinSerialize().length; @@ -1472,7 +1472,7 @@ private Genesis getGenesisInstance(TrieStore trieStore) { return new TestGenesisLoader(trieStore, "frontier.json", constants.getInitialNonce(), false, true, true).load(); } - private ErpFederation createErpFederation() { + private ErpFederation createNonStandardErpFederation() { Federation genesisFederation = bridgeConstantsRegtest.getGenesisFederation(); FederationArgs genesisFederationArgs = genesisFederation.getArgs(); List erpPubKeys = bridgeConstantsRegtest.getErpFedPubKeysList(); diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java index d6765f335e0..fef3014ca3f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java @@ -36,9 +36,9 @@ class FlyoverCompatibleBtcWalletWithStorageTest { }).map(hex -> BtcECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); private Federation federation; - private ErpFederation erpFederation; + private ErpFederation nonStandardErpFederation; private List federationList; - private List erpFederationList; + private List nonStandardErpFederationList; @BeforeEach void setup() { @@ -47,14 +47,13 @@ void setup() { FederationArgs federationArgs = new FederationArgs(fedMembers, Instant.ofEpochMilli(1000), 0L, btcParams); federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); + federationList = Collections.singletonList(federation); long activationDelay = 5063; ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFedKeys, activationDelay); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - - federationList = Collections.singletonList(federation); - erpFederationList = Collections.singletonList(erpFederation); + nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + nonStandardErpFederationList = Collections.singletonList(nonStandardErpFederation); } @Test @@ -103,13 +102,13 @@ void findRedeemDataFromScriptHash_with_flyoverInformation_in_storage() { } @Test - void findRedeemDataFromScriptHash_with_flyoverInformation_in_storage_and_erp_fed() { + void findRedeemDataFromScriptHash_with_flyoverInformation_in_storage_and_non_standard_erp_fed() { BridgeStorageProvider provider = mock(BridgeStorageProvider.class); Keccak256 derivationArgumentsHash = PegTestUtils.createHash3(1); Script flyoverRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( - erpFederation.getRedeemScript(), - Sha256Hash.wrap(derivationArgumentsHash.getBytes() + nonStandardErpFederation.getRedeemScript(), + Sha256Hash.wrap(derivationArgumentsHash.getBytes() ) ); @@ -119,7 +118,7 @@ void findRedeemDataFromScriptHash_with_flyoverInformation_in_storage_and_erp_fed FlyoverFederationInformation flyoverFederationInformation = new FlyoverFederationInformation( derivationArgumentsHash, - erpFederation.getP2SHScript().getPubKeyHash(), + nonStandardErpFederation.getP2SHScript().getPubKeyHash(), flyoverFederationP2SH); when(provider.getFlyoverFederationInformation(flyoverFederationP2SH)) @@ -128,7 +127,7 @@ void findRedeemDataFromScriptHash_with_flyoverInformation_in_storage_and_erp_fed FlyoverCompatibleBtcWalletWithStorage flyoverCompatibleBtcWalletWithStorage = new FlyoverCompatibleBtcWalletWithStorage( mock(Context.class), - erpFederationList, + nonStandardErpFederationList, provider ); @@ -154,7 +153,7 @@ void findRedeemDataFromScriptHash_null_destination_federation() { ); FlyoverCompatibleBtcWalletWithStorage flyoverCompatibleBtcWalletWithStorage = - new FlyoverCompatibleBtcWalletWithStorage(mock(Context.class), federationList, provider); + new FlyoverCompatibleBtcWalletWithStorage(mock(Context.class), nonStandardErpFederationList, provider); Assertions.assertNull(flyoverCompatibleBtcWalletWithStorage.findRedeemDataFromScriptHash(new byte[]{1})); } @@ -174,7 +173,7 @@ void getFlyoverFederationInformation_data_on_storage() { ); FlyoverCompatibleBtcWalletWithStorage flyoverCompatibleBtcWalletWithStorage = - new FlyoverCompatibleBtcWalletWithStorage(mock(Context.class), federationList, provider); + new FlyoverCompatibleBtcWalletWithStorage(mock(Context.class), nonStandardErpFederationList, provider); Optional result = flyoverCompatibleBtcWalletWithStorage. getFlyoverFederationInformation(flyoverScriptHash); @@ -191,7 +190,7 @@ void getFlyoverFederationInformation_no_data_on_storage() { ); FlyoverCompatibleBtcWalletWithStorage flyoverCompatibleBtcWalletWithStorage = - new FlyoverCompatibleBtcWalletWithStorage(mock(Context.class), federationList, provider); + new FlyoverCompatibleBtcWalletWithStorage(mock(Context.class), nonStandardErpFederationList, provider); Optional result = flyoverCompatibleBtcWalletWithStorage. getFlyoverFederationInformation(new byte[1]); diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java index 591c45ae855..b4a23ab81fc 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java @@ -33,20 +33,22 @@ class FlyoverCompatibleBtcWallextWithSingleScriptTest { }).map(hex -> BtcECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); private Federation federation; - private ErpFederation erpFederation; + private ErpFederation nonStandardErpFederation; private List federationList; - private List erpFederationList; + private List nonStandardErpFederationList; private ActivationConfig.ForBlock activations; @BeforeEach void setup() { - + // set up standard multisig federation List fedMembers = FederationTestUtils.getFederationMembers(3); Instant creationTime = Instant.ofEpochMilli(1000); NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, btcParams); federation = FederationFactory.buildStandardMultiSigFederation(federationArgs); + federationList = Collections.singletonList(federation); + // set up non-standard erp federation activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP123)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); @@ -54,10 +56,8 @@ void setup() { when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFedKeys, 5063); - erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - - federationList = Collections.singletonList(federation); - erpFederationList = Collections.singletonList(erpFederation); + nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + nonStandardErpFederationList = Collections.singletonList(nonStandardErpFederation); } @Test @@ -101,25 +101,25 @@ void findRedeemDataFromScriptHash_with_flyoverInformation() { } @Test - void findRedeemDataFromScriptHash_with_flyoverInformation_and_erp_federation() { + void findRedeemDataFromScriptHash_with_flyoverInformation_and_non_standard_erp_federation() { byte[] flyoverScriptHash = new byte[]{(byte)0x22}; FlyoverFederationInformation flyoverFederationInformation = new FlyoverFederationInformation( PegTestUtils.createHash3(2), - erpFederation.getP2SHScript().getPubKeyHash(), + nonStandardErpFederation.getP2SHScript().getPubKeyHash(), flyoverScriptHash); FlyoverCompatibleBtcWalletWithSingleScript flyoverCompatibleBtcWalletWithSingleScript = new FlyoverCompatibleBtcWalletWithSingleScript( mock(Context.class), - erpFederationList, + nonStandardErpFederationList, flyoverFederationInformation); RedeemData redeemData = flyoverCompatibleBtcWalletWithSingleScript.findRedeemDataFromScriptHash( - erpFederation.getP2SHScript().getPubKeyHash()); + nonStandardErpFederation.getP2SHScript().getPubKeyHash()); Script flyoverRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( - erpFederation.getRedeemScript(), + nonStandardErpFederation.getRedeemScript(), Sha256Hash.wrap(flyoverFederationInformation.getDerivationHash().getBytes()) ); diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java index b71ac5b9a60..be2c45b3d29 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java @@ -540,9 +540,9 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_beforeRskip201_isP long activationDelay = 500L; ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - Script redeemScript = erpFederation.getRedeemScript(); + Script redeemScript = nonStandardErpFederation.getRedeemScript(); Script flyoverErpRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( redeemScript, Sha256Hash.of(PegTestUtils.createHash(1).getBytes()) @@ -578,11 +578,11 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_afterRskip201_notP List erpFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(erpFederationKeys); FederationArgs args = new FederationArgs(erpFedMembers, creationTime, 0L, networkParameters); - Federation erpFederation = FederationFactory.buildStandardMultiSigFederation(args); + Federation standardMultisigFederation = FederationFactory.buildStandardMultiSigFederation(args); Script erpRedeemScript = ErpFederationRedeemScriptParser.createErpRedeemScript( activeFederation.getRedeemScript(), - erpFederation.getRedeemScript(), + standardMultisigFederation.getRedeemScript(), 500L ); Script flyoverErpRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( @@ -623,13 +623,13 @@ void testIsValidPegInTx_hasChangeUtxoFromErpFederation_beforeRskip201_isPegin() 0L, networkParameters ); - Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( + Federation standardMultisigFederation = FederationFactory.buildStandardMultiSigFederation( args ); Script erpRedeemScript = ErpFederationRedeemScriptParser.createErpRedeemScript( activeFederation.getRedeemScript(), - erpFederation.getRedeemScript(), + standardMultisigFederation.getRedeemScript(), 500L ); @@ -661,13 +661,13 @@ void testIsValidPegInTx_hasChangeUtxoFromErpFederation_afterRskip201_notPegin() 0L, networkParameters ); - Federation erpFederation = FederationFactory.buildStandardMultiSigFederation( + Federation standardMultisigFederation = FederationFactory.buildStandardMultiSigFederation( args ); Script erpRedeemScript = ErpFederationRedeemScriptParser.createErpRedeemScript( activeFederation.getRedeemScript(), - erpFederation.getRedeemScript(), + standardMultisigFederation.getRedeemScript(), 500L ); @@ -804,7 +804,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_beforeRskip ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired fast bridge fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -818,10 +818,10 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_beforeRskip tx.addInput(txInput); Script flyoverErpRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( - erpFederation.getRedeemScript(), + nonStandardErpFederation.getRedeemScript(), PegTestUtils.createHash(2) ); - signWithNecessaryKeys(erpFederation, flyoverErpRedeemScript, retiredFederationKeys, txInput, tx); + signWithNecessaryKeys(nonStandardErpFederation, flyoverErpRedeemScript, retiredFederationKeys, txInput, tx); Wallet federationWallet = new BridgeBtcWallet(btcContext, Collections.singletonList(activeFederation)); @@ -846,7 +846,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 BtcECKey.fromPrivate(Hex.decode("fa02")) ); retiredFederationKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - + List retiredFederationMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys); FederationArgs retiredFederationArgs = new FederationArgs(retiredFederationMembers, creationTime, 0L, networkParameters); Federation retiredFederation = FederationFactory.buildStandardMultiSigFederation(retiredFederationArgs); @@ -858,7 +858,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired fast bridge fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -872,10 +872,10 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 tx.addInput(txInput); Script flyoverErpRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( - erpFederation.getRedeemScript(), + nonStandardErpFederation.getRedeemScript(), PegTestUtils.createHash(2) ); - signWithNecessaryKeys(erpFederation, flyoverErpRedeemScript, retiredFederationKeys, txInput, tx); + signWithNecessaryKeys(nonStandardErpFederation, flyoverErpRedeemScript, retiredFederationKeys, txInput, tx); Wallet federationWallet = new BridgeBtcWallet(btcContext, Collections.singletonList(activeFederation)); @@ -911,7 +911,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); // Create a tx from the retired erp fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -923,7 +923,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP new TransactionOutPoint(networkParameters, 0, Sha256Hash.ZERO_HASH) ); tx.addInput(txInput); - signWithErpFederation(erpFederation, retiredFederationKeys, txInput, tx); + signWithErpFederation(nonStandardErpFederation, retiredFederationKeys, txInput, tx); Wallet federationWallet = new BridgeBtcWallet(btcContext, Collections.singletonList(activeFederation)); @@ -959,7 +959,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_afterRskip201_notP ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); ErpFederationArgs erpFedArgs = ErpFederationArgs.fromFederationArgs(retiredFedArgs, erpFederationPublicKeys, 500L); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpFedArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFedArgs, activations); // Create a tx from the retired erp fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -971,7 +971,7 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_afterRskip201_notP new TransactionOutPoint(networkParameters, 0, Sha256Hash.ZERO_HASH) ); tx.addInput(txInput); - signWithErpFederation(erpFederation, retiredFederationKeys, txInput, tx); + signWithErpFederation(nonStandardErpFederation, retiredFederationKeys, txInput, tx); Wallet federationWallet = new BridgeBtcWallet(btcContext, Collections.singletonList(activeFederation)); @@ -1933,7 +1933,7 @@ void testIsPegOutTx_fromErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); ErpFederationArgs erpArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFederationPublicKeys, 500L); - ErpFederation erpFederation = FederationFactory.buildNonStandardErpFederation(erpArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpArgs, activations); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -1948,7 +1948,7 @@ void testIsPegOutTx_fromErpFederation() { new TransactionOutPoint(networkParameters, 0, Sha256Hash.ZERO_HASH) ); pegOutTx1.addInput(pegOutInput1); - signWithErpFederation(erpFederation, defaultFederationKeys, pegOutInput1, pegOutTx1); + signWithErpFederation(nonStandardErpFederation, defaultFederationKeys, pegOutInput1, pegOutTx1); // Before RSKIP 201 activation when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(false); @@ -1961,8 +1961,8 @@ void testIsPegOutTx_fromErpFederation() { assertFalse(isPegOutTx(pegOutTx1, activations, defaultFederation.getP2SHScript(), standardFederation.getP2SHScript())); assertFalse(isPegOutTx(pegOutTx1, activations, standardFederation.getP2SHScript())); - assertFalse(isPegOutTx(pegOutTx1, Collections.singletonList(erpFederation), activations)); - assertFalse(isPegOutTx(pegOutTx1, activations, erpFederation.getDefaultP2SHScript())); + assertFalse(isPegOutTx(pegOutTx1, Collections.singletonList(nonStandardErpFederation), activations)); + assertFalse(isPegOutTx(pegOutTx1, activations, nonStandardErpFederation.getDefaultP2SHScript())); // After RSKIP 201 activation when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); @@ -1975,8 +1975,8 @@ void testIsPegOutTx_fromErpFederation() { assertTrue(isPegOutTx(pegOutTx1, activations, defaultFederation.getP2SHScript(), standardFederation.getP2SHScript())); assertFalse(isPegOutTx(pegOutTx1, activations, standardFederation.getP2SHScript())); - assertTrue(isPegOutTx(pegOutTx1, Collections.singletonList(erpFederation), activations)); - assertTrue(isPegOutTx(pegOutTx1, activations, erpFederation.getDefaultP2SHScript())); + assertTrue(isPegOutTx(pegOutTx1, Collections.singletonList(nonStandardErpFederation), activations)); + assertTrue(isPegOutTx(pegOutTx1, activations, nonStandardErpFederation.getDefaultP2SHScript())); } @Test @@ -2000,7 +2000,7 @@ void testIsPegOutTx_fromFlyoverErpFederation() { erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); ErpFederationArgs erpArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFederationPublicKeys, 500L); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation(erpArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpArgs, activations); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -2017,10 +2017,10 @@ void testIsPegOutTx_fromFlyoverErpFederation() { pegOutTx1.addInput(pegOutInput1); Script flyoverErpRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( - erpFederation.getRedeemScript(), + nonStandardErpFederation.getRedeemScript(), PegTestUtils.createHash(2) ); - signWithNecessaryKeys(erpFederation, flyoverErpRedeemScript, defaultFederationKeys, pegOutInput1, pegOutTx1); + signWithNecessaryKeys(nonStandardErpFederation, flyoverErpRedeemScript, defaultFederationKeys, pegOutInput1, pegOutTx1); // Before RSKIP 201 activation when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(false); @@ -2304,7 +2304,7 @@ void scriptCorrectlySpends_invalidScript() { assertFalse(scriptCorrectlySpendsTx(tx, 0, genesisFederation.getP2SHScript())); } - private void signWithErpFederation(Federation erpFederation, List privateKeys, TransactionInput txIn, BtcTransaction tx) { + private void signWithErpFederation(ErpFederation erpFederation, List privateKeys, TransactionInput txIn, BtcTransaction tx) { signWithNecessaryKeys(erpFederation, privateKeys, txIn, tx); // Add OP_0 prefix to make it a valid erp federation script Script erpInputScript = new ScriptBuilder() diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index 7f72a8aeed2..b2d6e09dacf 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -138,7 +138,7 @@ private void testChangePowpeg( ErpFederationArgs erpFederationArgs = new ErpFederationArgs(originalPowpegMembers, creationTime, 0, btcParams, erpPubKeys, activationDelay); switch (oldPowPegFederationType) { - case legacyErp: + case nonStandardErp: originalPowpeg = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); break; case p2shErp: @@ -192,7 +192,7 @@ private void testChangePowpeg( Federation newPowPeg = argumentCaptor.getValue(); assertEquals(newPowPegAddress, newPowPeg.getAddress()); switch (newPowPegFederationType) { - case legacyErp: + case nonStandardErp: assertSame(ErpFederation.class, newPowPeg.getClass()); assertTrue(((ErpFederation) newPowPeg).getErpRedeemScriptBuilder() instanceof NonStandardErpRedeemScriptBuilder); break; @@ -588,12 +588,12 @@ private void testChangePowpeg( Script lastRetiredFederationP2SHScript = lastRetiredFederationP2SHScriptOptional.get(); if (activations.isActive(ConsensusRule.RSKIP377)){ - if (oldPowPegFederationType == FederationType.legacyErp || oldPowPegFederationType == FederationType.p2shErp){ + if (oldPowPegFederationType == FederationType.nonStandardErp || oldPowPegFederationType == FederationType.p2shErp){ assertNotEquals(lastRetiredFederationP2SHScript, originalPowpeg.getP2SHScript()); } assertEquals(lastRetiredFederationP2SHScript, getFederationDefaultP2SHScript(originalPowpeg)); } else { - if (oldPowPegFederationType == FederationType.legacyErp || oldPowPegFederationType == FederationType.p2shErp){ + if (oldPowPegFederationType == FederationType.nonStandardErp || oldPowPegFederationType == FederationType.p2shErp){ assertEquals(lastRetiredFederationP2SHScript, originalPowpeg.getP2SHScript()); assertNotEquals(lastRetiredFederationP2SHScript, getFederationDefaultP2SHScript(originalPowpeg)); } else { @@ -1345,11 +1345,11 @@ void test_change_powpeg_from_erpFederation_with_mainnet_powpeg_pre_RSKIP_353_cre ); testChangePowpeg( - FederationType.legacyErp, + FederationType.nonStandardErp, getMainnetPowpegKeys(), originalPowpegAddress, utxos, - FederationType.legacyErp, + FederationType.nonStandardErp, newPowpegKeys, newPowpegAddress, bridgeConstants, @@ -1371,7 +1371,7 @@ void test_change_powpeg_from_erpFederation_with_mainnet_powpeg_post_RSKIP_353_cr ); testChangePowpeg( - FederationType.legacyErp, + FederationType.nonStandardErp, getMainnetPowpegKeys(), originalPowpegAddress, utxos, @@ -1592,7 +1592,7 @@ void test_change_powpeg_from_p2shErpFederation_with_mainnet_powpeg_post_RSKIP_37 } private enum FederationType { - legacyErp, + nonStandardErp, p2shErp, standardMultisig } diff --git a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java index 03d9bec45bd..d10f517357d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java @@ -165,7 +165,7 @@ void first_output_pay_fees() { } @Test - void build_pegout_tx_from_erp_federation() { + void build_pegout_tx_from_non_standard_erp_federation() { ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); @@ -189,7 +189,7 @@ void build_pegout_tx_from_erp_federation() { bridgeConstants.getErpFedActivationDelay() ); - Federation erpFederation = FederationFactory.buildNonStandardErpFederation( + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation( erpFederationArgs, activations ); @@ -201,7 +201,7 @@ void build_pegout_tx_from_erp_federation() { Coin.COIN, 0, false, - erpFederation.getP2SHScript() + nonStandardErpFederation.getP2SHScript() ), new UTXO( Sha256Hash.of(new byte[]{1}), @@ -209,13 +209,13 @@ void build_pegout_tx_from_erp_federation() { Coin.COIN, 0, false, - erpFederation.getP2SHScript() + nonStandardErpFederation.getP2SHScript() ) ); Wallet thisWallet = BridgeUtils.getFederationSpendWallet( new Context(bridgeConstants.getBtcParams()), - erpFederation, + nonStandardErpFederation, utxos, false, mock(BridgeStorageProvider.class) @@ -224,7 +224,7 @@ void build_pegout_tx_from_erp_federation() { ReleaseTransactionBuilder releaseTransactionBuilder = new ReleaseTransactionBuilder( bridgeConstants.getBtcParams(), thisWallet, - erpFederation.getAddress(), + nonStandardErpFederation.getAddress(), Coin.SATOSHI.multiply(1000), activations ); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java index efa05b546bb..dd19387d3d6 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java @@ -50,7 +50,7 @@ import org.junit.jupiter.params.provider.ValueSource; class NonStandardErpFederationsTest { - private ErpFederation federation; + private ErpFederation nonStandardErpFederation; private NetworkParameters networkParameters; private List defaultKeys; private int defaultThreshold; @@ -87,7 +87,7 @@ void setup() { activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP201)).thenReturn(true); - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); } private ErpFederation createDefaultNonStandardErpFederation() { @@ -167,7 +167,7 @@ void createFederation_postRSKIP293_withValidCsvValues_valid(long csvValue) { createAndValidateFederation(); // Also check the builder is the expected one considering the activations - ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); assertTrue(builder instanceof NonStandardErpRedeemScriptBuilder); } @@ -182,7 +182,7 @@ void createFederation_postRSKIP284_preRSKIP293_withValidCsvValueOneByteLong_vali createAndValidateFederation(); // Also check the builder is the expected one considering the activations - ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); assertTrue(builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE); } @@ -194,14 +194,14 @@ void createFederation_postRSKIP293_withInvalidCsvValues_throwsErpFederationCreat activationDelayValue = csvValue; - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); ErpFederationCreationException fedException = assertThrows( ErpFederationCreationException.class, - () -> federation.getRedeemScript()); + () -> nonStandardErpFederation.getRedeemScript()); assertEquals(REDEEM_SCRIPT_CREATION_FAILED, fedException.getReason()); // Check the builder throws the particular expected exception - ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); RedeemScriptCreationException exception = assertThrows( RedeemScriptCreationException.class, () -> builder.createRedeemScriptFromKeys( @@ -215,7 +215,7 @@ void createFederation_postRSKIP293_withInvalidCsvValues_throwsErpFederationCreat @Test void createFederation_withRedeemScriptSizeAboveMaximum_throwsScriptCreationException() { // add one member to exceed redeem script size limit - List newDefaultKeys = federation.getBtcPublicKeys(); + List newDefaultKeys = nonStandardErpFederation.getBtcPublicKeys(); BtcECKey federator10PublicKey = BtcECKey.fromPublicOnly( Hex.decode("02550cc87fa9061162b1dd395a16662529c9d8094c0feca17905a3244713d65fe8") ); @@ -232,50 +232,50 @@ void createFederation_withRedeemScriptSizeAboveMaximum_throwsScriptCreationExcep @Test void getErpPubKeys() { - assertEquals(emergencyKeys, federation.getErpPubKeys()); + assertEquals(emergencyKeys, nonStandardErpFederation.getErpPubKeys()); } @Test void getActivationDelay() { - assertEquals(activationDelayValue, federation.getActivationDelay()); + assertEquals(activationDelayValue, nonStandardErpFederation.getActivationDelay()); } @Test void testEquals_basic() { - assertEquals(federation, federation); + assertEquals(nonStandardErpFederation, nonStandardErpFederation); - assertNotEquals(null, federation); - assertNotEquals(federation, new Object()); - assertNotEquals("something else", federation); + assertNotEquals(null, nonStandardErpFederation); + assertNotEquals(nonStandardErpFederation, new Object()); + assertNotEquals("something else", nonStandardErpFederation); } @Test void testEquals_same() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber(), - federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay() + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime(), nonStandardErpFederation.getCreationBlockNumber(), + nonStandardErpFederation.getBtcParams(), nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay() ); ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - assertEquals(federation, otherFederation); + assertEquals(nonStandardErpFederation, otherFederation); } @Test void testEquals_differentCreationTime() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime().plus(1, ChronoUnit.MILLIS), - federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay() + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime().plus(1, ChronoUnit.MILLIS), + nonStandardErpFederation.getCreationBlockNumber(), nonStandardErpFederation.getBtcParams(), nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay() ); ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - assertEquals(federation, otherFederation); + assertEquals(nonStandardErpFederation, otherFederation); } @Test void testEquals_differentCreationBlockNumber() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime(), federation.getCreationBlockNumber() + 1, - federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay() + ErpFederationArgs erpFederationArgs = new ErpFederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime(), nonStandardErpFederation.getCreationBlockNumber() + 1, + nonStandardErpFederation.getBtcParams(), nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay() ); ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - assertEquals(federation, otherFederation); + assertEquals(nonStandardErpFederation, otherFederation); } @Test @@ -283,18 +283,18 @@ void testEquals_differentNetworkParameters() { networkParameters = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); ErpFederation otherFederation = createDefaultNonStandardErpFederation(); - Assertions.assertNotEquals(federation, otherFederation); + Assertions.assertNotEquals(nonStandardErpFederation, otherFederation); } @Test void testEquals_differentNumberOfMembers() { // remove federator9 - List newDefaultKeys = federation.getBtcPublicKeys(); + List newDefaultKeys = nonStandardErpFederation.getBtcPublicKeys(); newDefaultKeys.remove(newDefaultKeys.size() - 1); defaultKeys = newDefaultKeys; ErpFederation otherFederation = createDefaultNonStandardErpFederation(); - Assertions.assertNotEquals(federation, otherFederation); + Assertions.assertNotEquals(nonStandardErpFederation, otherFederation); } @Test @@ -303,13 +303,13 @@ void testEquals_differentMembers() { BtcECKey federator9PublicKey = BtcECKey.fromPublicOnly( Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea") ); - List newDefaultKeys = federation.getBtcPublicKeys(); + List newDefaultKeys = nonStandardErpFederation.getBtcPublicKeys(); newDefaultKeys.remove(8); newDefaultKeys.add(federator9PublicKey); defaultKeys = newDefaultKeys; ErpFederation otherFederation = createDefaultNonStandardErpFederation(); - Assertions.assertNotEquals(federation, otherFederation); + Assertions.assertNotEquals(nonStandardErpFederation, otherFederation); } @Test @@ -342,9 +342,9 @@ void createdRedeemScriptProgramFromNonStandardErpBuilderHardcoded_withRealValues networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); // this should create the expected non-standard hardcoded fed - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); - ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); Script obtainedRedeemScript = builder .createRedeemScriptFromKeys(defaultKeys, defaultThreshold, emergencyKeys, emergencyThreshold, @@ -383,9 +383,9 @@ void createdRedeemScriptProgramFromNonStandardErpBuilderCsvUnsignedBE_withRealVa when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); // this should create the expected non-standard with csv unsigned be fed - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); - ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); Script obtainedRedeemScript = builder .createRedeemScriptFromKeys( defaultKeys, defaultThreshold, @@ -426,9 +426,9 @@ void createdRedeemScriptProgramFromNonStandardErpBuilder_withRealValues_equalsRe when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); // this should create the expected non-standard fed - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); - ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); Script obtainedRedeemScript = builder .createRedeemScriptFromKeys(defaultKeys, defaultThreshold, emergencyKeys, emergencyThreshold, @@ -458,9 +458,9 @@ void createdFederationInfo_withRealValues_equalsExistingFederationInfo_testnet() when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); // this should create the real fed - ErpFederation realLegacyErpFederation = createDefaultNonStandardErpFederation(); - Script p2shScript = realLegacyErpFederation.getP2SHScript(); - Address address = realLegacyErpFederation.getAddress(); + ErpFederation realNonStandardErpFederation = createDefaultNonStandardErpFederation(); + Script p2shScript = realNonStandardErpFederation.getP2SHScript(); + Address address = realNonStandardErpFederation.getAddress(); assertEquals(expectedProgram, Hex.toHexString(p2shScript.getProgram())); assertEquals(3, p2shScript.getChunks().size()); @@ -470,19 +470,19 @@ void createdFederationInfo_withRealValues_equalsExistingFederationInfo_testnet() @Test void getErpPubKeys_fromUncompressedPublicKeys_equals() { - // Public keys used for creating federation, but uncompressed format now + // Public keys used for creating nonStandardErpFederation, but uncompressed format now emergencyKeys = emergencyKeys .stream() .map(BtcECKey::decompress) .collect(Collectors.toList()); - // Recreate federation + // Recreate nonStandardErpFederation ErpFederation federationWithUncompressedKeys = createDefaultNonStandardErpFederation(); assertEquals(emergencyKeys, federationWithUncompressedKeys.getErpPubKeys()); } @Test - void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { + void getNonStandardErpRedeemScript_compareOtherImplementation() throws IOException { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); @@ -503,8 +503,8 @@ void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { emergencyKeys = generatedScript.emergencyFed; activationDelayValue = generatedScript.timelock; - federation = createDefaultNonStandardErpFederation(); - Script rskjScript = federation.getRedeemScript(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); + Script rskjScript = nonStandardErpFederation.getRedeemScript(); Script alternativeScript = generatedScript.script; assertEquals(alternativeScript, rskjScript); @@ -515,8 +515,8 @@ void getLegacyErpRedeemScript_compareOtherImplementation() throws IOException { @Test void getRedeemScript_before_RSKIP293() { when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - federation = createDefaultNonStandardErpFederation(); - Script redeemScript = federation.getRedeemScript(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); + Script redeemScript = nonStandardErpFederation.getRedeemScript(); validateErpRedeemScript( redeemScript, activationDelayValue @@ -526,8 +526,8 @@ void getRedeemScript_before_RSKIP293() { @Test void getRedeemScript_after_RSKIP293() { when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - federation = createDefaultNonStandardErpFederation(); - Script redeemScript = federation.getRedeemScript(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); + Script redeemScript = nonStandardErpFederation.getRedeemScript(); validateErpRedeemScript( redeemScript, @@ -542,12 +542,12 @@ void getRedeemScript_changes_related_to_RSKIP293_testnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - federation = createDefaultNonStandardErpFederation(); - Script preRskip293RedeemScript = federation.getRedeemScript(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); + Script preRskip293RedeemScript = nonStandardErpFederation.getRedeemScript(); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - federation = createDefaultNonStandardErpFederation(); - Script postRskip293RedeemScript = federation.getRedeemScript(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); + Script postRskip293RedeemScript = nonStandardErpFederation.getRedeemScript(); Assertions.assertNotEquals(preRskip293RedeemScript, postRskip293RedeemScript); } @@ -588,20 +588,20 @@ void getRedeemScript_before_RSKIP_284_testnet() { networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); - assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); + assertEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, nonStandardErpFederation.getRedeemScript()); } @Test void getRedeemScript_before_RSKIP_284_mainnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); //when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); - Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); + Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, nonStandardErpFederation.getRedeemScript()); validateErpRedeemScript( - federation.getRedeemScript(), + nonStandardErpFederation.getRedeemScript(), activationDelayValue ); } @@ -611,14 +611,14 @@ void getRedeemScript_after_RSKIP_284_testnet() { networkParameters = NetworkParameters.fromID(NetworkParameters.ID_TESTNET); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); - ErpRedeemScriptBuilder builder = federation.getErpRedeemScriptBuilder(); + ErpRedeemScriptBuilder builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); assertTrue(builder instanceof NonStandardErpRedeemScriptBuilderWithCsvUnsignedBE); - Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); + Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, nonStandardErpFederation.getRedeemScript()); validateErpRedeemScript( - federation.getRedeemScript(), + nonStandardErpFederation.getRedeemScript(), activationDelayValue ); } @@ -628,19 +628,19 @@ void getRedeemScript_after_RSKIP_201_before_RSKIP_293_mainnet() { ErpRedeemScriptBuilder builder; // check the hardcoded fed didnt exist on mainnet after rskip201 - federation = createDefaultNonStandardErpFederation(); - builder = federation.getErpRedeemScriptBuilder(); - Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, federation.getRedeemScript()); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); + builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); + Assertions.assertNotEquals(TestConstants.ERP_TESTNET_REDEEM_SCRIPT, nonStandardErpFederation.getRedeemScript()); assertFalse(builder instanceof NonStandardErpRedeemScriptBuilderHardcoded); // check the hardcoded fed didnt exist on mainnet after rskip284 when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); - federation = createDefaultNonStandardErpFederation(); - builder = federation.getErpRedeemScriptBuilder(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); + builder = nonStandardErpFederation.getErpRedeemScriptBuilder(); assertFalse(builder instanceof NonStandardErpRedeemScriptBuilderHardcoded); validateErpRedeemScript( - federation.getRedeemScript(), + nonStandardErpFederation.getRedeemScript(), activationDelayValue ); } @@ -651,23 +651,23 @@ void testEquals_differentRedeemScript() { // Both federations created before RSKIP284 with the same data, should have the same redeem script when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(false); - Federation erpFederation = createDefaultNonStandardErpFederation(); + ErpFederation nonStandardErpFederation = createDefaultNonStandardErpFederation(); Federation otherErpFederation = createDefaultNonStandardErpFederation(); - assertEquals(erpFederation, otherErpFederation); + assertEquals(nonStandardErpFederation, otherErpFederation); - // One federation created after RSKIP284 with the same data, should have different redeem script + // One nonStandardErpFederation created after RSKIP284 with the same data, should have different redeem script when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); otherErpFederation = createDefaultNonStandardErpFederation(); - assertNotEquals(erpFederation, otherErpFederation); + assertNotEquals(nonStandardErpFederation, otherErpFederation); - // The other federation created after RSKIP284 with the same data, should have same redeem script - erpFederation = createDefaultNonStandardErpFederation(); - assertEquals(erpFederation, otherErpFederation); + // The other nonStandardErpFederation created after RSKIP284 with the same data, should have same redeem script + nonStandardErpFederation = createDefaultNonStandardErpFederation(); + assertEquals(nonStandardErpFederation, otherErpFederation); } @Disabled("Can't recreate the hardcoded redeem script since the needed CSV value is above the max. Keeping the test ignored as testimonial") @Test - void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { + void createNonStandardErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { // We can't test the same condition before RSKIP293 since the serialization used by bj-thin // prior to RSKIP293 enforces the CSV value to be encoded using 2 bytes. // The hardcoded script has a 3 byte long CSV value @@ -699,14 +699,14 @@ void createErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fails() { } @Test - void spendFromErpFed_before_RSKIP293_testnet_using_erp_multisig_can_spend() { + void spendFromNonStandardErpFed_before_RSKIP293_testnet_using_erp_multisig_can_spend() { BridgeConstants constants = BridgeTestNetConstants.getInstance(); // The CSV value defined in BridgeTestnetConstants, // actually allows the emergency multisig to spend before the expected amount of blocks // Since it's encoded as BE and decoded as LE, the result is a number lower than the one defined in the constant assertDoesNotThrow(() -> - spendFromErpFed( + spendFromNonStandardErpFed( constants.getBtcParams(), constants.getErpFedActivationDelay(), false, @@ -715,14 +715,14 @@ void spendFromErpFed_before_RSKIP293_testnet_using_erp_multisig_can_spend() { } @Test - void spendFromErpFed_before_RSKIP293_testnet_using_erp_multisig_cant_spend() { + void spendFromNonStandardErpFed_before_RSKIP293_testnet_using_erp_multisig_cant_spend() { BridgeConstants constants = BridgeTestNetConstants.getInstance(); // Should fail due to the wrong encoding of the CSV value // In this case, the value 300 when encoded as BE and decoded as LE results in a larger number // This causes the validation to fail NetworkParameters btcParams = constants.getBtcParams(); - assertThrows(ScriptException.class, () -> spendFromErpFed( + assertThrows(ScriptException.class, () -> spendFromNonStandardErpFed( btcParams, 300, false, @@ -731,11 +731,11 @@ void spendFromErpFed_before_RSKIP293_testnet_using_erp_multisig_cant_spend() { } @Test - void spendFromErpFed_before_RSKIP293_testnet_using_standard_multisig() { + void spendFromNonStandardErpFed_before_RSKIP293_testnet_using_standard_multisig_can_spend() { BridgeConstants constants = BridgeTestNetConstants.getInstance(); // Should validate since it's not executing the path of the script with the CSV value - assertDoesNotThrow(() -> spendFromErpFed( + assertDoesNotThrow(() -> spendFromNonStandardErpFed( constants.getBtcParams(), constants.getErpFedActivationDelay(), false, @@ -744,13 +744,13 @@ void spendFromErpFed_before_RSKIP293_testnet_using_standard_multisig() { } @Test - void spendFromErpFed_before_RSKIP293_mainnet_using_erp_multisig_can_spend() { + void spendFromNonStandardErpFed_before_RSKIP293_mainnet_using_erp_multisig_can_spend() { BridgeConstants constants = BridgeMainNetConstants.getInstance(); // The CSV value defined in BridgeMainnetConstants, // actually allows the emergency multisig to spend before the expected amount of blocks // Since it's encoded as BE and decoded as LE, the result is a number lower than the one defined in the constant - assertDoesNotThrow(() -> spendFromErpFed( + assertDoesNotThrow(() -> spendFromNonStandardErpFed( constants.getBtcParams(), constants.getErpFedActivationDelay(), false, @@ -759,13 +759,13 @@ void spendFromErpFed_before_RSKIP293_mainnet_using_erp_multisig_can_spend() { } @Test - void spendFromErpFed_before_RSKIP293_mainnet_using_erp_multisig_cant_spend() { + void spendFromNonStandardErpFed_before_RSKIP293_mainnet_using_erp_multisig_cant_spend() { // Should fail due to the wrong encoding of the CSV value // In this case, the value 300 when encoded as BE and decoded as LE results in a larger number // This causes the validation to fail when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(false); - assertThrows(ScriptException.class, () -> spendFromErpFed( + assertThrows(ScriptException.class, () -> spendFromNonStandardErpFed( networkParameters, 300, false, @@ -774,11 +774,11 @@ void spendFromErpFed_before_RSKIP293_mainnet_using_erp_multisig_cant_spend() { } @Test - void spendFromErpFed_before_RSKIP293_mainnet_using_standard_multisig() { + void spendFromNonStandardErpFed_before_RSKIP293_mainnet_using_standard_multisig_can_spend() { BridgeConstants constants = BridgeMainNetConstants.getInstance(); // Should validate since it's not executing the path of the script with the CSV value - assertDoesNotThrow(() -> spendFromErpFed( + assertDoesNotThrow(() -> spendFromNonStandardErpFed( constants.getBtcParams(), constants.getErpFedActivationDelay(), false, @@ -787,11 +787,11 @@ void spendFromErpFed_before_RSKIP293_mainnet_using_standard_multisig() { } @Test - void spendFromErpFed_after_RSKIP293_testnet_using_erp_multisig() { + void spendFromNonStandardErpFed_after_RSKIP293_testnet_using_erp_multisig_can_spend() { BridgeConstants constants = BridgeTestNetConstants.getInstance(); // Post RSKIP293 activation it should encode the CSV value correctly - assertDoesNotThrow(() -> spendFromErpFed( + assertDoesNotThrow(() -> spendFromNonStandardErpFed( constants.getBtcParams(), constants.getErpFedActivationDelay(), true, @@ -800,10 +800,10 @@ void spendFromErpFed_after_RSKIP293_testnet_using_erp_multisig() { } @Test - void spendFromErpFed_after_RSKIP293_testnet_using_standard_multisig() { + void spendFromNonStandardErpFed_after_RSKIP293_testnet_using_standard_multisig_can_spend() { BridgeConstants constants = BridgeTestNetConstants.getInstance(); - assertDoesNotThrow(() -> spendFromErpFed( + assertDoesNotThrow(() -> spendFromNonStandardErpFed( constants.getBtcParams(), constants.getErpFedActivationDelay(), true, @@ -812,11 +812,11 @@ void spendFromErpFed_after_RSKIP293_testnet_using_standard_multisig() { } @Test - void spendFromErpFed_after_RSKIP293_mainnet_using_erp_multisig() { + void spendFromNonStandardErpFed_after_RSKIP293_mainnet_using_erp_multisig_can_spend() { BridgeConstants constants = BridgeMainNetConstants.getInstance(); // Post RSKIP293 activation it should encode the CSV value correctly - assertDoesNotThrow(() -> spendFromErpFed( + assertDoesNotThrow(() -> spendFromNonStandardErpFed( constants.getBtcParams(), constants.getErpFedActivationDelay(), true, @@ -825,10 +825,10 @@ void spendFromErpFed_after_RSKIP293_mainnet_using_erp_multisig() { } @Test - void spendFromErpFed_after_RSKIP293_mainnet_using_standard_multisig() { + void spendFromNonStandardErpFed_after_RSKIP293_mainnet_using_standard_multisig_can_spend() { BridgeConstants constants = BridgeMainNetConstants.getInstance(); - assertDoesNotThrow(() -> spendFromErpFed( + assertDoesNotThrow(() -> spendFromNonStandardErpFed( constants.getBtcParams(), constants.getErpFedActivationDelay(), true, @@ -838,17 +838,17 @@ void spendFromErpFed_after_RSKIP293_mainnet_using_standard_multisig() { private void createAndValidateFederation() { - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); validateErpRedeemScript( - federation.getRedeemScript(), + nonStandardErpFederation.getRedeemScript(), defaultKeys, emergencyKeys, activationDelayValue ); } - private void spendFromErpFed( + private void spendFromNonStandardErpFed( NetworkParameters networkParametersValue, long activationDelay, boolean isRskip293Active, @@ -871,12 +871,12 @@ private void spendFromErpFed( Collections.singletonList(ConsensusRule.RSKIP293); activations = ActivationConfigsForTest.hop400(except).forBlock(0); - federation = createDefaultNonStandardErpFederation(); + nonStandardErpFederation = createDefaultNonStandardErpFederation(); Coin value = Coin.valueOf(1_000_000); Coin fee = Coin.valueOf(10_000); BtcTransaction fundTx = new BtcTransaction(networkParameters); - fundTx.addOutput(value, federation.getAddress()); + fundTx.addOutput(value, nonStandardErpFederation.getAddress()); Address destinationAddress = BitcoinTestUtils.createP2PKHAddress( networkParameters, @@ -885,7 +885,7 @@ private void spendFromErpFed( FederationTestUtils.spendFromErpFed( networkParameters, - federation, + nonStandardErpFederation, signWithEmergencyMultisig ? emergencyKeys : defaultKeys, fundTx.getHash(), 0, From f6eeb460f31e4f60eb9993dec19c0d239d14b013 Mon Sep 17 00:00:00 2001 From: julia zack Date: Wed, 10 Jan 2024 10:41:54 -0300 Subject: [PATCH 047/137] Make FederationArgs fields private and create accessors. Adapt. Rename some variables to be clearer. Remove federationArgs field from Federation and so getArgs method. --- .../co/rsk/peg/BridgeStorageProvider.java | 2 +- .../co/rsk/peg/federation/ErpFederation.java | 4 +-- .../rsk/peg/federation/ErpFederationArgs.java | 13 ++++--- .../co/rsk/peg/federation/Federation.java | 12 +++---- .../co/rsk/peg/federation/FederationArgs.java | 20 ++++++++--- .../rsk/peg/federation/FederationFactory.java | 2 +- .../rsk/peg/federation/PendingFederation.java | 16 ++++----- .../co/rsk/peg/BridgeStorageProviderTest.java | 2 +- ...idgeSupportRegisterBtcTransactionTest.java | 3 -- .../java/co/rsk/peg/BridgeSupportTest.java | 36 +++++++++---------- .../peg/federation/PendingFederationTest.java | 2 +- 11 files changed, 62 insertions(+), 50 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index ec67eb953f8..b4e4ae3ab47 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -446,7 +446,7 @@ public PendingFederation getPendingFederation() { return PendingFederation.deserialize(data); // Assume this is the multi-key version } - return PendingFederation.deserializeFromBtcKeys(data); + return PendingFederation.deserializeFromBtcKeysOnly(data); } ); diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java index 20b889a4996..e98d4562faa 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java @@ -28,8 +28,8 @@ protected ErpFederation( ) { super(erpFederationArgs, formatVersion); - this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpFederationArgs.erpPubKeys); - this.activationDelay = erpFederationArgs.activationDelay; + this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpFederationArgs.getErpPubKeys()); + this.activationDelay = erpFederationArgs.getActivationDelay(); this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java index 1fae0ebcffd..8f89b478aff 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java @@ -9,8 +9,9 @@ import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; public class ErpFederationArgs extends FederationArgs{ - protected final List erpPubKeys; - protected final long activationDelay; + private final List erpPubKeys; + private final long activationDelay; + public ErpFederationArgs( List members, Instant creationTime, @@ -26,9 +27,13 @@ public ErpFederationArgs( this.activationDelay = activationDelay; } + public List getErpPubKeys() { return erpPubKeys; } + + public long getActivationDelay() { return activationDelay; } + public static ErpFederationArgs fromFederationArgs(FederationArgs federationArgs, List erpPubKeys, long activationDelay){ - return new ErpFederationArgs(federationArgs.members, federationArgs.creationTime, - federationArgs.creationBlockNumber, federationArgs.btcParams, erpPubKeys, activationDelay); + return new ErpFederationArgs(federationArgs.getMembers(), federationArgs.getCreationTime(), + federationArgs.getCreationBlockNumber(), federationArgs.getBtcParams(), erpPubKeys, activationDelay); } private void validateEmergencyKeys(List erpPubKeys) { diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java index b5e0fa9d3f3..288d8458390 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/Federation.java @@ -39,7 +39,6 @@ */ public abstract class Federation { - protected final FederationArgs federationArgs; protected final List members; protected final Instant creationTime; protected final long creationBlockNumber; @@ -57,11 +56,10 @@ protected Federation( // Sorting members ensures same order of federation members for same members // Immutability provides protection against unwanted modification, thus making the Federation instance // effectively immutable - this.federationArgs = federationArgs; - this.members = Collections.unmodifiableList(federationArgs.members.stream().sorted(FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR).collect(Collectors.toList())); - this.creationTime = federationArgs.creationTime.truncatedTo(ChronoUnit.MILLIS); - this.creationBlockNumber = federationArgs.creationBlockNumber; - this.btcParams = federationArgs.btcParams; + this.members = Collections.unmodifiableList(federationArgs.getMembers().stream().sorted(FederationMember.BTC_RSK_MST_PUBKEYS_COMPARATOR).collect(Collectors.toList())); + this.creationTime = federationArgs.getCreationTime().truncatedTo(ChronoUnit.MILLIS); + this.creationBlockNumber = federationArgs.getCreationBlockNumber(); + this.btcParams = federationArgs.getBtcParams(); this.formatVersion = formatVersion; } @@ -70,7 +68,7 @@ public int getFormatVersion() { } public FederationArgs getArgs() { - return federationArgs; + return new FederationArgs(members, creationTime, creationBlockNumber, btcParams); } public List getMembers() { // Safe to return members since diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java index aed980038d1..1d1f67f6ff7 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java @@ -6,10 +6,10 @@ import java.util.List; public class FederationArgs { - protected final List members; - protected final Instant creationTime; - protected final long creationBlockNumber; - protected final NetworkParameters btcParams; + private final List members; + private final Instant creationTime; + private final long creationBlockNumber; + private final NetworkParameters btcParams; public FederationArgs(List members, Instant creationTime, long creationBlockNumber, NetworkParameters btcParams) { @@ -18,4 +18,16 @@ public FederationArgs(List members, Instant creationTime, this.creationBlockNumber = creationBlockNumber; this.btcParams = btcParams; } + + public List getMembers() { + return members; + } + + public Instant getCreationTime() { + return creationTime; + } + + public long getCreationBlockNumber() { return creationBlockNumber; } + public NetworkParameters getBtcParams() { return btcParams; } + } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java index 8b60489d600..df3dacc2f19 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java @@ -21,7 +21,7 @@ public static StandardMultisigFederation buildStandardMultiSigFederation(Federat public static ErpFederation buildNonStandardErpFederation(ErpFederationArgs erpFederationArgs, ActivationConfig.ForBlock activations) { - NetworkParameters btcParams = erpFederationArgs.btcParams; + NetworkParameters btcParams = erpFederationArgs.getBtcParams(); ErpRedeemScriptBuilder erpRedeemScriptBuilder = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, btcParams); diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index 92e8efb0963..e6e2aaf3954 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -98,29 +98,29 @@ public PendingFederation addMember(FederationMember member) { * @return a Federation */ public Federation buildFederation( - Instant creationTime, - long blockNumber, - BridgeConstants bridgeConstants, - ActivationConfig.ForBlock activations + Instant creationTime, + long creationBlockNumber, + BridgeConstants bridgeConstants, + ActivationConfig.ForBlock activations ) { if (!this.isComplete()) { throw new IllegalStateException("PendingFederation is incomplete"); } NetworkParameters btcParams = bridgeConstants.getBtcParams(); - FederationArgs federationArgs = new FederationArgs(members, creationTime, blockNumber, btcParams); + FederationArgs federationArgs = new FederationArgs(members, creationTime, creationBlockNumber, btcParams); if (shouldBuildStandardMultisigFederation(activations)){ return FederationFactory.buildStandardMultiSigFederation(federationArgs); } - // should build and erp federation due to activations + // should build an erp federation due to activations List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); if (shouldBuildNonStandardErpFederation(activations)) { - logger.info("[buildFederation] Going to create an ERP Federation"); + logger.info("[buildFederation] Going to create a Non-Standard ERP Federation"); return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); } @@ -221,7 +221,7 @@ private byte[] serializeOnlyBtcKeys() { return RLP.encodeList(encodedKeys.toArray(new byte[0][])); } - public static PendingFederation deserializeFromBtcKeys(byte[] data) { + public static PendingFederation deserializeFromBtcKeysOnly(byte[] data) { // BTC, RSK and MST keys are the same List deserializedMembers = deserializeBtcPublicKeys(data).stream() .map(FederationMember::getFederationMemberFromKey) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index e43cbba1b1b..1d84e910d70 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -934,7 +934,7 @@ void getPendingFederation_initialVersion() { }); try (MockedStatic pendingFederationMocked = mockStatic(PendingFederation.class)) { - pendingFederationMocked.when(() -> PendingFederation.deserializeFromBtcKeys(any(byte[].class))).then((InvocationOnMock invocation) -> { + pendingFederationMocked.when(() -> PendingFederation.deserializeFromBtcKeysOnly(any(byte[].class))).then((InvocationOnMock invocation) -> { deserializeCalls.add(0); byte[] data = invocation.getArgument(0); // Make sure we're deserializing what just came from the repo with the correct BTC context diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index f9e07fc66b9..037f0407337 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -57,9 +57,6 @@ class BridgeSupportRegisterBtcTransactionTest { private static final Coin minimumPeginTxValue = bridgeMainnetConstants.getMinimumPeginTxValue(ActivationConfigsForTest.all().forBlock(0)); private static final Coin belowMinimumPeginTxValue = minimumPeginTxValue.minus(Coin.SATOSHI); - private static final Coin minimumPeginTxValue = bridgeMainnetConstants.getMinimumPeginTxValue(ActivationConfigsForTest.all().forBlock(0)); - private static final Coin belowMinimumPeginTxValue = minimumPeginTxValue.minus(Coin.SATOSHI); - private static final int FIRST_OUTPUT_INDEX = 0; private static final int FIRST_INPUT_INDEX = 0; 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 1589b2742e3..294d0bb90a3 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -963,36 +963,36 @@ void registerBtcTransactionLockTxNotWhitelisted_before_rskip_146_activation() th NetworkParameters btcParams = NetworkParameters.fromID(NetworkParameters.ID_REGTEST); BridgeEventLogger bridgeEventLogger = mock(BridgeEventLogger.class); - //Creates federation 1 - List federation1Keys = Arrays.asList( + // Creates active federation + List newFederationKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ); - FederationArgs federation1Args = new FederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(federation1Keys), + FederationArgs newFederationArgs = new FederationArgs( + FederationTestUtils.getFederationMembersWithBtcKeys(newFederationKeys), Instant.ofEpochMilli(1000L), 0L, btcParams ); - Federation federation1 = FederationFactory.buildStandardMultiSigFederation( - federation1Args + Federation newFederation = FederationFactory.buildStandardMultiSigFederation( + newFederationArgs ); - //Creates federation 2 - List federation2Keys = Arrays.asList( + // Creates retiring federation + List retiringFederationKeys = Arrays.asList( BtcECKey.fromPrivate(Hex.decode("fb01")), BtcECKey.fromPrivate(Hex.decode("fb02")), BtcECKey.fromPrivate(Hex.decode("fb03"))); - FederationArgs federation2Args = new FederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(federation2Keys), + FederationArgs retiringFederationArgs = new FederationArgs( + FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), Instant.ofEpochMilli(2000L), 0L, btcParams ); - Federation federation2 = FederationFactory.buildStandardMultiSigFederation( - federation2Args + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( + retiringFederationArgs ); Repository repository = createRepository(); @@ -1002,29 +1002,29 @@ void registerBtcTransactionLockTxNotWhitelisted_before_rskip_146_activation() th // First transaction goes only to the first federation BtcTransaction tx1 = new BtcTransaction(btcRegTestParams); - tx1.addOutput(Coin.COIN.multiply(5), federation1.getAddress()); + tx1.addOutput(Coin.COIN.multiply(5), newFederation.getAddress()); BtcECKey srcKey1 = new BtcECKey(); tx1.addInput(BitcoinTestUtils.createHash(1), 0, ScriptBuilder.createInputScript(null, srcKey1)); // Second transaction goes only to the second federation BtcTransaction tx2 = new BtcTransaction(btcRegTestParams); - tx2.addOutput(Coin.COIN.multiply(10), federation2.getAddress()); + tx2.addOutput(Coin.COIN.multiply(10), retiringFederation.getAddress()); BtcECKey srcKey2 = new BtcECKey(); tx2.addInput(BitcoinTestUtils.createHash(1), 0, ScriptBuilder.createInputScript(null, srcKey2)); // Third transaction has one output to each federation // Lock is expected to be done accordingly and utxos assigned accordingly as well BtcTransaction tx3 = new BtcTransaction(btcRegTestParams); - tx3.addOutput(Coin.COIN.multiply(3), federation1.getAddress()); - tx3.addOutput(Coin.COIN.multiply(4), federation2.getAddress()); + tx3.addOutput(Coin.COIN.multiply(3), newFederation.getAddress()); + tx3.addOutput(Coin.COIN.multiply(4), retiringFederation.getAddress()); BtcECKey srcKey3 = new BtcECKey(); tx3.addInput(PegTestUtils.createHash(), 0, ScriptBuilder.createInputScript(null, srcKey3)); BtcBlockStoreWithCache btcBlockStore = mock(BtcBlockStoreWithCache.class); BridgeStorageProvider provider = new BridgeStorageProvider(repository, contractAddress, bridgeConstantsRegtest, activations); - provider.setNewFederation(federation1); - provider.setOldFederation(federation2); + provider.setNewFederation(newFederation); + provider.setOldFederation(retiringFederation); BtcBlockStoreWithCache.Factory mockFactory = mock(BtcBlockStoreWithCache.Factory.class); when(mockFactory.newInstance(repository, bridgeConstantsRegtest, provider, activations)).thenReturn(btcBlockStore); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java index 8df4e733763..ada7c3b8d85 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java @@ -374,7 +374,7 @@ void deserializePendingFederationOnlyBtcKeys() throws Exception { byte[] data = RLP.encodeList(rlpBytes); - PendingFederation deserializedPendingFederation = PendingFederation.deserializeFromBtcKeys(data); + PendingFederation deserializedPendingFederation = PendingFederation.deserializeFromBtcKeysOnly(data); Assertions.assertEquals(6, deserializedPendingFederation.getBtcPublicKeys().size()); for (int i = 0; i < 6; i++) { From 1bce5c3aaf01332a79becb22f22d8398b0ecb993 Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 11 Jan 2024 16:11:12 -0300 Subject: [PATCH 048/137] Create getErpArgs method for ErpFederation. Create tests for both FederationArgs and ErpFederationArgs classes --- .../co/rsk/peg/federation/ErpFederation.java | 3 ++ .../NonStandardErpFederationsTest.java | 39 ++++++++++++++++++ .../peg/federation/P2shErpFederationTest.java | 40 +++++++++++++++++++ .../StandardMultisigFederationTest.java | 27 +++++++++++++ 4 files changed, 109 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java index e98d4562faa..10e0662d82a 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java @@ -33,6 +33,9 @@ protected ErpFederation( this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; } + public ErpFederationArgs getErpArgs() { + return new ErpFederationArgs(members, creationTime, creationBlockNumber, btcParams, erpPubKeys, activationDelay); + } public ErpRedeemScriptBuilder getErpRedeemScriptBuilder() { return erpRedeemScriptBuilder; } diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java index dd19387d3d6..a67452d2d13 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java @@ -258,6 +258,45 @@ void testEquals_same() { assertEquals(nonStandardErpFederation, otherFederation); } + @Test + void values_from_erpFederationArgs_equal_values_from_nonStandardErpFederation() { + ErpFederationArgs erpFederationArgs = nonStandardErpFederation.getErpArgs(); + List federationMembersFromErpArgs = erpFederationArgs.getMembers(); + Instant creationTimeFromErpArgs = erpFederationArgs.getCreationTime(); + long creationBlockNumberFromErpArgs = erpFederationArgs.getCreationBlockNumber(); + NetworkParameters btcParamsFromErpArgs = erpFederationArgs.getBtcParams(); + List emergencyKeysFromErpArgs = erpFederationArgs.getErpPubKeys(); + long activationDelayFromErpArgs = erpFederationArgs.getActivationDelay(); + + List members = nonStandardErpFederation.getMembers(); + Instant creationTime = nonStandardErpFederation.getCreationTime(); + long creationBlockNumber = nonStandardErpFederation.getCreationBlockNumber(); + + assertEquals(members, federationMembersFromErpArgs); + assertEquals(creationTime, creationTimeFromErpArgs); + assertEquals(creationBlockNumber, creationBlockNumberFromErpArgs); + assertEquals(networkParameters, btcParamsFromErpArgs); + assertEquals(emergencyKeys, emergencyKeysFromErpArgs); + assertEquals(activationDelayValue, activationDelayFromErpArgs); + } + + @Test + void nonStandardErpFederation_from_federationArgs_and_erp_values_equals_nonStandardErpFederation() { + FederationArgs federationArgs = nonStandardErpFederation.getArgs(); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, emergencyKeys, activationDelayValue); + ErpFederation nonStandardErpFederationFromFederationArgs = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + + assertEquals(nonStandardErpFederation, nonStandardErpFederationFromFederationArgs); + } + + @Test + void nonStandardErpFederation_from_erpFederationArgs_equals_nonStandardErpFederation() { + ErpFederationArgs erpFederationArgs = nonStandardErpFederation.getErpArgs(); + ErpFederation federationFromFederationArgs = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + + assertEquals(nonStandardErpFederation, federationFromFederationArgs); + } + @Test void testEquals_differentCreationTime() { ErpFederationArgs erpFederationArgs = new ErpFederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime().plus(1, ChronoUnit.MILLIS), diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java index 6f6732f30a8..ee5f4ec77bc 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java @@ -229,6 +229,46 @@ void testEquals_same() { assertEquals(federation, otherFederation); } + @Test + void values_from_erpFederationArgs_equal_values_from_p2shErpFederation() { + ErpFederationArgs erpFederationArgs = federation.getErpArgs(); + List federationMembersFromErpArgs = erpFederationArgs.getMembers(); + Instant creationTimeFromErpArgs = erpFederationArgs.getCreationTime(); + long creationBlockNumberFromErpArgs = erpFederationArgs.getCreationBlockNumber(); + NetworkParameters btcParamsFromErpArgs = erpFederationArgs.getBtcParams(); + List emergencyKeysFromErpArgs = erpFederationArgs.getErpPubKeys(); + long activationDelayFromErpArgs = erpFederationArgs.getActivationDelay(); + + List members = federation.getMembers(); + Instant creationTime = federation.getCreationTime(); + long creationBlockNumber = federation.getCreationBlockNumber(); + + assertEquals(members, federationMembersFromErpArgs); + assertEquals(creationTime, creationTimeFromErpArgs); + assertEquals(creationBlockNumber, creationBlockNumberFromErpArgs); + assertEquals(networkParameters, btcParamsFromErpArgs); + assertEquals(emergencyKeys, emergencyKeysFromErpArgs); + assertEquals(activationDelayValue, activationDelayFromErpArgs); + } + + @Test + void p2shErpFederation_from_federationArgs_and_erp_values_equals_p2shErpFederation() { + FederationArgs federationArgs = federation.getArgs(); + ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, emergencyKeys, activationDelayValue); + + ErpFederation federationFromFederationArgs = FederationFactory.buildP2shErpFederation(erpFederationArgs); + + assertEquals(federation, federationFromFederationArgs); + } + + @Test + void p2shErpFederation_from_erpFederationArgs_equals_p2shErpFederation() { + ErpFederationArgs erpFederationArgs = federation.getErpArgs(); + ErpFederation federationFromFederationArgs = FederationFactory.buildP2shErpFederation(erpFederationArgs); + + assertEquals(federation, federationFromFederationArgs); + } + @Test void testEquals_differentNumberOfMembers() { // remove federator9 diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java index dc7c72fd485..086a45a4617 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java @@ -135,6 +135,33 @@ void testEquals_same() { assertEquals(federation, otherFederation); } + @Test + void values_from_federationArgs_equal_values_from_federation() { + FederationArgs actualFederationArgs = federation.getArgs(); + List federationMembersFromArgs = actualFederationArgs.getMembers(); + Instant creationTimeFromArgs = actualFederationArgs.getCreationTime(); + long creationBlockNumberFromArgs = actualFederationArgs.getCreationBlockNumber(); + NetworkParameters btcParamsFromArgs = actualFederationArgs.getBtcParams(); + + List federationMembers = federation.getMembers(); + Instant creationTime = federation.getCreationTime(); + long creationBlockNumber = federation.getCreationBlockNumber(); + NetworkParameters btcParams = federation.getBtcParams(); + + assertEquals(federationMembers, federationMembersFromArgs); + assertEquals(creationTime, creationTimeFromArgs); + assertEquals(creationBlockNumber, creationBlockNumberFromArgs); + assertEquals(btcParams, btcParamsFromArgs); + } + + @Test + void federation_from_federationArgs_equals_federation() { + FederationArgs federationArgs = federation.getArgs(); + Federation federationFromFederationArgs = FederationFactory.buildStandardMultiSigFederation(federationArgs); + + assertEquals(federation, federationFromFederationArgs); + } + @Test void testEquals_differentCreationTime() { FederationArgs federationArgs = new FederationArgs( From ebdfe7f094047a8359278a1c9f12da13acb245ee Mon Sep 17 00:00:00 2001 From: julia zack Date: Thu, 11 Jan 2024 20:25:46 -0300 Subject: [PATCH 049/137] Create equals methods in FederationArgs and ErpFederationArgs. Simplify tests using them --- .../co/rsk/peg/BridgeSerializationUtils.java | 6 +- .../co/rsk/peg/federation/ErpFederation.java | 25 ++-- .../rsk/peg/federation/ErpFederationArgs.java | 45 -------- .../co/rsk/peg/federation/FederationArgs.java | 42 ++++++- .../rsk/peg/federation/FederationFactory.java | 22 +++- .../rsk/peg/federation/PendingFederation.java | 5 +- .../rsk/peg/BridgeSerializationUtilsTest.java | 13 +-- .../BridgeStorageProviderFederationTests.java | 5 +- .../co/rsk/peg/BridgeStorageProviderTest.java | 29 ++--- ...idgeSupportRegisterBtcTransactionTest.java | 12 +- .../java/co/rsk/peg/BridgeSupportTest.java | 35 ++---- .../test/java/co/rsk/peg/BridgeUtilsTest.java | 30 ++--- ...verCompatibleBtcWalletWithStorageTest.java | 3 +- ...patibleBtcWallextWithSingleScriptTest.java | 3 +- .../test/java/co/rsk/peg/PegTestUtils.java | 5 +- .../PegUtilsLegacyGetTransactionTypeTest.java | 19 ++- .../java/co/rsk/peg/PegUtilsLegacyTest.java | 109 +++++++----------- .../test/java/co/rsk/peg/PegUtilsTest.java | 12 +- .../test/java/co/rsk/peg/PocSighashTest.java | 56 +++------ .../java/co/rsk/peg/PowpegMigrationTest.java | 8 +- .../peg/ReleaseTransactionBuilderTest.java | 16 +-- .../peg/federation/FederationFactoryTest.java | 12 +- .../NonStandardErpFederationsTest.java | 71 +++++------- .../peg/federation/P2shErpFederationTest.java | 68 ++++------- .../peg/federation/PendingFederationTest.java | 21 +++- .../StandardMultisigFederationTest.java | 13 +-- 26 files changed, 278 insertions(+), 407 deletions(-) delete mode 100644 rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java index 45c61a82d2e..2faf18dcaea 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSerializationUtils.java @@ -327,8 +327,7 @@ public static ErpFederation deserializeNonStandardErpFederation( List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + return FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); } public static ErpFederation deserializeP2shErpFederation( @@ -345,8 +344,7 @@ public static ErpFederation deserializeP2shErpFederation( List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - return FederationFactory.buildP2shErpFederation(erpFederationArgs); + return FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); } // An ABI call election is serialized as a list of the votes, like so: diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java index 10e0662d82a..c988f3aa0bc 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java @@ -8,10 +8,10 @@ import co.rsk.bitcoinj.script.ScriptChunk; import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.RedeemScriptCreationException; -import co.rsk.peg.utils.EcKeyUtils; import java.util.Collections; import java.util.List; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; import static co.rsk.peg.federation.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; public class ErpFederation extends Federation { @@ -22,19 +22,19 @@ public class ErpFederation extends Federation { private final ErpRedeemScriptBuilder erpRedeemScriptBuilder; protected ErpFederation( - ErpFederationArgs erpFederationArgs, + FederationArgs federationArgs, + List erpPubKeys, + long activationDelay, ErpRedeemScriptBuilder erpRedeemScriptBuilder, int formatVersion ) { - super(erpFederationArgs, formatVersion); + super(federationArgs, formatVersion); - this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpFederationArgs.getErpPubKeys()); - this.activationDelay = erpFederationArgs.getActivationDelay(); - this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; - } + validateEmergencyKeys(erpPubKeys); - public ErpFederationArgs getErpArgs() { - return new ErpFederationArgs(members, creationTime, creationBlockNumber, btcParams, erpPubKeys, activationDelay); + this.erpPubKeys = erpPubKeys; + this.activationDelay = activationDelay; + this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; } public ErpRedeemScriptBuilder getErpRedeemScriptBuilder() { return erpRedeemScriptBuilder; } @@ -92,4 +92,11 @@ public Script getDefaultP2SHScript() { return defaultP2SHScript; } + private void validateEmergencyKeys(List erpPubKeys) { + if (erpPubKeys == null || erpPubKeys.isEmpty()) { + String message = "Emergency keys are not provided"; + throw new ErpFederationCreationException(message, NULL_OR_EMPTY_EMERGENCY_KEYS); + } + } + } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java deleted file mode 100644 index 8f89b478aff..00000000000 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederationArgs.java +++ /dev/null @@ -1,45 +0,0 @@ -package co.rsk.peg.federation; - -import co.rsk.bitcoinj.core.BtcECKey; -import co.rsk.bitcoinj.core.NetworkParameters; - -import java.time.Instant; -import java.util.List; - -import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; - -public class ErpFederationArgs extends FederationArgs{ - private final List erpPubKeys; - private final long activationDelay; - - public ErpFederationArgs( - List members, - Instant creationTime, - long creationBlockNumber, - NetworkParameters btcParams, - List erpPubKeys, - long activationDelay - ) { - super(members, creationTime, creationBlockNumber, btcParams); - - validateEmergencyKeys(erpPubKeys); - this.erpPubKeys = erpPubKeys; - this.activationDelay = activationDelay; - } - - public List getErpPubKeys() { return erpPubKeys; } - - public long getActivationDelay() { return activationDelay; } - - public static ErpFederationArgs fromFederationArgs(FederationArgs federationArgs, List erpPubKeys, long activationDelay){ - return new ErpFederationArgs(federationArgs.getMembers(), federationArgs.getCreationTime(), - federationArgs.getCreationBlockNumber(), federationArgs.getBtcParams(), erpPubKeys, activationDelay); - } - - private void validateEmergencyKeys(List erpPubKeys) { - if (erpPubKeys == null || erpPubKeys.isEmpty()) { - String message = "Emergency keys are not provided"; - throw new ErpFederationCreationException(message, NULL_OR_EMPTY_EMERGENCY_KEYS); - } - } -} diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java index 1d1f67f6ff7..ac5bda7b83e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationArgs.java @@ -4,6 +4,7 @@ import java.time.Instant; import java.util.List; +import java.util.Objects; public class FederationArgs { private final List members; @@ -19,15 +20,44 @@ public FederationArgs(List members, Instant creationTime, this.btcParams = btcParams; } - public List getMembers() { - return members; + public List getMembers() { return members; } + public Instant getCreationTime() { return creationTime; } + public long getCreationBlockNumber() { return creationBlockNumber; } + public NetworkParameters getBtcParams() { return btcParams; } + + @Override + public String toString() { + return String.format("Got federation args with values %s, %s, %d, %s", + getMembers(), getCreationTime(), getCreationBlockNumber(), getBtcParams() + ); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (other == null || this.getClass() != other.getClass()) { + return false; + } + + FederationArgs otherFederationArgs = (FederationArgs) other; + return allValuesAreEqual(otherFederationArgs); } - public Instant getCreationTime() { - return creationTime; + @Override + public int hashCode() { + return + Objects.hash(getMembers(), getCreationTime(), getCreationBlockNumber(), getBtcParams()); } - public long getCreationBlockNumber() { return creationBlockNumber; } - public NetworkParameters getBtcParams() { return btcParams; } + private boolean allValuesAreEqual(FederationArgs otherFederationArgs) { + return + otherFederationArgs.getMembers().equals(this.getMembers()) + && otherFederationArgs.getCreationTime().equals(this.getCreationTime()) + && otherFederationArgs.getCreationBlockNumber() == this.getCreationBlockNumber() + && otherFederationArgs.getBtcParams().equals(this.getBtcParams()); + } } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java index df3dacc2f19..b08156697fc 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java @@ -1,11 +1,14 @@ package co.rsk.peg.federation; +import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import java.util.List; + import static co.rsk.peg.federation.FederationFormatVersion.*; public class FederationFactory { @@ -13,25 +16,32 @@ public class FederationFactory { private FederationFactory() {} public static StandardMultisigFederation buildStandardMultiSigFederation(FederationArgs federationArgs) { + return new StandardMultisigFederation( federationArgs, STANDARD_MULTISIG_FEDERATION.getFormatVersion() ); } - public static ErpFederation buildNonStandardErpFederation(ErpFederationArgs erpFederationArgs, + public static ErpFederation buildNonStandardErpFederation(FederationArgs federationArgs, + List erpPubKeys, + long activationDelay, ActivationConfig.ForBlock activations) { - NetworkParameters btcParams = erpFederationArgs.getBtcParams(); + NetworkParameters btcParams = federationArgs.getBtcParams(); ErpRedeemScriptBuilder erpRedeemScriptBuilder = NonStandardErpRedeemScriptBuilderFactory.getNonStandardErpRedeemScriptBuilder(activations, btcParams); - return new ErpFederation(erpFederationArgs, erpRedeemScriptBuilder, NON_STANDARD_ERP_FEDERATION.getFormatVersion() + return new ErpFederation(federationArgs, erpPubKeys, activationDelay, + erpRedeemScriptBuilder, NON_STANDARD_ERP_FEDERATION.getFormatVersion() ); } - public static ErpFederation buildP2shErpFederation(ErpFederationArgs erpFederationArgs) { + public static ErpFederation buildP2shErpFederation(FederationArgs federationArgs, + List erpPubKeys, + long activationDelay) { ErpRedeemScriptBuilder erpRedeemScriptBuilder = new P2shErpRedeemScriptBuilder(); - return new ErpFederation(erpFederationArgs, erpRedeemScriptBuilder, P2SH_ERP_FEDERATION.getFormatVersion() - ); + + return new ErpFederation(federationArgs, erpPubKeys, activationDelay, + erpRedeemScriptBuilder, P2SH_ERP_FEDERATION.getFormatVersion()); } } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java index e6e2aaf3954..301ba7010c3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/PendingFederation.java @@ -117,15 +117,14 @@ public Federation buildFederation( // should build an erp federation due to activations List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); if (shouldBuildNonStandardErpFederation(activations)) { logger.info("[buildFederation] Going to create a Non-Standard ERP Federation"); - return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + return FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); } logger.info("[buildFederation] Going to create a P2SH ERP Federation"); - return FederationFactory.buildP2shErpFederation(erpFederationArgs); + return FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); } private boolean shouldBuildStandardMultisigFederation(ActivationConfig.ForBlock activations) { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java index 1e3cc097e13..1c1a1c8aa1d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSerializationUtilsTest.java @@ -1142,12 +1142,10 @@ private void testSerializeAndDeserializeFederation( BridgeSerializationUtils.deserializeStandardMultisigFederation(serializedTestStandardMultisigFederation, bridgeConstants.getBtcParams()); FederationArgs deserializedTestStandardMultisigFederationArgs = deserializedTestStandardMultisigFederation.getArgs(); - ErpFederationArgs erpFederationArgs = - ErpFederationArgs.fromFederationArgs(deserializedTestStandardMultisigFederationArgs, bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay()); - Federation testNonStandardErpFederation = FederationFactory.buildNonStandardErpFederation( - erpFederationArgs, - activations - ); + List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); + long activationDelay = bridgeConstants.getErpFedActivationDelay(); + Federation testNonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(deserializedTestStandardMultisigFederationArgs, + erpPubKeys, activationDelay, activations); byte[] serializedTestNonStandardErpFederation = BridgeSerializationUtils.serializeFederation(testNonStandardErpFederation); ErpFederation deserializedTestNonStandardErpFederation = BridgeSerializationUtils.deserializeNonStandardErpFederation( @@ -1166,7 +1164,8 @@ private void testSerializeAndDeserializeFederation( } if (isRskip353Active) { - Federation testP2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + Federation testP2shErpFederation = FederationFactory.buildP2shErpFederation(deserializedTestStandardMultisigFederationArgs, + erpPubKeys, activationDelay); byte[] serializedTestP2shErpFederation = BridgeSerializationUtils.serializeFederation(testP2shErpFederation); Federation deserializedTestP2shErpFederation = BridgeSerializationUtils.deserializeP2shErpFederation( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java index 548c962dd85..1be609af42a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderFederationTests.java @@ -615,13 +615,12 @@ private Federation createFederation(int version) { // version should be erp List erpPubKeys = bridgeConstantsRegtest.getErpFedPubKeysList(); long activationDelay = bridgeConstantsRegtest.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); if (version == NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION) { - return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + return FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); } if (version == P2SH_ERP_FEDERATION_FORMAT_VERSION) { - return FederationFactory.buildP2shErpFederation(erpFederationArgs); + return FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); } // To keep backwards compatibility return FederationFactory.buildStandardMultiSigFederation(federationArgs); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java index 1d84e910d70..e26affbfeab 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderTest.java @@ -411,9 +411,8 @@ void getNewFederation_non_standard_erp_and_p2sh_erp_feds() { List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); testGetNewFederationPostMultiKey(nonStandardErpFederation); testGetNewFederationPostMultiKey(p2shErpFederation); @@ -534,8 +533,7 @@ void saveNewFederation_postMultiKey_RSKIP_201_active_non_standard_erp_fed() { List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); testSaveNewFederationPostMultiKey(nonStandardErpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); } @@ -549,8 +547,7 @@ void saveNewFederation_postMultiKey_RSKIP_353_active_p2sh_erp_fed() { List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); testSaveNewFederationPostMultiKey(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activationsAllForks); } @@ -661,20 +658,18 @@ void getOldFederation_non_standard_erp_feds() { List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - // this should get non-standard hardcoded fed ActivationConfig.ForBlock activations = ActivationConfigsForTest.iris300().forBlock(0); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); testGetOldFederation(nonStandardErpFederation, activations); // this should get non-standard with csv unsigned BE fed - nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); testGetOldFederation(nonStandardErpFederation, activations); // this should get non-standard fed activations = ActivationConfigsForTest.hop400().forBlock(0); - nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); testGetOldFederation(nonStandardErpFederation, activations); } @@ -687,8 +682,7 @@ void getOldFederation_RSKIP_353_active_p2sh_erp_fed() { List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); testGetOldFederation(p2shErpFederation, activations); @@ -809,9 +803,7 @@ void saveOldFederation_postMultikey_RSKIP_201_active_non_standard_erp_fed() { List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); testSaveOldFederation(nonStandardErpFederation, NON_STANDARD_ERP_FEDERATION_FORMAT_VERSION, activations); } @@ -823,9 +815,8 @@ void saveOldFederation_postMultikey_RSKIP_353_active_p2sh_erp_fed() { FederationArgs federationArgs = oldFederation.getArgs(); List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); testSaveOldFederation(p2shErpFederation, P2SH_ERP_FEDERATION_FORMAT_VERSION, activationsAllForks); } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index 037f0407337..646f5fce84a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -356,9 +356,9 @@ void init() throws IOException { List erpPubKeys = bridgeMainnetConstants.getErpFedPubKeysList(); long activationDelay = bridgeMainnetConstants.getErpFedActivationDelay(); - ErpFederationArgs retiringFedArgs = - new ErpFederationArgs(retiringFedMembers, creationTime, retiringFedCreationBlockNumber, btcParams, erpPubKeys, activationDelay); - retiringFederation = FederationFactory.buildP2shErpFederation(retiringFedArgs); + FederationArgs retiringFedArgs = + new FederationArgs(retiringFedMembers, creationTime, retiringFedCreationBlockNumber, btcParams); + retiringFederation = FederationFactory.buildP2shErpFederation(retiringFedArgs, erpPubKeys, activationDelay); activeFedSigners = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa07", "fa08", "fa09", "fa10", "fa11"}, true @@ -366,9 +366,9 @@ void init() throws IOException { activeFedSigners.sort(BtcECKey.PUBKEY_COMPARATOR); List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFedSigners); long activeFedCreationBlockNumber = 2L; - ErpFederationArgs activeFedArgs = - new ErpFederationArgs(activeFedMembers, creationTime, activeFedCreationBlockNumber, btcParams, erpPubKeys, activationDelay); - activeFederation = FederationFactory.buildP2shErpFederation(activeFedArgs); + FederationArgs activeFedArgs = + new FederationArgs(activeFedMembers, creationTime, activeFedCreationBlockNumber, btcParams); + activeFederation = FederationFactory.buildP2shErpFederation(activeFedArgs, erpPubKeys, activationDelay); mockFactory = mock(BtcBlockStoreWithCache.Factory.class); 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 294d0bb90a3..b15b588f6e4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportTest.java @@ -6593,16 +6593,9 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ when(preRSKIP271_activations.isActive(ConsensusRule.RSKIP271)).thenReturn(false); when(preRSKIP271_activations.isActive(ConsensusRule.RSKIP385)).thenReturn(false); - ErpFederationArgs p2shFedArgs = new ErpFederationArgs(members, - Instant.now(), - 1L, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); - Federation p2shFed = FederationFactory.buildP2shErpFederation( - p2shFedArgs - ); + FederationArgs p2shFedArgs = new FederationArgs(members, Instant.now(), 1L, bridgeConstants.getBtcParams()); + Federation p2shFed = + FederationFactory.buildP2shErpFederation(p2shFedArgs, bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay()); Stream preRskip271 = Stream.of( // active fed is standard and pegoutRequestsCount is equal to zero @@ -6662,16 +6655,13 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ when(preRSKIP385_activations.isActive(ConsensusRule.RSKIP271)).thenReturn(true); when(preRSKIP385_activations.isActive(ConsensusRule.RSKIP385)).thenReturn(false); - ErpFederationArgs p2shFedArgs = new ErpFederationArgs(members, + FederationArgs p2shFedArgs = new FederationArgs(members, Instant.now(), 1L, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); - Federation p2shFed = FederationFactory.buildP2shErpFederation( - p2shFedArgs + bridgeConstants.getBtcParams() ); + Federation p2shFed = + FederationFactory.buildP2shErpFederation(p2shFedArgs, bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay()); Stream preRskip385 = Stream.of( // active fed is standard and pegoutRequestsCount is equal to zero @@ -6730,16 +6720,13 @@ private static Stream getEstimatedFeesForNextPegOutEventArgsProvider_ PegTestUtils.createRandomBtcECKeys(7) ); - ErpFederationArgs p2shFedArgs = new ErpFederationArgs(members, + FederationArgs p2shFedArgs = new FederationArgs(members, Instant.now(), 1L, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); - ErpFederation p2shFed = FederationFactory.buildP2shErpFederation( - p2shFedArgs + bridgeConstants.getBtcParams() ); + ErpFederation p2shFed = + FederationFactory.buildP2shErpFederation(p2shFedArgs, bridgeConstants.getErpFedPubKeysList(), bridgeConstants.getErpFedActivationDelay()); Stream postRskip385 = Stream.of( // active fed is standard and pegoutRequestsCount is equal to zero diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java index 0df8d511596..95adee50229 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeUtilsTest.java @@ -1071,18 +1071,14 @@ void testCalculatePegoutTxSize_50Inputs_200Outputs_nonStandardErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( + FederationArgs federationArgs = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, - networkParameters, - erpFederationPublicKeys, - 500L - ); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation( - erpFederationArgs, - activations + networkParameters ); + ErpFederation nonStandardErpFederation = + FederationFactory.buildNonStandardErpFederation(federationArgs, erpFederationPublicKeys, 500L, activations); // Create a pegout tx with 50 inputs and 200 outputs int inputSize = 50; @@ -1118,18 +1114,14 @@ void testCalculatePegoutTxSize_100Inputs_50Outputs_nonStandardErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( + FederationArgs federationArgs = new FederationArgs( FederationTestUtils.getFederationMembersWithBtcKeys(defaultFederationKeys), Instant.ofEpochMilli(1000L), 0L, - networkParameters, - erpFederationPublicKeys, - 500L - ); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation( - erpFederationArgs, - activations + networkParameters ); + ErpFederation nonStandardErpFederation = + FederationFactory.buildNonStandardErpFederation(federationArgs, erpFederationPublicKeys, 500L, activations); // Create a pegout tx with 100 inputs and 50 outputs int inputSize = 100; @@ -1478,11 +1470,7 @@ private ErpFederation createNonStandardErpFederation() { List erpPubKeys = bridgeConstantsRegtest.getErpFedPubKeysList(); long activationDelay = bridgeConstantsRegtest.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(genesisFederationArgs, erpPubKeys, activationDelay); - return FederationFactory.buildNonStandardErpFederation( - erpFederationArgs, - activations - ); + return FederationFactory.buildNonStandardErpFederation(genesisFederationArgs, erpPubKeys, activationDelay, activations); } private BtcTransaction createPegOutTx( diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java index fef3014ca3f..ff4019506fc 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWalletWithStorageTest.java @@ -50,9 +50,8 @@ void setup() { federationList = Collections.singletonList(federation); long activationDelay = 5063; - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFedKeys, activationDelay); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); - nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpFedKeys, activationDelay, activations); nonStandardErpFederationList = Collections.singletonList(nonStandardErpFederation); } diff --git a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java index b4a23ab81fc..c6304b026f0 100644 --- a/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/FlyoverCompatibleBtcWallextWithSingleScriptTest.java @@ -55,8 +55,7 @@ void setup() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFedKeys, 5063); - nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpFedKeys, 5063, activations); nonStandardErpFederationList = Collections.singletonList(nonStandardErpFederation); } diff --git a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java index deca10614d6..8f44a68744b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegTestUtils.java @@ -315,9 +315,8 @@ public static ErpFederation createP2shErpFederation(BridgeConstants bridgeConsta List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = new - ErpFederationArgs(fedMembers, creationTime, 0L, btcParams, erpPubKeys, activationDelay); - return FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, btcParams); + return FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); } public static BtcTransaction createBtcTransactionWithOutputToAddress(NetworkParameters networkParameters, Coin amount, Address btcAddress) { diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java index 45dcf06fe93..eefb4d10e28 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyGetTransactionTypeTest.java @@ -68,12 +68,11 @@ void test_sentFromP2SHErpFed() { Federation genesisFederation = bridgeMainnetConstants.getGenesisFederation(); List erpPubKeys = bridgeMainnetConstants.getErpFedPubKeysList(); long activationDelay = bridgeMainnetConstants.getErpFedActivationDelay(); - - ErpFederationArgs activeErpFedArgs = - new ErpFederationArgs(federationMembers, genesisFederation.getCreationTime(), 5L, btcMainnetParams, erpPubKeys, activationDelay); + FederationArgs activeFedArgs = + new FederationArgs(federationMembers, genesisFederation.getCreationTime(), 5L, btcMainnetParams); // Arrange - ErpFederation activeFederation = FederationFactory.buildP2shErpFederation(activeErpFedArgs); + ErpFederation activeFederation = FederationFactory.buildP2shErpFederation(activeFedArgs, erpPubKeys, activationDelay); List fedKeys = BitcoinTestUtils.getBtcEcKeysFromSeeds( new String[]{"fa01", "fa02", "fa03"}, true @@ -81,10 +80,10 @@ void test_sentFromP2SHErpFed() { List retiringFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(fedKeys); Instant creationTime = Instant.ofEpochMilli(1000L); - ErpFederationArgs retiringErpFedArgs = - new ErpFederationArgs(retiringFedMembers, creationTime, 0L, btcMainnetParams, erpPubKeys, activationDelay); + FederationArgs retiringFedArgs = + new FederationArgs(retiringFedMembers, creationTime, 0L, btcMainnetParams); ErpFederation p2shRetiringFederation = FederationFactory.buildP2shErpFederation( - retiringErpFedArgs + retiringFedArgs, erpPubKeys, activationDelay ); // Create a migrationTx from the p2sh erp fed @@ -342,9 +341,9 @@ void test_pegin( List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFedKeys); Instant creationTime = Instant.ofEpochMilli(1000L); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(activeFedMembers, creationTime, 0L, btcMainnetParams, erpFedKeys, 100L); - ErpFederation activeFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = + new FederationArgs(activeFedMembers, creationTime, 0L, btcMainnetParams); + ErpFederation activeFederation = FederationFactory.buildP2shErpFederation(federationArgs, erpFedKeys, 100L); BtcTransaction peginTx = new BtcTransaction(btcMainnetParams); peginTx.addInput(BitcoinTestUtils.createHash(1), 0, new Script(new byte[]{})); diff --git a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java index be2c45b3d29..18f06e2bf24 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsLegacyTest.java @@ -539,8 +539,7 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpFederation_beforeRskip201_isP erpPubKeys.sort(BtcECKey.PUBKEY_COMPARATOR); long activationDelay = 500L; - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); Script redeemScript = nonStandardErpFederation.getRedeemScript(); Script flyoverErpRedeemScript = FastBridgeErpRedeemScriptParser.createFastBridgeErpRedeemScript( @@ -803,8 +802,9 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_beforeRskip BtcECKey.fromPrivate(Hex.decode("fa04")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + long activationDelay = 500L; + + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(retiredFederationArgs, erpFederationPublicKeys, activationDelay, activations); // Create a tx from the retired fast bridge fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -856,9 +856,9 @@ void testIsValidPegInTx_hasChangeUtxoFromFlyoverErpRetiredFederation_afterRskip2 BtcECKey.fromPrivate(Hex.decode("fa04")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); + long activationDelay = 500L; - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(retiredFederationArgs, erpFederationPublicKeys, activationDelay, activations); // Create a tx from the retired fast bridge fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -909,9 +909,9 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_beforeRskip201_isP BtcECKey.fromPrivate(Hex.decode("fa04")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); + long activationDelay = 500L; - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(retiredFederationArgs, erpFederationPublicKeys, 500L); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(retiredFederationArgs, erpFederationPublicKeys, activationDelay, activations); // Create a tx from the retired erp fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -958,8 +958,9 @@ void testIsValidPegInTx_hasChangeUtxoFromErpRetiredFederation_afterRskip201_notP BtcECKey.fromPrivate(Hex.decode("fa04")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpFedArgs = ErpFederationArgs.fromFederationArgs(retiredFedArgs, erpFederationPublicKeys, 500L); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpFedArgs, activations); + long activationDelay = 500L; + + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(retiredFedArgs, erpFederationPublicKeys, activationDelay, activations); // Create a tx from the retired erp fed to the active fed BtcTransaction tx = new BtcTransaction(networkParameters); @@ -1201,8 +1202,7 @@ private void testIsValidPegInTx_fromP2shErpScriptSender( List emergencyKeys = PegTestUtils.createRandomBtcECKeys(3); long activationDelay = 256L; - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(activeFederationArgs, emergencyKeys, activationDelay); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(activeFederationArgs, emergencyKeys, activationDelay); Script flyoverP2shErpRedeemScript = FastBridgeP2shErpRedeemScriptParser.createFastBridgeP2shErpRedeemScript( p2shErpFederation.getRedeemScript(), @@ -1260,34 +1260,22 @@ void testIsMigrationTx_sending_funds_from_retired_p2sh_fed_to_active_p2sh_fed() BtcECKey.fromPrivate(Hex.decode("fc01")), BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - - ErpFederationArgs retiredFedArgs = new ErpFederationArgs( - FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys), - creationTime, - 1L, - bridgeConstantsMainnet.getBtcParams(), - bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay() - ); - ErpFederation retiredFederation = FederationFactory.buildP2shErpFederation( - retiredFedArgs - ); + List retiredFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiredFederationKeys); + NetworkParameters btcParams = bridgeConstantsMainnet.getBtcParams(); + FederationArgs retiredFedArgs = new FederationArgs(retiredFedMembers, creationTime, 1L, btcParams); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); + List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); + FederationArgs activeFedArgs = new FederationArgs(activeFedMembers, creationTime, 1L, btcParams); - ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - creationTime, - 1L, - bridgeConstantsMainnet.getBtcParams(), - bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay() - ); - Federation activeFederation = FederationFactory.buildP2shErpFederation( - activeFedArgs - ); + List erpPubKeys = bridgeConstantsMainnet.getErpFedPubKeysList(); + long activationDelay = bridgeConstantsMainnet.getErpFedActivationDelay(); + + ErpFederation retiredFederation = FederationFactory.buildP2shErpFederation(retiredFedArgs, erpPubKeys, activationDelay); + Federation activeFederation = FederationFactory.buildP2shErpFederation(activeFedArgs, erpPubKeys, activationDelay); Address activeFederationAddress = activeFederation.getAddress(); @@ -1341,20 +1329,18 @@ void testIsMigrationTx_sending_funds_from_retiring_p2sh_fed_to_active_p2sh_fed() List erpPubKeys = bridgeConstantsMainnet.getErpFedPubKeysList(); long activationDelay = bridgeConstantsMainnet.getErpFedActivationDelay(); - ErpFederationArgs retiringFedArgs = - new ErpFederationArgs(retiringFedMembers, creationTime, 1L, btcParams, erpPubKeys, activationDelay); - Federation retiringFederation = FederationFactory.buildP2shErpFederation(retiringFedArgs); + FederationArgs retiringFedArgs = new FederationArgs(retiringFedMembers, creationTime, 1L, btcParams); + Federation retiringFederation = FederationFactory.buildP2shErpFederation(retiringFedArgs, erpPubKeys, activationDelay); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); - ErpFederationArgs activeFedArgs = - new ErpFederationArgs(activeFedMembers, creationTime, 1L, btcParams, erpPubKeys, activationDelay); - Federation activeFederation = FederationFactory.buildP2shErpFederation( - activeFedArgs - ); + FederationArgs activeFedArgs = + new FederationArgs(activeFedMembers, creationTime, 1L, btcParams); + + Federation activeFederation = FederationFactory.buildP2shErpFederation(activeFedArgs, erpPubKeys, activationDelay); Address activeFederationAddress = activeFederation.getAddress(); @@ -1407,16 +1393,13 @@ void testIsMigrationTx_sending_funds_from_retired_standard_fed_to_active_p2sh_fe BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); - ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), + FederationArgs activeFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), creationTime, 1L, - bridgeConstantsMainnet.getBtcParams(), - bridgeConstantsMainnet.getErpFedPubKeysList(), - bridgeConstantsMainnet.getErpFedActivationDelay() - ); - Federation activeFederation = FederationFactory.buildP2shErpFederation( - activeFedArgs + bridgeConstantsMainnet.getBtcParams() ); + Federation activeFederation = + FederationFactory.buildP2shErpFederation(activeFedArgs, bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay()); Address activeFederationAddress = activeFederation.getAddress(); @@ -1464,31 +1447,23 @@ void testIsMigrationTx_sending_funds_from_retiring_standard_fed_to_active_p2sh_f BtcECKey.fromPrivate(Hex.decode("fc01")), BtcECKey.fromPrivate(Hex.decode("fc02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); + List retiringFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys); - FederationArgs retiringFedArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(retiringFederationKeys), - creationTime, - 1L, - bridgeConstantsMainnet.getBtcParams() - ); - Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation( - retiringFedArgs - ); + FederationArgs retiringFedArgs = new FederationArgs(retiringFedMembers, creationTime, 1L, networkParameters); + Federation retiringFederation = FederationFactory.buildStandardMultiSigFederation(retiringFedArgs); List activeFederationKeys = Stream.of( BtcECKey.fromPrivate(Hex.decode("fa01")), BtcECKey.fromPrivate(Hex.decode("fa02")) ).sorted(BtcECKey.PUBKEY_COMPARATOR).collect(Collectors.toList()); + List activeFedMembers = FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys); - ErpFederationArgs activeFedArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(activeFederationKeys), - creationTime, - 1L, - bridgeConstantsMainnet.getBtcParams(), + FederationArgs activeFedArgs = new FederationArgs(activeFedMembers, creationTime, 1L, networkParameters); + Federation activeFederation = FederationFactory.buildP2shErpFederation( + activeFedArgs, bridgeConstantsMainnet.getErpFedPubKeysList(), bridgeConstantsMainnet.getErpFedActivationDelay() ); - Federation activeFederation = FederationFactory.buildP2shErpFederation( - activeFedArgs - ); Address activeFederationAddress = activeFederation.getAddress(); @@ -1932,8 +1907,7 @@ void testIsPegOutTx_fromErpFederation() { BtcECKey.fromPrivate(Hex.decode("fa05")) ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFederationPublicKeys, 500L); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpFederationPublicKeys, 500L, activations); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); @@ -1999,8 +1973,7 @@ void testIsPegOutTx_fromFlyoverErpFederation() { ); erpFederationPublicKeys.sort(BtcECKey.PUBKEY_COMPARATOR); - ErpFederationArgs erpArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpFederationPublicKeys, 500L); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(erpArgs, activations); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpFederationPublicKeys, 500L, activations); Federation standardFederation = bridgeConstantsRegtest.getGenesisFederation(); 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 88bb865a0e2..1b41abee10b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PegUtilsTest.java @@ -208,9 +208,9 @@ void test_getTransactionType_pegin_output_to_retiring_fed_and_other_addresses() Instant creationTime = Instant.ofEpochMilli(1000L); List erpPubKeys = bridgeMainnetConstants.getErpFedPubKeysList(); long activationDelay = bridgeMainnetConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(fedMembers, creationTime, 0L, btcMainnetParams, erpPubKeys, activationDelay); - ErpFederation activeFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, btcMainnetParams); + + ErpFederation activeFed = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); BtcTransaction btcTransaction = new BtcTransaction(btcMainnetParams); @@ -610,9 +610,9 @@ void test_getTransactionType_flyover_segwit() { List erpPubKeys = bridgeTestNetConstants.getErpFedPubKeysList(); long activationDelay = bridgeTestNetConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(fedMembers, creationTime, 0L, btcTestNetParams, erpPubKeys, activationDelay); - ErpFederation activeFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = + new FederationArgs(fedMembers, creationTime, 0L, btcTestNetParams); + ErpFederation activeFed = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); Wallet liveFederationWallet = new BridgeBtcWallet(context, Arrays.asList(retiringFed, activeFed)); String segwitTxHex = "020000000001011f668117f2ca3314806ade1d99ae400f5413d7e9d4bfcbd11d52645e060e22fb0100000000fdffffff0300000000000000001b6a1952534b5401a27c6f697954357247e78f9900023cfe01a9d49c0412030000000000160014b413f59a7ee6e34321140e83ea661e0484a79bc2988708000000000017a9145e6cf80958803e9b3c81cd90422152520d2a505c870247304402203fce49b39f79581d93720f462b5f33f9174e66dc6efb635d4f41aacb33b08d0302201221aec5db31e269454fcc7a4df2936ccedd566ccf48828d4f97050954f196540121021831c5ba44b739521d635e521560525672087e4d5db053801f4aeb60e782f6d6d0f02400"; diff --git a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java index 3a1e0026534..ac85c504401 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PocSighashTest.java @@ -66,11 +66,8 @@ void test_each_input_sighash_is_unique(NetworkParameters networkParameters) { Instant creationTime = Instant.now(); List erpFedPubKeys = erpFedSigners.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(fedMembers, creationTime, 0L, networkParameters, erpFedPubKeys, erpFedActivationDelay); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - erpFederationArgs - ); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, networkParameters); + ErpFederation fed = FederationFactory.buildP2shErpFederation(federationArgs, erpFedPubKeys, erpFedActivationDelay); List utxos = new ArrayList<>(); for (int i = 0; i < 7; i++) { @@ -139,9 +136,8 @@ void test_sighash_is_different_when_tx_is_altered(NetworkParameters networkParam when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(fedMembers, creationTime, 0L, networkParameters, erpPubKeys, erpFedActivationDelay); - ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, networkParameters); + ErpFederation p2shErpFederation = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, erpFedActivationDelay); List utxos = new ArrayList<>(); BtcTransaction peginTx = new BtcTransaction(networkParameters); @@ -233,9 +229,8 @@ void test_sighash_is_equal_for_signed_input_and_unsigned_input(NetworkParameters when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(fedMembers, creationTime, 0L, networkParameters, erpPubKeys, erpFedActivationDelay); - ErpFederation fed = FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, networkParameters); + ErpFederation fed = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, erpFedActivationDelay); List utxos = new ArrayList<>(); for (int i = 0; i < 7; i++) { @@ -282,23 +277,17 @@ void test_each_input_sighash_is_unique_using_real_tx_testnet() { NetworkParameters networkParameters = BridgeTestNetConstants.getInstance().getBtcParams(); int erpFedActivationDelay = 720; - List fedMembers = FedSigner.listOf("federator1", "federator2", "federator6"); - List erpFedMembers = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); + List fedSigners = FedSigner.listOf("federator1", "federator2", "federator6"); + List fedMembers = fedSigners.stream().map(FedSigner::getFed).collect(Collectors.toList()); + List erpFedSigners = FedSigner.listOf("erp-fed-01", "erp-fed-02", "erp-fed-03"); + List erpPubKeys = erpFedSigners.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers.stream().map(FedSigner::getFed).collect(Collectors.toList()), - Instant.now(), - 0L, - networkParameters, - erpFedMembers.stream().map(FedSigner::getFed).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()), - erpFedActivationDelay - ); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - erpFederationArgs - ); + FederationArgs federationArgs = new FederationArgs(fedMembers, Instant.now(), 0L, networkParameters); + ErpFederation fed = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, erpFedActivationDelay); Address expectedAddress = Address.fromBase58( networkParameters, @@ -328,7 +317,7 @@ void test_each_input_sighash_is_unique_using_real_tx_testnet() { networkParameters, erpFedActivationDelay, fed, - fedMembers, + fedSigners, false, utxos, Coin.valueOf(1_107_748L), @@ -379,11 +368,8 @@ void test_each_input_sighash_is_unique_for_a_signed_erp_tx_testnet() { when(activations.isActive(ConsensusRule.RSKIP284)).thenReturn(true); when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(true); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(fedMembers, creationTime, 0L, networkParameters, erpPubKeys, erpFedActivationDelay); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - erpFederationArgs - ); + FederationArgs federationArgs = new FederationArgs(fedMembers, creationTime, 0L, networkParameters); + ErpFederation fed = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, erpFedActivationDelay); Address expectedAddress = Address.fromBase58( networkParameters, @@ -466,16 +452,8 @@ void test_redeemScript_can_be_obtained_from_input() { FedSigner::getFed ).map(FederationMember::getBtcPublicKey).collect(Collectors.toList()); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(fedMembers, - Instant.now(), - 0L, - networkParameters, - erpPubKeys, - erpFedActivationDelay - ); - ErpFederation fed = FederationFactory.buildP2shErpFederation( - erpFederationArgs - ); + FederationArgs federationArgs = new FederationArgs(fedMembers, Instant.now(), 0L, networkParameters); + ErpFederation fed = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, erpFedActivationDelay); Address expectedAddress = Address.fromBase58( networkParameters, diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index b2d6e09dacf..c91d6c0d746 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -135,14 +135,14 @@ private void testChangePowpeg( Federation originalPowpeg; Instant creationTime = Instant.now(); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(originalPowpegMembers, creationTime, 0, btcParams, erpPubKeys, activationDelay); + FederationArgs federationArgs = + new FederationArgs(originalPowpegMembers, creationTime, 0, btcParams); switch (oldPowPegFederationType) { case nonStandardErp: - originalPowpeg = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + originalPowpeg = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); break; case p2shErp: - originalPowpeg = FederationFactory.buildP2shErpFederation(erpFederationArgs); + originalPowpeg = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); // TODO: CHECK REDEEMSCRIPT break; default: diff --git a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java index d10f517357d..600531d0da4 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java @@ -180,19 +180,11 @@ void build_pegout_tx_from_non_standard_erp_federation() { new BtcECKey() ) ); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs( - members, - Instant.now(), - 0, - bridgeConstants.getBtcParams(), - bridgeConstants.getErpFedPubKeysList(), - bridgeConstants.getErpFedActivationDelay() - ); + FederationArgs federationArgs = new FederationArgs(members, Instant.now(), 0, bridgeConstants.getBtcParams()); - ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation( - erpFederationArgs, - activations - ); + ErpFederation nonStandardErpFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, + bridgeConstants.getErpFedPubKeysList(), + bridgeConstants.getErpFedActivationDelay(), activations); List utxos = Arrays.asList( new UTXO( diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java index 4d4a3eaef98..c893c158d45 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationFactoryTest.java @@ -177,15 +177,15 @@ private Federation createStandardMultisigFederation() { } private ErpFederation createNonStandardErpFederation() { - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue); - return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + FederationArgs federationArgs = + new FederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters); + return FederationFactory.buildNonStandardErpFederation(federationArgs, emergencyKeys, activationDelayValue, activations); } private ErpFederation createP2shErpFederation() { - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue); - return FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = + new FederationArgs(federationMembers, creationTime, creationBlockNumber, networkParameters); + return FederationFactory.buildP2shErpFederation(federationArgs, emergencyKeys, activationDelayValue); } } diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java index a67452d2d13..f97d4b8c103 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/NonStandardErpFederationsTest.java @@ -95,9 +95,8 @@ private ErpFederation createDefaultNonStandardErpFederation() { Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(standardMembers, creationTime, creationBlockNumber, networkParameters, - emergencyKeys, activationDelayValue); - return FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + FederationArgs federationArgs = new FederationArgs(standardMembers, creationTime, creationBlockNumber, networkParameters); + return FederationFactory.buildNonStandardErpFederation(federationArgs, emergencyKeys, activationDelayValue, activations); } @Test @@ -251,68 +250,55 @@ void testEquals_basic() { @Test void testEquals_same() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime(), nonStandardErpFederation.getCreationBlockNumber(), - nonStandardErpFederation.getBtcParams(), nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay() - ); - ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + FederationArgs federationArgs = + new FederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime(), + nonStandardErpFederation.getCreationBlockNumber(), nonStandardErpFederation.getBtcParams()); + ErpFederation otherFederation = + FederationFactory.buildNonStandardErpFederation(federationArgs, nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay(), activations); + assertEquals(nonStandardErpFederation, otherFederation); } @Test - void values_from_erpFederationArgs_equal_values_from_nonStandardErpFederation() { - ErpFederationArgs erpFederationArgs = nonStandardErpFederation.getErpArgs(); - List federationMembersFromErpArgs = erpFederationArgs.getMembers(); - Instant creationTimeFromErpArgs = erpFederationArgs.getCreationTime(); - long creationBlockNumberFromErpArgs = erpFederationArgs.getCreationBlockNumber(); - NetworkParameters btcParamsFromErpArgs = erpFederationArgs.getBtcParams(); - List emergencyKeysFromErpArgs = erpFederationArgs.getErpPubKeys(); - long activationDelayFromErpArgs = erpFederationArgs.getActivationDelay(); - - List members = nonStandardErpFederation.getMembers(); + void federationArgs_from_values_equals_federationArgs_from_nonStandardErpFederation() { + List federationMembers = nonStandardErpFederation.getMembers(); Instant creationTime = nonStandardErpFederation.getCreationTime(); long creationBlockNumber = nonStandardErpFederation.getCreationBlockNumber(); + NetworkParameters btcParams = nonStandardErpFederation.getBtcParams(); - assertEquals(members, federationMembersFromErpArgs); - assertEquals(creationTime, creationTimeFromErpArgs); - assertEquals(creationBlockNumber, creationBlockNumberFromErpArgs); - assertEquals(networkParameters, btcParamsFromErpArgs); - assertEquals(emergencyKeys, emergencyKeysFromErpArgs); - assertEquals(activationDelayValue, activationDelayFromErpArgs); + FederationArgs federationArgsFromValues = new FederationArgs(federationMembers, creationTime, creationBlockNumber, btcParams); + FederationArgs federationArgs = nonStandardErpFederation.getArgs(); + + assertEquals(federationArgs, federationArgsFromValues); } @Test void nonStandardErpFederation_from_federationArgs_and_erp_values_equals_nonStandardErpFederation() { FederationArgs federationArgs = nonStandardErpFederation.getArgs(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, emergencyKeys, activationDelayValue); - ErpFederation nonStandardErpFederationFromFederationArgs = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation nonStandardErpFederationFromFederationArgs = + FederationFactory.buildNonStandardErpFederation(federationArgs, emergencyKeys, activationDelayValue, activations); assertEquals(nonStandardErpFederation, nonStandardErpFederationFromFederationArgs); } - @Test - void nonStandardErpFederation_from_erpFederationArgs_equals_nonStandardErpFederation() { - ErpFederationArgs erpFederationArgs = nonStandardErpFederation.getErpArgs(); - ErpFederation federationFromFederationArgs = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - - assertEquals(nonStandardErpFederation, federationFromFederationArgs); - } - @Test void testEquals_differentCreationTime() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime().plus(1, ChronoUnit.MILLIS), - nonStandardErpFederation.getCreationBlockNumber(), nonStandardErpFederation.getBtcParams(), nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay() + FederationArgs federationArgs = new FederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime().plus(1, ChronoUnit.MILLIS), + nonStandardErpFederation.getCreationBlockNumber(), nonStandardErpFederation.getBtcParams() ); - ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + ErpFederation otherFederation = + FederationFactory.buildNonStandardErpFederation(federationArgs, nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay(), activations); assertEquals(nonStandardErpFederation, otherFederation); } @Test void testEquals_differentCreationBlockNumber() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(nonStandardErpFederation.getMembers(), nonStandardErpFederation.getCreationTime(), nonStandardErpFederation.getCreationBlockNumber() + 1, - nonStandardErpFederation.getBtcParams(), nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay() - ); - ErpFederation otherFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); + FederationArgs federationArgs = new FederationArgs(nonStandardErpFederation.getMembers(), + nonStandardErpFederation.getCreationTime(), nonStandardErpFederation.getCreationBlockNumber() + 1, + nonStandardErpFederation.getBtcParams()); + ErpFederation otherFederation = + FederationFactory.buildNonStandardErpFederation(federationArgs, nonStandardErpFederation.getErpPubKeys(), nonStandardErpFederation.getActivationDelay(), activations); assertEquals(nonStandardErpFederation, otherFederation); } @@ -731,10 +717,9 @@ void createNonStandardErpFedWithSameRedeemScriptAsHardcodedOne_after_RSKIP293_fa List federationMembersWithBtcKeys = FederationTestUtils.getFederationMembersWithBtcKeys(standardMultisigKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federationMembersWithBtcKeys, creationTime, 1, btcParams, - emergencyMultisigKeys, activationDelay); + FederationArgs federationArgs = new FederationArgs(federationMembersWithBtcKeys, creationTime, 1, btcParams); - assertThrows(ErpFederationCreationException.class, () -> FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations)); + assertThrows(ErpFederationCreationException.class, () -> FederationFactory.buildNonStandardErpFederation(federationArgs, emergencyMultisigKeys, activationDelay, activations)); } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java index ee5f4ec77bc..65c7bdd9185 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java @@ -81,10 +81,10 @@ private ErpFederation createDefaultP2shErpFederation() { List standardMembers = FederationTestUtils.getFederationMembersWithBtcKeys(defaultKeys); Instant creationTime = ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(); long creationBlockNumber = 0L; - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(standardMembers, creationTime, creationBlockNumber, networkParameters, emergencyKeys, activationDelayValue); + FederationArgs federationArgs = + new FederationArgs(standardMembers, creationTime, creationBlockNumber, networkParameters); - return FederationFactory.buildP2shErpFederation(erpFederationArgs); + return FederationFactory.buildP2shErpFederation(federationArgs, emergencyKeys, activationDelayValue); } private void createAndValidateFederation() { @@ -222,49 +222,33 @@ void testEquals_basic() { @Test void testEquals_same() { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(federation.getMembers(), federation.getCreationTime(), - federation.getCreationBlockNumber(), federation.getBtcParams(), federation.getErpPubKeys(), federation.getActivationDelay()); - ErpFederation otherFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = new FederationArgs(federation.getMembers(), federation.getCreationTime(), + federation.getCreationBlockNumber(), federation.getBtcParams()); + ErpFederation otherFederation = + FederationFactory.buildP2shErpFederation(federationArgs, federation.getErpPubKeys(), federation.getActivationDelay()); assertEquals(federation, otherFederation); } @Test - void values_from_erpFederationArgs_equal_values_from_p2shErpFederation() { - ErpFederationArgs erpFederationArgs = federation.getErpArgs(); - List federationMembersFromErpArgs = erpFederationArgs.getMembers(); - Instant creationTimeFromErpArgs = erpFederationArgs.getCreationTime(); - long creationBlockNumberFromErpArgs = erpFederationArgs.getCreationBlockNumber(); - NetworkParameters btcParamsFromErpArgs = erpFederationArgs.getBtcParams(); - List emergencyKeysFromErpArgs = erpFederationArgs.getErpPubKeys(); - long activationDelayFromErpArgs = erpFederationArgs.getActivationDelay(); - - List members = federation.getMembers(); + void federationArgs_from_values_equals_federationArgs_from_p2shErpFederation() { + List federationMembers = federation.getMembers(); Instant creationTime = federation.getCreationTime(); long creationBlockNumber = federation.getCreationBlockNumber(); + NetworkParameters btcParams = federation.getBtcParams(); - assertEquals(members, federationMembersFromErpArgs); - assertEquals(creationTime, creationTimeFromErpArgs); - assertEquals(creationBlockNumber, creationBlockNumberFromErpArgs); - assertEquals(networkParameters, btcParamsFromErpArgs); - assertEquals(emergencyKeys, emergencyKeysFromErpArgs); - assertEquals(activationDelayValue, activationDelayFromErpArgs); - } - - @Test - void p2shErpFederation_from_federationArgs_and_erp_values_equals_p2shErpFederation() { + FederationArgs federationArgsFromValues = + new FederationArgs(federationMembers, creationTime, creationBlockNumber, btcParams); FederationArgs federationArgs = federation.getArgs(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, emergencyKeys, activationDelayValue); - ErpFederation federationFromFederationArgs = FederationFactory.buildP2shErpFederation(erpFederationArgs); - - assertEquals(federation, federationFromFederationArgs); + assertEquals(federationArgs, federationArgsFromValues); } @Test - void p2shErpFederation_from_erpFederationArgs_equals_p2shErpFederation() { - ErpFederationArgs erpFederationArgs = federation.getErpArgs(); - ErpFederation federationFromFederationArgs = FederationFactory.buildP2shErpFederation(erpFederationArgs); + void p2shErpFederation_from_federationArgs_and_erp_values_equals_p2shErpFederation() { + FederationArgs federationArgs = federation.getArgs(); + ErpFederation federationFromFederationArgs = + FederationFactory.buildP2shErpFederation(federationArgs, emergencyKeys, activationDelayValue); assertEquals(federation, federationFromFederationArgs); } @@ -380,8 +364,7 @@ void getStandardRedeemScript() { StandardMultisigFederation standardMultisigFed = FederationFactory.buildStandardMultiSigFederation(federationArgs); List erpPubKeys = Arrays.asList(new BtcECKey(), new BtcECKey()); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, 10_000); - ErpFederation p2shFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); + ErpFederation p2shFed = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, 10_000); assertEquals(standardMultisigFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); Assertions.assertNotEquals(p2shFed.getRedeemScript(), p2shFed.getDefaultRedeemScript()); @@ -485,12 +468,11 @@ void getErpRedeemScript_compareOtherImplementation_P2SHERPFederation() throws IO for (RawGeneratedRedeemScript generatedScript : generatedScripts) { // Skip test cases with invalid redeem script that exceed the maximum size if (generatedScript.script.getProgram().length <= MAX_SCRIPT_ELEMENT_SIZE) { - ErpFederationArgs erpFederationArgs = new ErpFederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(generatedScript.mainFed), + FederationArgs federationArgs = new FederationArgs(FederationTestUtils.getFederationMembersWithBtcKeys(generatedScript.mainFed), ZonedDateTime.parse("2017-06-10T02:30:00Z").toInstant(), 1, - NetworkParameters.fromID(NetworkParameters.ID_TESTNET), - generatedScript.emergencyFed, - generatedScript.timelock); - Federation erpFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); + NetworkParameters.fromID(NetworkParameters.ID_TESTNET)); + Federation erpFederation = + FederationFactory.buildP2shErpFederation(federationArgs, generatedScript.emergencyFed, generatedScript.timelock); Script rskjScript = erpFederation.getRedeemScript(); Script alternativeScript = generatedScript.script; @@ -518,9 +500,9 @@ void spendFromP2shErpFed( true ); - ErpFederationArgs erpFederationArgs = - new ErpFederationArgs(federationMembers, creationTime, 0L, networkParameters, emergencyKeys, activationDelay); - ErpFederation p2shErpFed = FederationFactory.buildP2shErpFederation(erpFederationArgs); + FederationArgs federationArgs = + new FederationArgs(federationMembers, creationTime, 0L, networkParameters); + ErpFederation p2shErpFed = FederationFactory.buildP2shErpFederation(federationArgs, emergencyKeys, activationDelay); Coin value = Coin.valueOf(1_000_000); Coin fee = Coin.valueOf(10_000); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java index ada7c3b8d85..49f7756198e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/PendingFederationTest.java @@ -424,15 +424,16 @@ private void testBuildFederation( List erpPubKeys = bridgeConstants.getErpFedPubKeysList(); long activationDelay = bridgeConstants.getErpFedActivationDelay(); - ErpFederationArgs erpFederationArgs = ErpFederationArgs.fromFederationArgs(federationArgs, erpPubKeys, activationDelay); - if (isRskip353Active) { - expectedFederation = FederationFactory.buildP2shErpFederation(erpFederationArgs); - } else if (isRskip201Active) { - expectedFederation = FederationFactory.buildNonStandardErpFederation(erpFederationArgs, activations); - } else { + if (expectedFederationShouldBeStandardMultisig(isRskip201Active)) { expectedFederation = FederationFactory.buildStandardMultiSigFederation(federationArgs); } + else if (expectedFederationShouldBeNonStandardErp(isRskip353Active)) { + expectedFederation = FederationFactory.buildNonStandardErpFederation(federationArgs, erpPubKeys, activationDelay, activations); + } + else { + expectedFederation = FederationFactory.buildP2shErpFederation(federationArgs, erpPubKeys, activationDelay); + } assertEquals(expectedFederation, builtFederation); if (isRskip201Active && !isRskip284Active && networkId.equals(NetworkParameters.ID_TESTNET)) { @@ -440,6 +441,14 @@ private void testBuildFederation( } } + private boolean expectedFederationShouldBeStandardMultisig(boolean isRskip201Active) { + return !isRskip201Active; + } + + private boolean expectedFederationShouldBeNonStandardErp(boolean isRskip353Active) { + return !isRskip353Active; + } + private int randomInRange(int min, int max) { return TestUtils.generateInt(PendingFederationTest.class.toString(),max - min + 1) + min; } diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java index 086a45a4617..244fb990078 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/StandardMultisigFederationTest.java @@ -137,21 +137,14 @@ void testEquals_same() { @Test void values_from_federationArgs_equal_values_from_federation() { - FederationArgs actualFederationArgs = federation.getArgs(); - List federationMembersFromArgs = actualFederationArgs.getMembers(); - Instant creationTimeFromArgs = actualFederationArgs.getCreationTime(); - long creationBlockNumberFromArgs = actualFederationArgs.getCreationBlockNumber(); - NetworkParameters btcParamsFromArgs = actualFederationArgs.getBtcParams(); - List federationMembers = federation.getMembers(); Instant creationTime = federation.getCreationTime(); long creationBlockNumber = federation.getCreationBlockNumber(); NetworkParameters btcParams = federation.getBtcParams(); + FederationArgs federationArgsFromValues = new FederationArgs(federationMembers, creationTime, creationBlockNumber, btcParams); - assertEquals(federationMembers, federationMembersFromArgs); - assertEquals(creationTime, creationTimeFromArgs); - assertEquals(creationBlockNumber, creationBlockNumberFromArgs); - assertEquals(btcParams, btcParamsFromArgs); + FederationArgs federationArgs = federation.getArgs(); + assertEquals(federationArgs, federationArgsFromValues); } @Test From 376b6276f9884dd714223a6490e777efa72be2b3 Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 12 Jan 2024 17:18:47 -0300 Subject: [PATCH 050/137] Save erpPubKeys as compressed in ErpFederation --- .../src/main/java/co/rsk/peg/federation/ErpFederation.java | 5 +++-- .../main/java/co/rsk/peg/federation/FederationFactory.java | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java index c988f3aa0bc..310de38e915 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/ErpFederation.java @@ -8,6 +8,8 @@ import co.rsk.bitcoinj.script.ScriptChunk; import co.rsk.peg.bitcoin.ErpRedeemScriptBuilder; import co.rsk.peg.bitcoin.RedeemScriptCreationException; +import co.rsk.peg.utils.EcKeyUtils; + import java.util.Collections; import java.util.List; @@ -29,10 +31,9 @@ protected ErpFederation( int formatVersion ) { super(federationArgs, formatVersion); - validateEmergencyKeys(erpPubKeys); - this.erpPubKeys = erpPubKeys; + this.erpPubKeys = EcKeyUtils.getCompressedPubKeysList(erpPubKeys); this.activationDelay = activationDelay; this.erpRedeemScriptBuilder = erpRedeemScriptBuilder; } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java index b08156697fc..28ff1b9f48f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationFactory.java @@ -6,7 +6,6 @@ import co.rsk.peg.bitcoin.NonStandardErpRedeemScriptBuilderFactory; import co.rsk.peg.bitcoin.P2shErpRedeemScriptBuilder; import org.ethereum.config.blockchain.upgrades.ActivationConfig; - import java.util.List; import static co.rsk.peg.federation.FederationFormatVersion.*; From 2cfd231efdbe323397c3f2ed4f56944741ac6c9f Mon Sep 17 00:00:00 2001 From: Volodymyr Kravets Date: Mon, 29 Jan 2024 13:56:50 +0200 Subject: [PATCH 051/137] Used fixed buffer allocator for udp channel --- .../java/co/rsk/net/discovery/UDPServer.java | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/UDPServer.java b/rskj-core/src/main/java/co/rsk/net/discovery/UDPServer.java index f7e1bf18d49..0ad594526fd 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/UDPServer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/UDPServer.java @@ -22,10 +22,9 @@ import co.rsk.util.ExecState; import com.google.common.annotations.VisibleForTesting; import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.EventLoopGroup; +import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannelConfig; import io.netty.channel.socket.nio.NioDatagramChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,6 +42,8 @@ public class UDPServer implements InternalService { private static final Logger logger = LoggerFactory.getLogger(UDPServer.class); + private static final int BUFFER_SIZE = 8_192; + private final int port; private final String address; @@ -163,6 +164,29 @@ private Bootstrap createBootstrap(EventLoopGroup group) { .handler(new ChannelInitializer() { @Override public void initChannel(@Nonnull NioDatagramChannel ch) { + DatagramChannelConfig channelConfig = ch.config(); + channelConfig.setRecvByteBufAllocator(new FixedRecvByteBufAllocator(BUFFER_SIZE)); + + Integer defaultSndBuf = channelConfig.getOption(ChannelOption.SO_SNDBUF); + if (defaultSndBuf == null || defaultSndBuf < BUFFER_SIZE) { + logger.info("Default {} size of {} bytes is not sufficient. Changing to {}", + ChannelOption.SO_SNDBUF, defaultSndBuf, BUFFER_SIZE); + channelConfig.setOption(ChannelOption.SO_SNDBUF, BUFFER_SIZE); + } + + Integer defaultRcvBuf = channelConfig.getOption(ChannelOption.SO_RCVBUF); + if (defaultRcvBuf == null || defaultRcvBuf < BUFFER_SIZE) { + logger.info("Default {} size of {} bytes is not sufficient. Changing to {}", + ChannelOption.SO_RCVBUF, defaultRcvBuf, BUFFER_SIZE); + channelConfig.setOption(ChannelOption.SO_RCVBUF, BUFFER_SIZE); + } + + logger.info("Init channel with {}({}), {}={}, {}={}", + FixedRecvByteBufAllocator.class.getSimpleName(), + BUFFER_SIZE, + ChannelOption.SO_SNDBUF, channelConfig.getOption(ChannelOption.SO_SNDBUF), + ChannelOption.SO_RCVBUF, channelConfig.getOption(ChannelOption.SO_RCVBUF)); + ch.pipeline().addLast(new PacketDecoder()); UDPChannel udpChannel = new UDPChannel(ch, peerExplorer); peerExplorer.setUDPChannel(udpChannel); From d421333d39d1bf945a90d5037f3b5437994c57f5 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Wed, 13 Dec 2023 17:16:46 -0300 Subject: [PATCH 052/137] add retry connection logic --- .../co/rsk/net/discovery/PeerExplorer.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java index f4eafb25278..235cb01d7a6 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java @@ -63,6 +63,8 @@ public class PeerExplorer { private static final int MAX_NODES_TO_CHECK = 16; private static final int RETRIES_COUNT = 3; + private static final int MAX_RETRY_ATTEMPTS = 5; + private int retryCounter = 0; private final Set bootNodes = ConcurrentHashMap.newKeySet(); private final Map pendingPingRequests = new ConcurrentHashMap<>(); @@ -427,12 +429,25 @@ synchronized void update() { return; } - List closestNodes = this.distanceTable.getClosestNodes(this.localNode.getId()); - - logger.trace("update - closestNodes: [{}]", closestNodes); + if (shouldRetryConnection()) { + retryCounter++; + if (retryCounter <= MAX_RETRY_ATTEMPTS) { + logger.info("retrying connection to bootstrap nodes. Attempt: {}", retryCounter); + startConversationWithNewNodes(); + } else { + logger.warn("max retry attempts reached."); + } + } else { + List closestNodes = this.distanceTable.getClosestNodes(this.localNode.getId()); + logger.trace("update - closestNodes: [{}]", closestNodes); + this.askForMoreNodes(closestNodes); + this.checkPeersPulse(closestNodes); + } + } - this.askForMoreNodes(closestNodes); - this.checkPeersPulse(closestNodes); + private boolean shouldRetryConnection() { + return bootNodes.isEmpty() && pendingPingRequests.isEmpty() && + pendingFindNodeRequests.isEmpty() && establishedConnections.isEmpty(); } private void checkPeersPulse(List closestNodes) { From 230300168e5d373464198e25e1453cd1a15dcaca Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Tue, 19 Dec 2023 20:17:11 -0300 Subject: [PATCH 053/137] load initial boot nodes and check for closest nodes --- .../main/java/co/rsk/net/discovery/PeerExplorer.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java index 235cb01d7a6..5d03fc5bd17 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java @@ -64,6 +64,7 @@ public class PeerExplorer { private static final int RETRIES_COUNT = 3; private static final int MAX_RETRY_ATTEMPTS = 5; + private final List initialBootNodes; private int retryCounter = 0; private final Set bootNodes = ConcurrentHashMap.newKeySet(); @@ -106,6 +107,7 @@ public PeerExplorer(List initialBootNodes, this.distanceTable = distanceTable; this.updateEntryLock = new ReentrantLock(); this.networkId = networkId; + this.initialBootNodes = initialBootNodes; loadInitialBootNodes(initialBootNodes); this.cleaner = new PeerExplorerCleaner(updatePeriod, cleanPeriod, this); @@ -429,24 +431,26 @@ synchronized void update() { return; } - if (shouldRetryConnection()) { + List closestNodes = this.distanceTable.getClosestNodes(this.localNode.getId()); + + if (shouldRetryConnection(closestNodes)) { retryCounter++; if (retryCounter <= MAX_RETRY_ATTEMPTS) { logger.info("retrying connection to bootstrap nodes. Attempt: {}", retryCounter); + loadInitialBootNodes(initialBootNodes); startConversationWithNewNodes(); } else { logger.warn("max retry attempts reached."); } } else { - List closestNodes = this.distanceTable.getClosestNodes(this.localNode.getId()); logger.trace("update - closestNodes: [{}]", closestNodes); this.askForMoreNodes(closestNodes); this.checkPeersPulse(closestNodes); } } - private boolean shouldRetryConnection() { - return bootNodes.isEmpty() && pendingPingRequests.isEmpty() && + private boolean shouldRetryConnection(List closestNodes) { + return closestNodes.isEmpty() && bootNodes.isEmpty() && pendingPingRequests.isEmpty() && pendingFindNodeRequests.isEmpty() && establishedConnections.isEmpty(); } From 6cbf4143efb3236cabfa349c31bfeb0b2daa0d3c Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Tue, 19 Dec 2023 21:55:03 -0300 Subject: [PATCH 054/137] load max bootstrap retry limit from config --- rskj-core/src/main/java/co/rsk/RskContext.java | 3 ++- .../src/main/java/co/rsk/config/RskSystemProperties.java | 5 +++++ .../src/main/java/co/rsk/net/discovery/PeerExplorer.java | 9 ++++++--- rskj-core/src/main/resources/expected.conf | 1 + rskj-core/src/main/resources/reference.conf | 1 + .../co/rsk/net/discovery/NodeChallengeManagerTest.java | 2 +- .../test/java/co/rsk/net/discovery/UDPServerTest.java | 6 +++--- 7 files changed, 19 insertions(+), 8 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/RskContext.java b/rskj-core/src/main/java/co/rsk/RskContext.java index a08676ba834..f9ced02420c 100644 --- a/rskj-core/src/main/java/co/rsk/RskContext.java +++ b/rskj-core/src/main/java/co/rsk/RskContext.java @@ -1601,7 +1601,8 @@ protected PeerExplorer getPeerExplorer() { rskSystemProperties.peerDiscoveryCleanPeriod(), rskSystemProperties.networkId(), getPeerScoringManager(), - rskSystemProperties.allowMultipleConnectionsPerHostPort() + rskSystemProperties.allowMultipleConnectionsPerHostPort(), + rskSystemProperties.peerDiscoveryMaxBootRetries() ); } diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index f5b8c55a8e5..2e69655a724 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -47,6 +47,7 @@ public class RskSystemProperties extends SystemProperties { private static final int PD_DEFAULT_CLEAN_PERIOD = 15000; //miliseconds private static final int PD_DEFAULT_TIMEOUT_MESSAGE = PD_DEFAULT_CLEAN_PERIOD - 1; //miliseconds private static final int PD_DEFAULT_REFRESH_PERIOD = 60000; //miliseconds + private static final int PD_DEFAULT_MAX_BOOTSTRAP_RETRIES = -1; private static final String REGTEST_BLOCKCHAIN_CONFIG = "regtest"; @@ -262,6 +263,10 @@ public boolean allowMultipleConnectionsPerHostPort() { return getBoolean("peer.discovery.allowMultipleConnectionsPerHostPort", true); } + public long peerDiscoveryMaxBootRetries() { + return getLong("peer.discovery.maxBootRetries", PD_DEFAULT_MAX_BOOTSTRAP_RETRIES); + } + public int discoveryBucketSize() { return getInt(DISCOVERY_BUCKET_SIZE, KademliaOptions.BUCKET_SIZE); } diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java index 5d03fc5bd17..aea6826df5b 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java @@ -66,6 +66,7 @@ public class PeerExplorer { private static final int MAX_RETRY_ATTEMPTS = 5; private final List initialBootNodes; private int retryCounter = 0; + private final long maxBootRetries; private final Set bootNodes = ConcurrentHashMap.newKeySet(); private final Map pendingPingRequests = new ConcurrentHashMap<>(); @@ -101,7 +102,7 @@ public class PeerExplorer { public PeerExplorer(List initialBootNodes, Node localNode, NodeDistanceTable distanceTable, ECKey key, long reqTimeOut, long updatePeriod, long cleanPeriod, Integer networkId, - PeerScoringManager peerScoringManager, boolean allowMultipleConnectionsPerHostPort) { + PeerScoringManager peerScoringManager, boolean allowMultipleConnectionsPerHostPort, long maxBootRetries) { this.localNode = localNode; this.key = key; this.distanceTable = distanceTable; @@ -118,6 +119,8 @@ public PeerExplorer(List initialBootNodes, this.knownHosts = new ConcurrentHashMap<>(); this.allowMultipleConnectionsPerHostPort = allowMultipleConnectionsPerHostPort; + + this.maxBootRetries = maxBootRetries; } void start() { @@ -434,8 +437,8 @@ synchronized void update() { List closestNodes = this.distanceTable.getClosestNodes(this.localNode.getId()); if (shouldRetryConnection(closestNodes)) { - retryCounter++; - if (retryCounter <= MAX_RETRY_ATTEMPTS) { + if (maxBootRetries == -1 || retryCounter < maxBootRetries) { + retryCounter++; logger.info("retrying connection to bootstrap nodes. Attempt: {}", retryCounter); loadInitialBootNodes(initialBootNodes); startConversationWithNewNodes(); diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index 095f2a3e83c..8b6461c0167 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -135,6 +135,7 @@ peer = { msg.timeout = refresh.period = allowMultipleConnectionsPerHostPort = + maxBootRetries = bucketSize = } port = diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 3f689a5ed4a..827613c0c50 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -143,6 +143,7 @@ peer { discovery = { # allow multiple connections per host by default allowMultipleConnectionsPerHostPort = true + maxBootRetries = -1 } # flag that allows to propagate a received block without executing it and only checking basic validation rules. diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/NodeChallengeManagerTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/NodeChallengeManagerTest.java index ea699f52f20..5137846f6ca 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/NodeChallengeManagerTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/NodeChallengeManagerTest.java @@ -65,7 +65,7 @@ void startChallenge() { Node node3 = new Node(key3.getNodeId(), HOST_3, PORT_3); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node1); - PeerExplorer peerExplorer = new PeerExplorer(new ArrayList<>(), node1, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(new ArrayList<>(), node1, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID, mock(PeerScoringManager.class), true, -1); peerExplorer.setUDPChannel(mock(UDPChannel.class)); NodeChallengeManager manager = new NodeChallengeManager(); diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/UDPServerTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/UDPServerTest.java index 436726da859..57f91b7a4e0 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/UDPServerTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/UDPServerTest.java @@ -101,9 +101,9 @@ void run3NodesFullTest() throws InterruptedException { NodeDistanceTable distanceTable2 = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node2); NodeDistanceTable distanceTable3 = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node3); - PeerExplorer peerExplorer1 = new PeerExplorer(node1BootNode, node1, distanceTable1, key1, TIMEOUT, UPDATE, CLEAN, NETWORK_ID, mock(PeerScoringManager.class), true); - PeerExplorer peerExplorer2 = new PeerExplorer(node2BootNode, node2, distanceTable2, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID, mock(PeerScoringManager.class), true); - PeerExplorer peerExplorer3 = new PeerExplorer(node3BootNode, node3, distanceTable3, key3, TIMEOUT, UPDATE, CLEAN, NETWORK_ID, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer1 = new PeerExplorer(node1BootNode, node1, distanceTable1, key1, TIMEOUT, UPDATE, CLEAN, NETWORK_ID, mock(PeerScoringManager.class), true, -1); + PeerExplorer peerExplorer2 = new PeerExplorer(node2BootNode, node2, distanceTable2, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID, mock(PeerScoringManager.class), true, -1); + PeerExplorer peerExplorer3 = new PeerExplorer(node3BootNode, node3, distanceTable3, key3, TIMEOUT, UPDATE, CLEAN, NETWORK_ID, mock(PeerScoringManager.class), true, -1); assertEquals(0, peerExplorer1.getNodes().size()); assertEquals(0, peerExplorer2.getNodes().size()); From 1a4284313aec6a33be69db3511bbc8cf06de3090 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Thu, 21 Dec 2023 15:21:02 -0300 Subject: [PATCH 055/137] fix unit tests PeerExplorer constructor --- .../rsk/net/discovery/PeerExplorerTest.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java index e70b3cf828f..6fedac1b88a 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java @@ -86,7 +86,7 @@ class PeerExplorerTest { void sendInitialMessageToNodesNoNodes() { Node node = new Node(new ECKey().getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(new ArrayList<>(), node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(new ArrayList<>(), node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); peerExplorer.setUDPChannel(Mockito.mock(UDPChannel.class)); @@ -94,7 +94,7 @@ void sendInitialMessageToNodesNoNodes() { Assertions.assertTrue(nodesWithMessage.isEmpty()); - peerExplorer = new PeerExplorer(new ArrayList<>(), node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + peerExplorer = new PeerExplorer(new ArrayList<>(), node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true,-1); peerExplorer.setUDPChannel(Mockito.mock(UDPChannel.class)); nodesWithMessage = peerExplorer.startConversationWithNewNodes(); @@ -114,7 +114,7 @@ void sendInitialMessageToNodes() { Node node = new Node(new ECKey().getNodeId(), HOST_1, PORT_1); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, new ECKey(), TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); UDPChannel channel = new UDPChannel(Mockito.mock(Channel.class), peerExplorer); peerExplorer.setUDPChannel(channel); @@ -134,7 +134,7 @@ void handlePingMessageFromDifferentNetwork() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -164,7 +164,7 @@ void handlePingMessage() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -225,7 +225,7 @@ void handlePongMessage() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -279,7 +279,7 @@ void handlePongMessageMultipleNodesPerHostKeepLast() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), false); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), false, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -333,7 +333,7 @@ void handlePongMessageMultipleNodesPerHostAllowed() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -391,7 +391,7 @@ void handleFindNodeMessage() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -442,7 +442,7 @@ void handleFindNodeMessageWithExtraNodes() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -497,7 +497,7 @@ void handleNeighbors() throws Exception { NodeDistanceTable distanceTable = new NodeDistanceTable(KademliaOptions.BINS, KademliaOptions.BUCKET_SIZE, node2); PeerScoringManager peerScoringManager = mock(PeerScoringManager.class); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node2, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, peerScoringManager, true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node2, distanceTable, key2, TIMEOUT, UPDATE, CLEAN, NETWORK_ID1, peerScoringManager, true, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -593,7 +593,7 @@ void testCleanPeriod() throws Exception { Node node = new Node(key2.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(1, 1, node); - PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, 199, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(nodes, node, distanceTable, key2, 199, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); Channel internalChannel = Mockito.mock(Channel.class); UDPTestChannel channel = new UDPTestChannel(internalChannel, peerExplorer); @@ -650,7 +650,7 @@ void testStartAndStop() { Node node = new Node(key.getNodeId(), HOST_2, PORT_2); NodeDistanceTable distanceTable = new NodeDistanceTable(1, 1, node); - PeerExplorer peerExplorer = new PeerExplorer(Collections.emptyList(), node, distanceTable, key, 199, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true); + PeerExplorer peerExplorer = new PeerExplorer(Collections.emptyList(), node, distanceTable, key, 199, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); assertEquals(ExecState.CREATED, peerExplorer.getState()); peerExplorer.start(); From 5410fe8fbdc723fbc2dd81cb1f001fcdace91968 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Thu, 21 Dec 2023 18:05:29 -0300 Subject: [PATCH 056/137] remove unused field --- rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java | 1 - 1 file changed, 1 deletion(-) diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java index aea6826df5b..6557d2444d1 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java @@ -63,7 +63,6 @@ public class PeerExplorer { private static final int MAX_NODES_TO_CHECK = 16; private static final int RETRIES_COUNT = 3; - private static final int MAX_RETRY_ATTEMPTS = 5; private final List initialBootNodes; private int retryCounter = 0; private final long maxBootRetries; From b84e091c5435b2db12df37d51353e745b58abe26 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Mon, 8 Jan 2024 10:28:51 -0300 Subject: [PATCH 057/137] add unit tests --- .../co/rsk/net/discovery/PeerExplorer.java | 5 ++ .../rsk/net/discovery/PeerExplorerTest.java | 54 +++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java index 6557d2444d1..a44e1636c59 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java @@ -155,6 +155,11 @@ ExecState getState() { return state; } + @VisibleForTesting + int getRetryCounter() { + return retryCounter; + } + @VisibleForTesting Set startConversationWithNewNodes() { Set sentAddresses = new HashSet<>(); diff --git a/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java b/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java index 6fedac1b88a..506fd993f2a 100644 --- a/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java +++ b/rskj-core/src/test/java/co/rsk/net/discovery/PeerExplorerTest.java @@ -663,6 +663,60 @@ void testStartAndStop() { assertEquals(ExecState.FINISHED, peerExplorer.getState()); } + @Test + void testUnlimitedRetriesWhenLimitIsNegativeOne() { + ECKey key = ECKey.fromPrivate(Hex.decode(KEY_1)).decompress(); + Node node = new Node(key.getNodeId(), HOST_2, PORT_2); + NodeDistanceTable distanceTable = new NodeDistanceTable(1, 1, node); + + PeerExplorer peerExplorer = new PeerExplorer(Collections.emptyList(), node, distanceTable, key, 199, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, -1); + + peerExplorer.start(); + + for (int i = 0; i < 100; i++) { + peerExplorer.update(); + } + Assertions.assertEquals(peerExplorer.getRetryCounter(), 100); + } + + @Test + void testSpecificRetryLimit() { + ECKey key = ECKey.fromPrivate(Hex.decode(KEY_1)).decompress(); + Node node = new Node(key.getNodeId(), HOST_2, PORT_2); + NodeDistanceTable distanceTable = new NodeDistanceTable(1, 1, node); + + int maxBootRetries = 5; + + PeerExplorer peerExplorer = new PeerExplorer(Collections.emptyList(), node, distanceTable, key, 199, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, maxBootRetries); + + peerExplorer.start(); + + for (int i = 0; i < 10; i++) { + peerExplorer.update(); + } + + Assertions.assertEquals(maxBootRetries, peerExplorer.getRetryCounter(), "Retries should stop at the limit"); + } + + @Test + void testNoRetriesWhenLimitIsZero() { + ECKey key = ECKey.fromPrivate(Hex.decode(KEY_1)).decompress(); + Node node = new Node(key.getNodeId(), HOST_2, PORT_2); + NodeDistanceTable distanceTable = new NodeDistanceTable(1, 1, node); + + int maxBootRetries = 0; + + PeerExplorer peerExplorer = new PeerExplorer(Collections.emptyList(), node, distanceTable, key, 199, UPDATE, CLEAN, NETWORK_ID1, mock(PeerScoringManager.class), true, maxBootRetries); + + peerExplorer.start(); + + for (int i = 0; i < 10; i++) { + peerExplorer.update(); + } + + Assertions.assertEquals(0, peerExplorer.getRetryCounter(), "No retries should have occurred"); + } + private boolean containsNodeId(String nodeId, List nodes) { return nodes.stream().map(Node::getHexId).anyMatch(h -> StringUtils.equals(h, nodeId)); } From 5d5d665c81d676730010888d7a543e59c0cf20b4 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Wed, 17 Jan 2024 20:37:54 -0300 Subject: [PATCH 058/137] improve formatting and comments --- .../src/main/java/co/rsk/config/RskSystemProperties.java | 4 +++- .../src/main/java/co/rsk/net/discovery/PeerExplorer.java | 9 ++------- rskj-core/src/main/resources/reference.conf | 3 ++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index 2e69655a724..57ee131baa2 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -49,6 +49,8 @@ public class RskSystemProperties extends SystemProperties { private static final int PD_DEFAULT_REFRESH_PERIOD = 60000; //miliseconds private static final int PD_DEFAULT_MAX_BOOTSTRAP_RETRIES = -1; + private static final String PD_MAX_BOOTSTRAP_RETRIES_CONFIG = "peer.discovery.maxBootRetries"; + private static final String REGTEST_BLOCKCHAIN_CONFIG = "regtest"; private static final String MINER_REWARD_ADDRESS_CONFIG = "miner.reward.address"; @@ -264,7 +266,7 @@ public boolean allowMultipleConnectionsPerHostPort() { } public long peerDiscoveryMaxBootRetries() { - return getLong("peer.discovery.maxBootRetries", PD_DEFAULT_MAX_BOOTSTRAP_RETRIES); + return getLong(PD_MAX_BOOTSTRAP_RETRIES_CONFIG, PD_DEFAULT_MAX_BOOTSTRAP_RETRIES); } public int discoveryBucketSize() { diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java index a44e1636c59..47507ec5724 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/PeerExplorer.java @@ -41,12 +41,7 @@ import java.net.InetSocketAddress; import java.net.UnknownHostException; import java.security.SecureRandom; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -107,7 +102,7 @@ public PeerExplorer(List initialBootNodes, this.distanceTable = distanceTable; this.updateEntryLock = new ReentrantLock(); this.networkId = networkId; - this.initialBootNodes = initialBootNodes; + this.initialBootNodes = Collections.unmodifiableList(new ArrayList<>(initialBootNodes)); loadInitialBootNodes(initialBootNodes); this.cleaner = new PeerExplorerCleaner(updatePeriod, cleanPeriod, this); diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 827613c0c50..5a2c3c7153a 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -143,7 +143,8 @@ peer { discovery = { # allow multiple connections per host by default allowMultipleConnectionsPerHostPort = true - maxBootRetries = -1 + # allows to specify a number of attempts to discover at least one peer. By default, it's -1, which means an infinite number of attempts + maxBootRetries = -1 } # flag that allows to propagate a received block without executing it and only checking basic validation rules. From 4d7f1567bd6cc710a41a8c898b3b4903488af917 Mon Sep 17 00:00:00 2001 From: Volodymyr Kravets Date: Mon, 29 Jan 2024 13:56:50 +0200 Subject: [PATCH 059/137] Used fixed buffer allocator for udp channel --- .../java/co/rsk/net/discovery/UDPServer.java | 30 +++++++++++++++++-- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/net/discovery/UDPServer.java b/rskj-core/src/main/java/co/rsk/net/discovery/UDPServer.java index f7e1bf18d49..0ad594526fd 100644 --- a/rskj-core/src/main/java/co/rsk/net/discovery/UDPServer.java +++ b/rskj-core/src/main/java/co/rsk/net/discovery/UDPServer.java @@ -22,10 +22,9 @@ import co.rsk.util.ExecState; import com.google.common.annotations.VisibleForTesting; import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.EventLoopGroup; +import io.netty.channel.*; import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DatagramChannelConfig; import io.netty.channel.socket.nio.NioDatagramChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,6 +42,8 @@ public class UDPServer implements InternalService { private static final Logger logger = LoggerFactory.getLogger(UDPServer.class); + private static final int BUFFER_SIZE = 8_192; + private final int port; private final String address; @@ -163,6 +164,29 @@ private Bootstrap createBootstrap(EventLoopGroup group) { .handler(new ChannelInitializer() { @Override public void initChannel(@Nonnull NioDatagramChannel ch) { + DatagramChannelConfig channelConfig = ch.config(); + channelConfig.setRecvByteBufAllocator(new FixedRecvByteBufAllocator(BUFFER_SIZE)); + + Integer defaultSndBuf = channelConfig.getOption(ChannelOption.SO_SNDBUF); + if (defaultSndBuf == null || defaultSndBuf < BUFFER_SIZE) { + logger.info("Default {} size of {} bytes is not sufficient. Changing to {}", + ChannelOption.SO_SNDBUF, defaultSndBuf, BUFFER_SIZE); + channelConfig.setOption(ChannelOption.SO_SNDBUF, BUFFER_SIZE); + } + + Integer defaultRcvBuf = channelConfig.getOption(ChannelOption.SO_RCVBUF); + if (defaultRcvBuf == null || defaultRcvBuf < BUFFER_SIZE) { + logger.info("Default {} size of {} bytes is not sufficient. Changing to {}", + ChannelOption.SO_RCVBUF, defaultRcvBuf, BUFFER_SIZE); + channelConfig.setOption(ChannelOption.SO_RCVBUF, BUFFER_SIZE); + } + + logger.info("Init channel with {}({}), {}={}, {}={}", + FixedRecvByteBufAllocator.class.getSimpleName(), + BUFFER_SIZE, + ChannelOption.SO_SNDBUF, channelConfig.getOption(ChannelOption.SO_SNDBUF), + ChannelOption.SO_RCVBUF, channelConfig.getOption(ChannelOption.SO_RCVBUF)); + ch.pipeline().addLast(new PacketDecoder()); UDPChannel udpChannel = new UDPChannel(ch, peerExplorer); peerExplorer.setUDPChannel(udpChannel); From b7bcfda2d0679b58925a4b911577ccfc24212428 Mon Sep 17 00:00:00 2001 From: Vovchyk Date: Tue, 30 Jan 2024 11:43:26 +0200 Subject: [PATCH 060/137] Update Dockerfile to properly handle SIGTERM signal --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 4047d784c0b..4843e051bdd 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,5 +33,5 @@ ENV RSKJ_SYS_PROPS="-Drpc.providers.web.http.bind_address=0.0.0.0 -Drpc.provider ENV RSKJ_CLASS=co.rsk.Start ENV RSKJ_OPTS="" -ENTRYPOINT ["/bin/sh", "-c", "java $DEFAULT_JVM_OPTS $RSKJ_SYS_PROPS -cp rsk.jar $RSKJ_CLASS $RSKJ_OPTS \"${@}\"", "--"] +ENTRYPOINT ["/bin/sh", "-c", "exec java $DEFAULT_JVM_OPTS $RSKJ_SYS_PROPS -cp rsk.jar $RSKJ_CLASS $RSKJ_OPTS \"${@}\"", "--"] From bbb4da1a5e52fcd0f1a957247bf36c5ca05be37c Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Thu, 25 Jan 2024 21:26:42 -0400 Subject: [PATCH 061/137] Added RSKIP415 activation code --- .../org/ethereum/config/blockchain/upgrades/ConsensusRule.java | 1 + rskj-core/src/main/resources/expected.conf | 1 + rskj-core/src/main/resources/reference.conf | 1 + .../config/blockchain/upgrades/ActivationConfigTest.java | 1 + 4 files changed, 4 insertions(+) diff --git a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java index 5ae8580a070..9ce0be35761 100644 --- a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java +++ b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java @@ -91,6 +91,7 @@ public enum ConsensusRule { RSKIP398("rskip398"), RSKIP400("rskip400"), // From EIP-2028 calldata gas cost reduction RSKIP412("rskip412"), // From EIP-3198 BASEFEE opcode + RSKIP415("rskip415"), ; private String configKey; diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index dec928794e5..6647e73e22e 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -90,6 +90,7 @@ blockchain = { rskip398 = rskip400 = rskip412 = + rskip415 = } } gc = { diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 7fb2ae06c6b..00da71ef4b3 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -77,6 +77,7 @@ blockchain = { rskip398 = arrowhead600 rskip400 = arrowhead600 rskip412 = arrowhead600 + rskip415 = arrowhead600 } } gc = { diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java index 1ab4a39d9cb..694fac377bf 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java @@ -117,6 +117,7 @@ class ActivationConfigTest { " rskip398: arrowhead600", " rskip400: arrowhead600", " rskip412: arrowhead600", + " rskip415: arrowhead600", "}" )); From afdb194127e8e3684bdf0c1b8c46a13220fcf1cf Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Mon, 29 Jan 2024 23:33:38 -0400 Subject: [PATCH 062/137] Added getMemberByBtcPublicKey new method --- .../src/main/java/co/rsk/peg/Federation.java | 4 ++++ .../co/rsk/peg/LegacyErpFederationTest.java | 23 ++++++++++++++++++- .../co/rsk/peg/P2shErpFederationTest.java | 22 ++++++++++++++++++ .../peg/StandardMultisigFederationTest.java | 21 +++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Federation.java b/rskj-core/src/main/java/co/rsk/peg/Federation.java index 247554623c1..0ad41d9cc50 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/Federation.java @@ -64,6 +64,10 @@ public List getMembers() { return members; } + public Optional getMemberByBtcPublicKey(BtcECKey btcPublicKey) { + return members.stream().filter(federationMember -> federationMember.getBtcPublicKey().equals(btcPublicKey)).findFirst(); + } + public List getBtcPublicKeys() { // Copy instances since we don't control // immutability of BtcECKey instances diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index e62b900e596..2a6c929186f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -14,7 +14,6 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.bitcoinj.core.ScriptException; import co.rsk.bitcoinj.core.Utils; -import co.rsk.bitcoinj.script.ErpFederationRedeemScriptParser; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.script.ScriptOpCodes; import co.rsk.config.BridgeConstants; @@ -36,6 +35,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -697,6 +697,27 @@ void spendFromErpFed_after_RSKIP293_mainnet_using_standard_multisig() { )); } + @Test + void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ + BtcECKey existingMemberBtcPublicKey = standardKeys.get(0); + Optional foundMember = federation.getMemberByBtcPublicKey(existingMemberBtcPublicKey); + Assertions.assertTrue(foundMember.isPresent()); + Assertions.assertEquals(existingMemberBtcPublicKey, foundMember.get().getBtcPublicKey()); + } + + @Test + void test_getMemberByBtcPublicKey_passing_non_existing_btcPublicKey(){ + BtcECKey noExistingBtcPublicKey = new BtcECKey(); + Optional foundMember = federation.getMemberByBtcPublicKey(noExistingBtcPublicKey); + Assertions.assertFalse(foundMember.isPresent()); + } + + @Test + void test_getMemberByBtcPublicKey_passing_null_btcPublicKey(){ + Optional foundMember = federation.getMemberByBtcPublicKey(null); + Assertions.assertFalse(foundMember.isPresent()); + } + private void createErpFederation(BridgeConstants constants, boolean isRskip293Active) { when(activations.isActive(ConsensusRule.RSKIP293)).thenReturn(isRskip293Active); diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index 46908b100cd..b79c0db298a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -23,6 +23,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -454,6 +455,27 @@ void spendFromP2shErpFed( )); } + @Test + void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ + BtcECKey existingMemberBtcPublicKey = standardKeys.get(0); + Optional foundMember = federation.getMemberByBtcPublicKey(existingMemberBtcPublicKey); + Assertions.assertTrue(foundMember.isPresent()); + Assertions.assertEquals(existingMemberBtcPublicKey, foundMember.get().getBtcPublicKey()); + } + + @Test + void test_getMemberByBtcPublicKey_passing_non_existing_btcPublicKey(){ + BtcECKey noExistingBtcPublicKey = new BtcECKey(); + Optional foundMember = federation.getMemberByBtcPublicKey(noExistingBtcPublicKey); + Assertions.assertFalse(foundMember.isPresent()); + } + + @Test + void test_getMemberByBtcPublicKey_passing_null_btcPublicKey(){ + Optional foundMember = federation.getMemberByBtcPublicKey(null); + Assertions.assertFalse(foundMember.isPresent()); + } + private void validateP2shErpRedeemScript( Script erpRedeemScript, List defaultMultisigKeys, diff --git a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java index fee7f0045e7..13f061338c1 100644 --- a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java @@ -320,4 +320,25 @@ void isMember(){ FederationMember invalidPubKeys = new FederationMember(invalidBtcKey, invalidRskKey, invalidRskKey); assertFalse(federation.isMember(invalidPubKeys)); } + + @Test + void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ + BtcECKey existingMemberBtcPublicKey = sortedPublicKeys.get(0); + Optional foundMember = federation.getMemberByBtcPublicKey(existingMemberBtcPublicKey); + Assertions.assertTrue(foundMember.isPresent()); + Assertions.assertEquals(existingMemberBtcPublicKey, foundMember.get().getBtcPublicKey()); + } + + @Test + void test_getMemberByBtcPublicKey_passing_non_existing_btcPublicKey(){ + BtcECKey noExistingBtcPublicKey = new BtcECKey(); + Optional foundMember = federation.getMemberByBtcPublicKey(noExistingBtcPublicKey); + Assertions.assertFalse(foundMember.isPresent()); + } + + @Test + void test_getMemberByBtcPublicKey_passing_null_btcPublicKey(){ + Optional foundMember = federation.getMemberByBtcPublicKey(null); + Assertions.assertFalse(foundMember.isPresent()); + } } From 5dc82e94fbe34a382ef420d95511b0b6a450866e Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Tue, 30 Jan 2024 11:00:50 -0400 Subject: [PATCH 063/137] - Change findFirst to findAny on getMemberByBtcPublicKey method - Improved naming convention for the unit tests added --- rskj-core/src/main/java/co/rsk/peg/Federation.java | 2 +- .../src/test/java/co/rsk/peg/LegacyErpFederationTest.java | 6 +++--- .../src/test/java/co/rsk/peg/P2shErpFederationTest.java | 6 +++--- .../java/co/rsk/peg/StandardMultisigFederationTest.java | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Federation.java b/rskj-core/src/main/java/co/rsk/peg/Federation.java index 0ad41d9cc50..f45579d18a8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/Federation.java @@ -65,7 +65,7 @@ public List getMembers() { } public Optional getMemberByBtcPublicKey(BtcECKey btcPublicKey) { - return members.stream().filter(federationMember -> federationMember.getBtcPublicKey().equals(btcPublicKey)).findFirst(); + return members.stream().filter(federationMember -> federationMember.getBtcPublicKey().equals(btcPublicKey)).findAny(); } public List getBtcPublicKeys() { diff --git a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java index 2a6c929186f..f2e175a723e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/LegacyErpFederationTest.java @@ -698,7 +698,7 @@ void spendFromErpFed_after_RSKIP293_mainnet_using_standard_multisig() { } @Test - void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_existing_btcPublicKey_should_return_found_member(){ BtcECKey existingMemberBtcPublicKey = standardKeys.get(0); Optional foundMember = federation.getMemberByBtcPublicKey(existingMemberBtcPublicKey); Assertions.assertTrue(foundMember.isPresent()); @@ -706,14 +706,14 @@ void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ } @Test - void test_getMemberByBtcPublicKey_passing_non_existing_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_non_existing_btcPublicKey_should_return_empty(){ BtcECKey noExistingBtcPublicKey = new BtcECKey(); Optional foundMember = federation.getMemberByBtcPublicKey(noExistingBtcPublicKey); Assertions.assertFalse(foundMember.isPresent()); } @Test - void test_getMemberByBtcPublicKey_passing_null_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_null_btcPublicKey_should_return_empty(){ Optional foundMember = federation.getMemberByBtcPublicKey(null); Assertions.assertFalse(foundMember.isPresent()); } diff --git a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java index b79c0db298a..999a506f9a7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/P2shErpFederationTest.java @@ -456,7 +456,7 @@ void spendFromP2shErpFed( } @Test - void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_existing_btcPublicKey_should_return_found_member(){ BtcECKey existingMemberBtcPublicKey = standardKeys.get(0); Optional foundMember = federation.getMemberByBtcPublicKey(existingMemberBtcPublicKey); Assertions.assertTrue(foundMember.isPresent()); @@ -464,14 +464,14 @@ void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ } @Test - void test_getMemberByBtcPublicKey_passing_non_existing_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_non_existing_btcPublicKey_should_return_empty(){ BtcECKey noExistingBtcPublicKey = new BtcECKey(); Optional foundMember = federation.getMemberByBtcPublicKey(noExistingBtcPublicKey); Assertions.assertFalse(foundMember.isPresent()); } @Test - void test_getMemberByBtcPublicKey_passing_null_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_null_btcPublicKey_should_return_empty(){ Optional foundMember = federation.getMemberByBtcPublicKey(null); Assertions.assertFalse(foundMember.isPresent()); } diff --git a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java index 13f061338c1..2a0fc0d1e43 100644 --- a/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/StandardMultisigFederationTest.java @@ -322,7 +322,7 @@ void isMember(){ } @Test - void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_existing_btcPublicKey_should_return_found_member(){ BtcECKey existingMemberBtcPublicKey = sortedPublicKeys.get(0); Optional foundMember = federation.getMemberByBtcPublicKey(existingMemberBtcPublicKey); Assertions.assertTrue(foundMember.isPresent()); @@ -330,14 +330,14 @@ void test_getMemberByBtcPublicKey_passing_existing_btcPublicKey(){ } @Test - void test_getMemberByBtcPublicKey_passing_non_existing_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_non_existing_btcPublicKey_should_return_empty(){ BtcECKey noExistingBtcPublicKey = new BtcECKey(); Optional foundMember = federation.getMemberByBtcPublicKey(noExistingBtcPublicKey); Assertions.assertFalse(foundMember.isPresent()); } @Test - void test_getMemberByBtcPublicKey_passing_null_btcPublicKey(){ + void getMemberByBtcPublicKey_passing_null_btcPublicKey_should_return_empty(){ Optional foundMember = federation.getMemberByBtcPublicKey(null); Assertions.assertFalse(foundMember.isPresent()); } From 915ad7961a9c17bd7d75a6448d51ea3614ea0632 Mon Sep 17 00:00:00 2001 From: jeremy-then Date: Wed, 31 Jan 2024 12:56:50 -0400 Subject: [PATCH 064/137] Changes RemascFederationProvider.getFederatorAddress logic and adds tests --- .../src/main/java/co/rsk/remasc/Remasc.java | 17 +++- .../rsk/remasc/RemascFederationProvider.java | 34 +++----- .../remasc/RemascFederationProviderTest.java | 85 +++++++++++++++++-- .../remasc/RemascProcessMinerFeesTest.java | 19 ++++- .../rsk/remasc/RemascStorageProviderTest.java | 50 +++++++++-- 5 files changed, 165 insertions(+), 40 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/remasc/Remasc.java b/rskj-core/src/main/java/co/rsk/remasc/Remasc.java index db430403df6..8a7de72a61f 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/Remasc.java +++ b/rskj-core/src/main/java/co/rsk/remasc/Remasc.java @@ -22,6 +22,8 @@ import co.rsk.core.Coin; import co.rsk.core.RskAddress; import co.rsk.core.bc.SelectionRule; +import co.rsk.peg.BridgeStorageProvider; +import co.rsk.peg.FederationSupport; import co.rsk.rpc.modules.trace.ProgramSubtrace; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -32,6 +34,7 @@ import org.ethereum.core.Transaction; import org.ethereum.db.BlockStore; import org.ethereum.vm.LogInfo; +import org.ethereum.vm.PrecompiledContracts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -199,7 +202,19 @@ RskAddress getRskLabsAddress() { } private Coin payToFederation(Constants constants, boolean isRskip85Enabled, Block processingBlock, BlockHeader processingBlockHeader, Coin syntheticReward) { - RemascFederationProvider federationProvider = new RemascFederationProvider(activationConfig, constants.getBridgeConstants(), repository, processingBlock); + + ActivationConfig.ForBlock activations = activationConfig.forBlock(processingBlock.getNumber()); + + BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( + repository, + PrecompiledContracts.BRIDGE_ADDR, + constants.getBridgeConstants(), + activations + ); + + FederationSupport federationSupport = new FederationSupport(constants.getBridgeConstants(), bridgeStorageProvider, processingBlock, activations); + + RemascFederationProvider federationProvider = new RemascFederationProvider(activations, federationSupport); Coin federationReward = syntheticReward.divide(BigInteger.valueOf(remascConstants.getFederationDivisor())); Coin payToFederation = provider.getFederationBalance().add(federationReward); diff --git a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java index ae5c8fcc37b..913e84daaf8 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java +++ b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java @@ -17,36 +17,26 @@ */ package co.rsk.remasc; -import co.rsk.config.BridgeConstants; import co.rsk.core.RskAddress; -import co.rsk.peg.BridgeStorageProvider; +import co.rsk.peg.FederationMember; import co.rsk.peg.FederationSupport; import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.core.Block; -import org.ethereum.core.Repository; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.crypto.ECKey; -import org.ethereum.vm.PrecompiledContracts; /** * Created by ajlopez on 14/11/2017. */ public class RemascFederationProvider { + private final FederationSupport federationSupport; + private final ActivationConfig.ForBlock activations; public RemascFederationProvider( - ActivationConfig activationConfig, - BridgeConstants bridgeConstants, - Repository repository, - Block processingBlock) { - - ActivationConfig.ForBlock activations = activationConfig.forBlock(processingBlock.getNumber()); - BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( - repository, - PrecompiledContracts.BRIDGE_ADDR, - bridgeConstants, - activations - ); - this.federationSupport = new FederationSupport(bridgeConstants, bridgeStorageProvider, processingBlock, activations); + ActivationConfig.ForBlock activations, + FederationSupport federationSupport) { + this.federationSupport = federationSupport; + this.activations = activations; } public int getFederationSize() { @@ -54,7 +44,11 @@ public int getFederationSize() { } public RskAddress getFederatorAddress(int n) { - byte[] publicKey = this.federationSupport.getFederatorBtcPublicKey(n); - return new RskAddress(ECKey.fromPublicOnly(publicKey).getAddress()); + if(!activations.isActive(ConsensusRule.RSKIP415)) { + byte[] btcPublicKey = this.federationSupport.getFederatorBtcPublicKey(n); + return new RskAddress(ECKey.fromPublicOnly(btcPublicKey).getAddress()); + } + byte[] rskPublicKey = this.federationSupport.getFederatorPublicKeyOfType(n, FederationMember.KeyType.RSK); + return new RskAddress(ECKey.fromPublicOnly(rskPublicKey).getAddress()); } } diff --git a/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java b/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java index b2d318d71f5..84cd250d782 100644 --- a/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java @@ -2,17 +2,30 @@ import co.rsk.blockchain.utils.BlockGenerator; import co.rsk.config.BridgeRegTestConstants; +import co.rsk.core.RskAddress; +import co.rsk.peg.*; import co.rsk.test.builders.BlockChainBuilder; +import co.rsk.util.HexUtils; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.Blockchain; import org.ethereum.core.Genesis; +import org.ethereum.crypto.ECKey; +import org.ethereum.vm.PrecompiledContracts; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import static org.mockito.Mockito.*; + /** * Created by ajlopez on 14/11/2017. */ class RemascFederationProviderTest { + + private static final String BTC_PUBLIC_KEY = "0x03a5e32151f974c35c5d08af36a8d6af0593248e8e4adca7ed0148192eb2f5d1bf"; + private static final String RSK_PUBLIC_KEY = "0x02f3b5fb3121932db9450121b0a37f3f051dc8b3fd5f1ea5e7cf726947d8f69c28"; + @Test void getDefaultFederationSize() { RemascFederationProvider provider = getRemascFederationProvider(); @@ -20,25 +33,79 @@ void getDefaultFederationSize() { } @Test - void getFederatorAddress() { - RemascFederationProvider provider = getRemascFederationProvider(); + void getFederatorAddress_preRSKIP415_returnsRskAddressDerivedFromBtcPublicKey() { + + int federatorIndex = 0; + + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP415)).thenReturn(false); + + FederationSupport federationSupport = mock(FederationSupport.class); + + byte[] btcPublicKey = HexUtils.strHexOrStrNumberToByteArray(BTC_PUBLIC_KEY); - byte[] address = provider.getFederatorAddress(0).getBytes(); + when(federationSupport.getFederatorBtcPublicKey(federatorIndex)) + .thenReturn(btcPublicKey); + + RemascFederationProvider provider = new RemascFederationProvider(activations, federationSupport); + + RskAddress actualRskAddress = provider.getFederatorAddress(federatorIndex); + RskAddress expectedRskAddress = new RskAddress(ECKey.fromPublicOnly(btcPublicKey).getAddress()); + + Assertions.assertEquals(expectedRskAddress, actualRskAddress); + verify(federationSupport, never()).getFederatorPublicKeyOfType(federatorIndex, FederationMember.KeyType.RSK); + verify(federationSupport, times(1)).getFederatorBtcPublicKey(federatorIndex); + + } + + @Test + void getFederatorAddress_postRSKIP415_returnsRskAddressDerivedFromRskPublicKey() { + + int federatorIndex = 0; + + ActivationConfig.ForBlock activations = mock(ActivationConfig.ForBlock.class); + when(activations.isActive(ConsensusRule.RSKIP415)).thenReturn(true); + + FederationSupport federationSupport = mock(FederationSupport.class); + + byte[] rskPublicKey = HexUtils.strHexOrStrNumberToByteArray(RSK_PUBLIC_KEY); + + when(federationSupport.getFederatorPublicKeyOfType(federatorIndex, FederationMember.KeyType.RSK)) + .thenReturn(rskPublicKey); + + RemascFederationProvider provider = new RemascFederationProvider(activations, federationSupport); + + RskAddress actualRskAddress = provider.getFederatorAddress(federatorIndex); + RskAddress expectedRskAddress = new RskAddress(ECKey.fromPublicOnly(rskPublicKey).getAddress()); + + Assertions.assertEquals(expectedRskAddress, actualRskAddress); + verify(federationSupport, never()).getFederatorBtcPublicKey(federatorIndex); + verify(federationSupport, times(1)).getFederatorPublicKeyOfType(federatorIndex, FederationMember.KeyType.RSK); - Assertions.assertNotNull(address); - Assertions.assertEquals(20, address.length); } private static RemascFederationProvider getRemascFederationProvider() { + Genesis genesisBlock = new BlockGenerator().getGenesisBlock(); BlockChainBuilder builder = new BlockChainBuilder().setTesting(true).setGenesis(genesisBlock); Blockchain blockchain = builder.build(); - return new RemascFederationProvider( - ActivationConfigsForTest.all(), - BridgeRegTestConstants.getInstance(), + ActivationConfig.ForBlock activations = ActivationConfigsForTest.all().forBlock(blockchain.getBestBlock().getNumber()); + + BridgeRegTestConstants bridgeRegTestConstants = BridgeRegTestConstants.getInstance(); + + BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( builder.getRepository(), - blockchain.getBestBlock() + PrecompiledContracts.BRIDGE_ADDR, + bridgeRegTestConstants, + activations + ); + + FederationSupport federationSupport = new FederationSupport(bridgeRegTestConstants, bridgeStorageProvider, blockchain.getBestBlock(), activations); + + return new RemascFederationProvider( + activations, + federationSupport ); } } diff --git a/rskj-core/src/test/java/co/rsk/remasc/RemascProcessMinerFeesTest.java b/rskj-core/src/test/java/co/rsk/remasc/RemascProcessMinerFeesTest.java index 4dc1ebf7f17..572aff76f27 100644 --- a/rskj-core/src/test/java/co/rsk/remasc/RemascProcessMinerFeesTest.java +++ b/rskj-core/src/test/java/co/rsk/remasc/RemascProcessMinerFeesTest.java @@ -32,12 +32,11 @@ import co.rsk.db.RepositorySnapshot; import co.rsk.db.StateRootHandler; import co.rsk.db.StateRootsStoreImpl; -import co.rsk.peg.BridgeSupportFactory; -import co.rsk.peg.PegTestUtils; -import co.rsk.peg.RepositoryBtcBlockStoreWithCache; +import co.rsk.peg.*; import co.rsk.test.builders.BlockChainBuilder; import org.bouncycastle.util.encoders.Hex; import org.ethereum.TestUtils; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; @@ -966,7 +965,19 @@ private HashMap getAccountsWithExpectedBalance(List otherAcc } private void validateFederatorsBalanceIsCorrect(RepositorySnapshot repository, long federationReward, Block executionBlock) { - RemascFederationProvider provider = new RemascFederationProvider(config.getActivationConfig(), config.getNetworkConstants().getBridgeConstants(), repository.startTracking(), executionBlock); + + ActivationConfig.ForBlock activations = config.getActivationConfig().forBlock(executionBlock.getNumber()); + + BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( + repository.startTracking(), + PrecompiledContracts.BRIDGE_ADDR, + config.getNetworkConstants().getBridgeConstants(), + activations + ); + + FederationSupport federationSupport = new FederationSupport(config.getNetworkConstants().getBridgeConstants(), bridgeStorageProvider, executionBlock, activations); + + RemascFederationProvider provider = new RemascFederationProvider(config.getActivationConfig().forBlock(executionBlock.getNumber()), federationSupport); int nfederators = provider.getFederationSize(); diff --git a/rskj-core/src/test/java/co/rsk/remasc/RemascStorageProviderTest.java b/rskj-core/src/test/java/co/rsk/remasc/RemascStorageProviderTest.java index 14ab83b2a37..c29b63d5f8a 100644 --- a/rskj-core/src/test/java/co/rsk/remasc/RemascStorageProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/remasc/RemascStorageProviderTest.java @@ -29,13 +29,12 @@ import co.rsk.db.MutableTrieImpl; import co.rsk.db.RepositoryLocator; import co.rsk.db.RepositorySnapshot; -import co.rsk.peg.BridgeSupportFactory; -import co.rsk.peg.PegTestUtils; -import co.rsk.peg.RepositoryBtcBlockStoreWithCache; +import co.rsk.peg.*; import co.rsk.test.builders.BlockChainBuilder; import co.rsk.trie.Trie; import org.ethereum.TestUtils; import org.ethereum.config.Constants; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; @@ -293,7 +292,20 @@ void alwaysPaysFedBeforeRFS() throws IOException { Blockchain blockchain = testRunner.getBlockChain(); RepositoryLocator repositoryLocator = builder.getRepositoryLocator(); RepositorySnapshot repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader()); - RemascFederationProvider federationProvider = new RemascFederationProvider(config.getActivationConfig(), config.getNetworkConstants().getBridgeConstants(), repository.startTracking(), testRunner.getBlockChain().getBestBlock()); + Block executionBlock = testRunner.getBlockChain().getBestBlock(); + + ActivationConfig.ForBlock activations = config.getActivationConfig().forBlock(executionBlock.getNumber()); + + BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( + repository.startTracking(), + PrecompiledContracts.BRIDGE_ADDR, + config.getNetworkConstants().getBridgeConstants(), + activations + ); + + FederationSupport federationSupport = new FederationSupport(config.getNetworkConstants().getBridgeConstants(), bridgeStorageProvider, executionBlock, activations); + + RemascFederationProvider federationProvider = new RemascFederationProvider(config.getActivationConfig().forBlock(executionBlock.getNumber()), federationSupport); assertEquals(Coin.valueOf(0), this.getRemascStorageProvider(repository).getFederationBalance()); long federatorBalance = (168 / federationProvider.getFederationSize()) * 2; assertEquals(Coin.valueOf(federatorBalance), RemascTestRunner.getAccountBalance(repository, federationProvider.getFederatorAddress(0))); @@ -320,7 +332,20 @@ void doesntPayFedBelowMinimumRewardAfterRFS() throws IOException { Blockchain blockchain = testRunner.getBlockChain(); RepositoryLocator repositoryLocator = builder.getRepositoryLocator(); RepositorySnapshot repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader()); - RemascFederationProvider federationProvider = new RemascFederationProvider(config.getActivationConfig(), config.getNetworkConstants().getBridgeConstants(), repository.startTracking(), testRunner.getBlockChain().getBestBlock()); + Block executionBlock = testRunner.getBlockChain().getBestBlock(); + + ActivationConfig.ForBlock activations = config.getActivationConfig().forBlock(executionBlock.getNumber()); + + BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( + repository.startTracking(), + PrecompiledContracts.BRIDGE_ADDR, + config.getNetworkConstants().getBridgeConstants(), + activations + ); + + FederationSupport federationSupport = new FederationSupport(config.getNetworkConstants().getBridgeConstants(), bridgeStorageProvider, executionBlock, activations); + + RemascFederationProvider federationProvider = new RemascFederationProvider(config.getActivationConfig().forBlock(executionBlock.getNumber()), federationSupport); assertEquals(Coin.valueOf(336), this.getRemascStorageProvider(repository).getFederationBalance()); assertEquals(null, RemascTestRunner.getAccountBalance(repository, federationProvider.getFederatorAddress(0))); } @@ -370,7 +395,20 @@ void paysFedWhenHigherThanMinimumRewardAfterRFS() throws IOException { Blockchain blockchain = testRunner.getBlockChain(); RepositoryLocator repositoryLocator = builder.getRepositoryLocator(); RepositorySnapshot repository = repositoryLocator.snapshotAt(blockchain.getBestBlock().getHeader()); - RemascFederationProvider federationProvider = new RemascFederationProvider(config.getActivationConfig(), config.getNetworkConstants().getBridgeConstants(), repository.startTracking(), testRunner.getBlockChain().getBestBlock()); + Block executionBlock = testRunner.getBlockChain().getBestBlock(); + + ActivationConfig.ForBlock activations = config.getActivationConfig().forBlock(executionBlock.getNumber()); + + BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( + repository.startTracking(), + PrecompiledContracts.BRIDGE_ADDR, + config.getNetworkConstants().getBridgeConstants(), + activations + ); + + FederationSupport federationSupport = new FederationSupport(config.getNetworkConstants().getBridgeConstants(), bridgeStorageProvider, executionBlock, activations); + + RemascFederationProvider federationProvider = new RemascFederationProvider(config.getActivationConfig().forBlock(executionBlock.getNumber()), federationSupport); long federatorBalance = (1680 / federationProvider.getFederationSize()) * 2; assertEquals(Coin.valueOf(0), this.getRemascStorageProvider(repository).getFederationBalance()); assertEquals(Coin.valueOf(federatorBalance), RemascTestRunner.getAccountBalance(repository, federationProvider.getFederatorAddress(0))); From 925ef8ec947a4e66d7b012d60aa793cedc96cd9d Mon Sep 17 00:00:00 2001 From: jeremy-then Date: Wed, 31 Jan 2024 17:59:03 -0400 Subject: [PATCH 065/137] Refactors RemascFederationProvider::getFederatorAddress and creates more utility functions for clean and readable code --- .../src/main/java/co/rsk/remasc/Remasc.java | 13 +++++++----- .../rsk/remasc/RemascFederationProvider.java | 19 ++++++++++++++--- .../remasc/RemascFederationProviderTest.java | 21 +++++++++---------- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/remasc/Remasc.java b/rskj-core/src/main/java/co/rsk/remasc/Remasc.java index 8a7de72a61f..4ea53fbb837 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/Remasc.java +++ b/rskj-core/src/main/java/co/rsk/remasc/Remasc.java @@ -18,6 +18,7 @@ package co.rsk.remasc; +import co.rsk.config.BridgeConstants; import co.rsk.config.RemascConfig; import co.rsk.core.Coin; import co.rsk.core.RskAddress; @@ -179,7 +180,7 @@ void processMinersFees() { Coin payToRskLabs = syntheticReward.divide(BigInteger.valueOf(remascConstants.getRskLabsDivisor())); feesPayer.payMiningFees(processingBlockHeader.getHash().getBytes(), payToRskLabs, rskLabsAddress, logs); syntheticReward = syntheticReward.subtract(payToRskLabs); - Coin payToFederation = payToFederation(constants, isRskip85Enabled, processingBlock, processingBlockHeader, syntheticReward); + Coin payToFederation = payToFederation(constants, processingBlock, processingBlockHeader, syntheticReward); syntheticReward = syntheticReward.subtract(payToFederation); if (!siblings.isEmpty()) { @@ -201,18 +202,20 @@ RskAddress getRskLabsAddress() { return isRskip218Enabled ? remascConstants.getRskLabsAddressRskip218() : remascConstants.getRskLabsAddress(); } - private Coin payToFederation(Constants constants, boolean isRskip85Enabled, Block processingBlock, BlockHeader processingBlockHeader, Coin syntheticReward) { + private Coin payToFederation(Constants constants, Block processingBlock, BlockHeader processingBlockHeader, Coin syntheticReward) { ActivationConfig.ForBlock activations = activationConfig.forBlock(processingBlock.getNumber()); + BridgeConstants bridgeConstants = constants.getBridgeConstants(); + BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, - constants.getBridgeConstants(), + bridgeConstants, activations ); - FederationSupport federationSupport = new FederationSupport(constants.getBridgeConstants(), bridgeStorageProvider, processingBlock, activations); + FederationSupport federationSupport = new FederationSupport(bridgeConstants, bridgeStorageProvider, processingBlock, activations); RemascFederationProvider federationProvider = new RemascFederationProvider(activations, federationSupport); Coin federationReward = syntheticReward.divide(BigInteger.valueOf(remascConstants.getFederationDivisor())); @@ -224,7 +227,7 @@ private Coin payToFederation(Constants constants, boolean isRskip85Enabled, Bloc Coin payToFederator = payAndRemainderToFederator[0]; Coin restToLastFederator = payAndRemainderToFederator[1]; - if (isRskip85Enabled) { + if (activations.isActive(ConsensusRule.RSKIP85)) { BigInteger minimumFederatorPayableGas = constants.getFederatorMinimumPayableGas(); Coin minPayableFederatorFees = executionBlock.getMinimumGasPrice().multiply(minimumFederatorPayableGas); if (payToFederator.compareTo(minPayableFederatorFees) < 0) { diff --git a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java index 913e84daaf8..2d76cc3198a 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java +++ b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java @@ -45,10 +45,23 @@ public int getFederationSize() { public RskAddress getFederatorAddress(int n) { if(!activations.isActive(ConsensusRule.RSKIP415)) { - byte[] btcPublicKey = this.federationSupport.getFederatorBtcPublicKey(n); - return new RskAddress(ECKey.fromPublicOnly(btcPublicKey).getAddress()); + return getRskAddressFromBtcKey(n); } + return getRskAddressFromRskKey(n); + } + + private RskAddress getRskAddressFromBtcKey(int n) { + byte[] btcPublicKey = this.federationSupport.getFederatorBtcPublicKey(n); + return getRskAddressFromKey(btcPublicKey); + } + + private RskAddress getRskAddressFromRskKey(int n) { byte[] rskPublicKey = this.federationSupport.getFederatorPublicKeyOfType(n, FederationMember.KeyType.RSK); - return new RskAddress(ECKey.fromPublicOnly(rskPublicKey).getAddress()); + return getRskAddressFromKey(rskPublicKey); } + + private RskAddress getRskAddressFromKey(byte[] publicKey) { + return new RskAddress(ECKey.fromPublicOnly(publicKey).getAddress()); + } + } diff --git a/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java b/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java index 84cd250d782..c91db4385cb 100644 --- a/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java @@ -1,7 +1,7 @@ package co.rsk.remasc; import co.rsk.blockchain.utils.BlockGenerator; -import co.rsk.config.BridgeRegTestConstants; +import co.rsk.config.BridgeMainNetConstants; import co.rsk.core.RskAddress; import co.rsk.peg.*; import co.rsk.test.builders.BlockChainBuilder; @@ -11,7 +11,6 @@ import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.Blockchain; import org.ethereum.core.Genesis; -import org.ethereum.crypto.ECKey; import org.ethereum.vm.PrecompiledContracts; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; @@ -24,12 +23,14 @@ class RemascFederationProviderTest { private static final String BTC_PUBLIC_KEY = "0x03a5e32151f974c35c5d08af36a8d6af0593248e8e4adca7ed0148192eb2f5d1bf"; + private static final String RSK_ADDRESS_FROM_BTC_PUBLIC_KEY = "131c7c821b0e4a1ab570feed952d9304e03fddd1"; private static final String RSK_PUBLIC_KEY = "0x02f3b5fb3121932db9450121b0a37f3f051dc8b3fd5f1ea5e7cf726947d8f69c28"; + private static final String RSK_ADDRESS_FROM_RSK_PUBLIC_KEY = "54a948b3d76ce84e5c7b4b3cd01f2af1f18d41e0"; @Test void getDefaultFederationSize() { RemascFederationProvider provider = getRemascFederationProvider(); - Assertions.assertEquals(3, provider.getFederationSize()); + Assertions.assertEquals(15, provider.getFederationSize()); } @Test @@ -50,9 +51,8 @@ void getFederatorAddress_preRSKIP415_returnsRskAddressDerivedFromBtcPublicKey() RemascFederationProvider provider = new RemascFederationProvider(activations, federationSupport); RskAddress actualRskAddress = provider.getFederatorAddress(federatorIndex); - RskAddress expectedRskAddress = new RskAddress(ECKey.fromPublicOnly(btcPublicKey).getAddress()); - Assertions.assertEquals(expectedRskAddress, actualRskAddress); + Assertions.assertEquals(RSK_ADDRESS_FROM_BTC_PUBLIC_KEY, actualRskAddress.toHexString()); verify(federationSupport, never()).getFederatorPublicKeyOfType(federatorIndex, FederationMember.KeyType.RSK); verify(federationSupport, times(1)).getFederatorBtcPublicKey(federatorIndex); @@ -76,11 +76,10 @@ void getFederatorAddress_postRSKIP415_returnsRskAddressDerivedFromRskPublicKey() RemascFederationProvider provider = new RemascFederationProvider(activations, federationSupport); RskAddress actualRskAddress = provider.getFederatorAddress(federatorIndex); - RskAddress expectedRskAddress = new RskAddress(ECKey.fromPublicOnly(rskPublicKey).getAddress()); - Assertions.assertEquals(expectedRskAddress, actualRskAddress); - verify(federationSupport, never()).getFederatorBtcPublicKey(federatorIndex); + Assertions.assertEquals(RSK_ADDRESS_FROM_RSK_PUBLIC_KEY, actualRskAddress.toHexString()); verify(federationSupport, times(1)).getFederatorPublicKeyOfType(federatorIndex, FederationMember.KeyType.RSK); + verify(federationSupport, never()).getFederatorBtcPublicKey(federatorIndex); } @@ -92,16 +91,16 @@ private static RemascFederationProvider getRemascFederationProvider() { ActivationConfig.ForBlock activations = ActivationConfigsForTest.all().forBlock(blockchain.getBestBlock().getNumber()); - BridgeRegTestConstants bridgeRegTestConstants = BridgeRegTestConstants.getInstance(); + BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( builder.getRepository(), PrecompiledContracts.BRIDGE_ADDR, - bridgeRegTestConstants, + bridgeMainNetConstants, activations ); - FederationSupport federationSupport = new FederationSupport(bridgeRegTestConstants, bridgeStorageProvider, blockchain.getBestBlock(), activations); + FederationSupport federationSupport = new FederationSupport(bridgeMainNetConstants, bridgeStorageProvider, blockchain.getBestBlock(), activations); return new RemascFederationProvider( activations, From 88ac4e46cd09d42a98ea2e846a127ea7271c79b6 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Tue, 30 Jan 2024 17:39:41 -0400 Subject: [PATCH 066/137] - Refactor logAddSignature method - Add and update existing tests for logAddSignature method --- .../main/java/co/rsk/peg/BridgeSupport.java | 12 ++-- .../co/rsk/peg/utils/BridgeEventLogger.java | 3 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 18 +++-- .../peg/utils/BrigeEventLoggerLegacyImpl.java | 5 +- .../peg/BridgeSupportAddSignatureTest.java | 3 +- .../peg/utils/BridgeEventLoggerImplTest.java | 71 ++++++++++++++++--- .../BridgeEventLoggerLegacyImplTest.java | 6 +- .../upgrades/ActivationConfigsForTest.java | 3 +- 8 files changed, 97 insertions(+), 24 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 7404569f792..99b9367a330 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1435,6 +1435,8 @@ public void addSignature(BtcECKey federatorPublicKey, List signatures, b } Federation federation = optionalFederation.get(); + FederationMember signingFederationMember = federation.getMemberByBtcPublicKey(federatorPublicKey).get(); + BtcTransaction btcTx = provider.getPegoutsWaitingForSignatures().get(new Keccak256(rskTxHash)); if (btcTx == null) { logger.warn( @@ -1453,10 +1455,10 @@ public void addSignature(BtcECKey federatorPublicKey, List signatures, b } if (!activations.isActive(ConsensusRule.RSKIP326)) { - eventLogger.logAddSignature(federatorPublicKey, btcTx, rskTxHash); + eventLogger.logAddSignature(signingFederationMember, btcTx, rskTxHash); } - processSigning(federatorPublicKey, signatures, rskTxHash, btcTx, federation); + processSigning(signingFederationMember, signatures, rskTxHash, btcTx, federation); } private Optional getFederationFromPublicKey(BtcECKey federatorPublicKey) { @@ -1474,11 +1476,13 @@ private Optional getFederationFromPublicKey(BtcECKey federatorPublic } private void processSigning( - BtcECKey federatorPublicKey, + FederationMember federatorMember, List signatures, byte[] rskTxHash, BtcTransaction btcTx, Federation federation) throws IOException { + + BtcECKey federatorPublicKey = federatorMember.getBtcPublicKey(); // Build input hashes for signatures int numInputs = btcTx.getInputs().size(); @@ -1568,7 +1572,7 @@ private void processSigning( } if(signed && activations.isActive(ConsensusRule.RSKIP326)) { - eventLogger.logAddSignature(federatorPublicKey, btcTx, rskTxHash); + eventLogger.logAddSignature(federatorMember, btcTx, rskTxHash); } if (BridgeUtils.hasEnoughSignatures(btcContext, btcTx)) { diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLogger.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLogger.java index 62bc7f7121b..7152c778ff8 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLogger.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLogger.java @@ -22,6 +22,7 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.Federation; +import co.rsk.peg.FederationMember; import co.rsk.peg.pegin.RejectedPeginReason; import org.ethereum.core.Block; import org.ethereum.core.Transaction; @@ -36,7 +37,7 @@ public interface BridgeEventLogger { void logUpdateCollections(Transaction rskTx); - void logAddSignature(BtcECKey federatorPublicKey, BtcTransaction btcTx, byte[] rskTxHash); + void logAddSignature(FederationMember federationMember, BtcTransaction btcTx, byte[] rskTxHash); void logReleaseBtc(BtcTransaction btcTx, byte[] rskTxHash); diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index 9f8c328f975..3628b361b60 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -23,6 +23,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.peg.BridgeEvents; import co.rsk.peg.Federation; +import co.rsk.peg.FederationMember; import co.rsk.peg.pegin.RejectedPeginReason; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -75,10 +76,19 @@ public void logUpdateCollections(Transaction rskTx) { } @Override - public void logAddSignature(BtcECKey federatorPublicKey, BtcTransaction btcTx, byte[] rskTxHash) { - ECKey key = ECKey.fromPublicOnly(federatorPublicKey.getPubKey()); - String federatorRskAddress = ByteUtil.toHexString(key.getAddress()); - logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddress, federatorPublicKey); + public void logAddSignature(FederationMember federationMember, BtcTransaction btcTx, byte[] rskTxHash) { + if (shouldUseRskPublicKey()){ + String federatorRskAddress = ByteUtil.toHexString(federationMember.getRskPublicKey().getAddress()); + logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddress, federationMember.getBtcPublicKey()); + } else { + ECKey ecKeyFromBtcPublicKey = ECKey.fromPublicOnly(federationMember.getBtcPublicKey().getPubKey()); + String federatorRskAddressFromBtcPublicKey = ByteUtil.toHexString(ecKeyFromBtcPublicKey.getAddress()); + logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddressFromBtcPublicKey, federationMember.getBtcPublicKey()); + } + } + + private boolean shouldUseRskPublicKey() { + return activations.isActive(ConsensusRule.RSKIP415); } private void logAddSignatureInSolidityFormat(byte[] rskTxHash, String federatorRskAddress, BtcECKey federatorPublicKey) { diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java index 81d521ea1cb..802550f8716 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BrigeEventLoggerLegacyImpl.java @@ -23,6 +23,7 @@ import co.rsk.peg.Bridge; import co.rsk.peg.DeprecatedMethodCallException; import co.rsk.peg.Federation; +import co.rsk.peg.FederationMember; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.Block; @@ -77,7 +78,7 @@ public void logUpdateCollections(Transaction rskTx) { } @Override - public void logAddSignature(BtcECKey federatorPublicKey, BtcTransaction btcTx, byte[] rskTxHash) { + public void logAddSignature(FederationMember federationMember, BtcTransaction btcTx, byte[] rskTxHash) { if (activations.isActive(ConsensusRule.RSKIP146)) { throw new DeprecatedMethodCallException( "Calling BrigeEventLoggerLegacyImpl.logAddSignature method after RSKIP146 activation" @@ -85,7 +86,7 @@ public void logAddSignature(BtcECKey federatorPublicKey, BtcTransaction btcTx, b } List topics = Collections.singletonList(Bridge.ADD_SIGNATURE_TOPIC); byte[] data = RLP.encodeList(RLP.encodeString(btcTx.getHashAsString()), - RLP.encodeElement(federatorPublicKey.getPubKeyHash()), + RLP.encodeElement(federationMember.getBtcPublicKey().getPubKeyHash()), RLP.encodeElement(rskTxHash)); this.logs.add(new LogInfo(BRIDGE_CONTRACT_ADDRESS, topics, data)); diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index 5f4744eef9e..941aed257b3 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -377,12 +377,13 @@ private void test_addSignature_EventEmitted(boolean rskip326Active, boolean useV } BtcECKey federatorPubKey = BridgeRegTestConstants.REGTEST_FEDERATION_PUBLIC_KEYS.get(indexOfKeyToSignWith); + FederationMember federationMember = FederationTestUtils.getFederationMemberWithKey(federatorPubKey); bridgeSupport.addSignature(federatorPubKey, derEncodedSigs, rskTxHash.getBytes()); if(shouldSignTwice) { bridgeSupport.addSignature(federatorPubKey, derEncodedSigs, rskTxHash.getBytes()); } - verify(eventLogger, times(wantedNumberOfInvocations)).logAddSignature(federatorPubKey, btcTx, rskTxHash.getBytes()); + verify(eventLogger, times(wantedNumberOfInvocations)).logAddSignature(federationMember, btcTx, rskTxHash.getBytes()); } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index 369dc1898bd..863524a0e81 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -19,13 +19,16 @@ import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.ScriptBuilder; +import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.*; +import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.pegin.RejectedPeginReason; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; @@ -36,6 +39,8 @@ 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 org.junit.jupiter.params.provider.ValueSource; import java.math.BigInteger; @@ -44,6 +49,7 @@ import java.util.LinkedList; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.junit.jupiter.api.Assertions.assertArrayEquals; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -174,21 +180,68 @@ void logUpdateCollections() { assertEvent(eventLogs, 0, BridgeEvents.UPDATE_COLLECTIONS.getEvent(), new Object[]{}, new Object[]{tx.getSender(signatureCache).toString()}); } - @Test - void logAddSignature() { - // Setup logAddSignature params - BtcECKey federatorPubKey = BtcECKey.fromPrivate(BigInteger.valueOf(2L)); + private static Stream logAddSignatureArgProvider() { + ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); + ActivationConfig.ForBlock arrowHeadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); + + FederationMember multiKeyFedMember = new FederationMember( + BtcECKey.fromPrivate(BigInteger.valueOf(100)), + ECKey.fromPrivate(BigInteger.valueOf(200)), + ECKey.fromPrivate(BigInteger.valueOf(300)) + ); + ECKey rskKeyFromMultiFedMemberBtcKey = ECKey.fromPublicOnly(multiKeyFedMember.getBtcPublicKey().getPubKey()); + String wrongDerivedRskAddressFromMultiKeyFedMember = ByteUtil.toHexString(rskKeyFromMultiFedMemberBtcKey.getAddress()); + String derivedRskAddressFromMultiKeyFedMember = ByteUtil.toHexString(multiKeyFedMember.getRskPublicKey().getAddress()); + + Arguments before_arrowhead_should_log_wrong_rskAddress_for_multiKey_FedMember = Arguments.of(fingerrootActivations, multiKeyFedMember, wrongDerivedRskAddressFromMultiKeyFedMember); + Arguments after_arrowhead_should_log_correct_rskAddress_for_multiKey_FedMember = Arguments.of(arrowHeadActivations, multiKeyFedMember, derivedRskAddressFromMultiKeyFedMember); + + FederationMember singleKeyFedMember = new FederationMember( + BtcECKey.fromPrivate(BigInteger.valueOf(100)), + ECKey.fromPrivate(BigInteger.valueOf(100)), + ECKey.fromPrivate(BigInteger.valueOf(100)) + ); + ECKey rskKeyFromSingleFedMemberBtcKey = ECKey.fromPublicOnly(singleKeyFedMember.getBtcPublicKey().getPubKey()); + String derivedRskAddressFromSingleBtcKeyFedMember = ByteUtil.toHexString(rskKeyFromSingleFedMemberBtcKey.getAddress()); + String derivedRskAddressFromSingleRskKeyFedMember = ByteUtil.toHexString(singleKeyFedMember.getRskPublicKey().getAddress()); + + Arguments before_arrowhead_should_log_correct_rskAddress_for_single_FedMember = Arguments.of(fingerrootActivations, singleKeyFedMember, derivedRskAddressFromSingleBtcKeyFedMember); + Arguments after_arrowhead_should_log_correct_rskAddress_for_single_FedMember = Arguments.of(arrowHeadActivations, singleKeyFedMember, derivedRskAddressFromSingleRskKeyFedMember); + + return Stream.of( + before_arrowhead_should_log_wrong_rskAddress_for_multiKey_FedMember, + after_arrowhead_should_log_correct_rskAddress_for_multiKey_FedMember, + before_arrowhead_should_log_correct_rskAddress_for_single_FedMember, + after_arrowhead_should_log_correct_rskAddress_for_single_FedMember + ); + } + + @ParameterizedTest() + @MethodSource("logAddSignatureArgProvider") + void logAddSignature(ActivationConfig.ForBlock activations, FederationMember federationMember, RskAddress expectedRskAddress) { + // Arrange + BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); + BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); + LinkedList eventLogs = new LinkedList<>(); + BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, activations, eventLogs, signatureCache); + + + BtcECKey federatorBtcPubKey = federationMember.getBtcPublicKey(); + Keccak256 rskTxHash = PegTestUtils.createHash3(1); - when(btcTxMock.getHashAsString()).thenReturn("3e72fdbae7bbd103f08e876c765e3d5ba35db30ea46cb45ab52803f987ead9fb"); + + BtcTransaction btcTxMock = mock(BtcTransaction.class); + when(btcTxMock.getHash()).thenReturn(BitcoinTestUtils.createHash(1)); + when(btcTxMock.getHashAsString()).thenReturn(rskTxHash.toHexString()); // Act - eventLogger.logAddSignature(federatorPubKey, btcTxMock, rskTxHash.getBytes()); + eventLogger.logAddSignature(federationMember, btcTxMock, rskTxHash.getBytes()); + // Assert commonAssertLogs(eventLogs); assertTopics(3, eventLogs); - ECKey key = ECKey.fromPublicOnly(federatorPubKey.getPubKey()); - String federatorRskAddress = ByteUtil.toHexString(key.getAddress()); - assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), federatorRskAddress}, new Object[]{federatorPubKey.getPubKey()}); + + assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), ByteUtil.toHexString(expectedRskAddress.getBytes())}, new Object[]{federatorBtcPubKey.getPubKey()}); } @Test diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java index dfc52e60c63..6094f732320 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerLegacyImplTest.java @@ -115,10 +115,11 @@ void testLogAddSignatureBeforeRskip146() { // Setup logAddSignature params BtcECKey federatorPubKey = BtcECKey.fromPrivate(BigInteger.valueOf(2L)); + FederationMember federationMember = FederationTestUtils.getFederationMemberWithKey(federatorPubKey); when(btcTxMock.getHashAsString()).thenReturn("3e72fdbae7bbd103f08e876c765e3d5ba35db30ea46cb45ab52803f987ead9fb"); // Act - eventLogger.logAddSignature(federatorPubKey, btcTxMock, rskTxHash.getBytes()); + eventLogger.logAddSignature(federationMember, btcTxMock, rskTxHash.getBytes()); // Assert log size Assertions.assertEquals(1, eventLogs.size()); @@ -147,8 +148,9 @@ void testLogAddSignatureBeforeRskip146() { void testLogAddSignatureAfterRskip146() { when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); BtcECKey federatorPublicKey = new BtcECKey(); + FederationMember federationMember = FederationTestUtils.getFederationMemberWithKey(federatorPublicKey); byte[] bytes = rskTxHash.getBytes(); - assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logAddSignature(federatorPublicKey, btcTxMock, bytes)); + assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logAddSignature(federationMember, btcTxMock, bytes)); } @Test diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java index a80a3cdf0ca..f354cf6c380 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java @@ -182,7 +182,8 @@ private static List getArrowhead600Rskips() { ConsensusRule.RSKIP379, ConsensusRule.RSKIP398, ConsensusRule.RSKIP400, - ConsensusRule.RSKIP203 + ConsensusRule.RSKIP203, + ConsensusRule.RSKIP415 )); return rskips; From 7b407cddcdd6b749b6f0c1f0a210950c45e17e01 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Wed, 31 Jan 2024 01:01:35 -0400 Subject: [PATCH 067/137] Update getMemberByBtcPublicKey to compare public keys by byte array instead of using equal to the btcEcKey object itself --- rskj-core/src/main/java/co/rsk/peg/Federation.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Federation.java b/rskj-core/src/main/java/co/rsk/peg/Federation.java index f45579d18a8..38a82488b5a 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/Federation.java @@ -65,7 +65,10 @@ public List getMembers() { } public Optional getMemberByBtcPublicKey(BtcECKey btcPublicKey) { - return members.stream().filter(federationMember -> federationMember.getBtcPublicKey().equals(btcPublicKey)).findAny(); + if (btcPublicKey == null){ + return Optional.empty(); + } + return members.stream().filter(federationMember -> Arrays.equals(federationMember.getBtcPublicKey().getPubKey(), btcPublicKey.getPubKey())).findAny(); } public List getBtcPublicKeys() { From 66763f05b8a1a21148fc53c7b092628db3f9a43d Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Wed, 31 Jan 2024 09:31:57 -0400 Subject: [PATCH 068/137] Check if federation member was found before getting the value from the optional result when using getMemberByBtcPublicKey method --- rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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 99b9367a330..91806937d83 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1435,7 +1435,15 @@ public void addSignature(BtcECKey federatorPublicKey, List signatures, b } Federation federation = optionalFederation.get(); - FederationMember signingFederationMember = federation.getMemberByBtcPublicKey(federatorPublicKey).get(); + Optional federationMember = federation.getMemberByBtcPublicKey(federatorPublicKey); + if (!federationMember.isPresent()){ + logger.warn( + "Supplied federator public key {} does not belong to any of the federators.", + federatorPublicKey + ); + return; + } + FederationMember signingFederationMember = federationMember.get(); BtcTransaction btcTx = provider.getPegoutsWaitingForSignatures().get(new Keccak256(rskTxHash)); if (btcTx == null) { From 19b554f14d460972ede723c5c3205aefef365636 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Wed, 31 Jan 2024 22:28:54 -0400 Subject: [PATCH 069/137] - Reordered arrohead rskips. - Refactored logAddSignature method. - Refactored logAddSignature tests. - Renamed federatorPublicKey to federatorBtcPublicKey on processSigning method. - Updated getMemberByBtcPublicKey method to create a BtcEcKey with only the public key for then use it to find the federation member. --- .../main/java/co/rsk/peg/BridgeSupport.java | 14 ++-- .../src/main/java/co/rsk/peg/Federation.java | 3 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 15 ++-- .../peg/utils/BridgeEventLoggerImplTest.java | 69 +++++++++++-------- .../upgrades/ActivationConfigsForTest.java | 2 +- 5 files changed, 60 insertions(+), 43 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 91806937d83..9afaa4a330c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1490,7 +1490,7 @@ private void processSigning( BtcTransaction btcTx, Federation federation) throws IOException { - BtcECKey federatorPublicKey = federatorMember.getBtcPublicKey(); + BtcECKey federatorBtcPublicKey = federatorMember.getBtcPublicKey(); // Build input hashes for signatures int numInputs = btcTx.getInputs().size(); @@ -1522,13 +1522,13 @@ private void processSigning( Sha256Hash sighash = sighashes.get(i); - if (!federatorPublicKey.verify(sighash, sig)) { + if (!federatorBtcPublicKey.verify(sighash, sig)) { logger.warn( "Signature {} {} is not valid for hash {} and public key {}", i, ByteUtil.toHexString(sig.encodeToDER()), sighash, - federatorPublicKey + federatorBtcPublicKey ); return; } @@ -1550,24 +1550,24 @@ private void processSigning( Script inputScript = input.getScriptSig(); boolean alreadySignedByThisFederator = BridgeUtils.isInputSignedByThisFederator( - federatorPublicKey, + federatorBtcPublicKey, sighash, input); // Sign the input if it wasn't already if (!alreadySignedByThisFederator) { try { - int sigIndex = inputScript.getSigInsertionIndex(sighash, federatorPublicKey); + int sigIndex = inputScript.getSigInsertionIndex(sighash, federatorBtcPublicKey); inputScript = ScriptBuilder.updateScriptWithSignature(inputScript, txSigs.get(i).encodeToBitcoin(), sigIndex, 1, 1); input.setScriptSig(inputScript); logger.debug("Tx input {} for tx {} signed.", i, new Keccak256(rskTxHash)); signed = true; } catch (IllegalStateException e) { Federation retiringFederation = getRetiringFederation(); - if (getActiveFederation().hasBtcPublicKey(federatorPublicKey)) { + if (getActiveFederation().hasBtcPublicKey(federatorBtcPublicKey)) { logger.debug("A member of the active federation is trying to sign a tx of the retiring one"); return; - } else if (retiringFederation != null && retiringFederation.hasBtcPublicKey(federatorPublicKey)) { + } else if (retiringFederation != null && retiringFederation.hasBtcPublicKey(federatorBtcPublicKey)) { logger.debug("A member of the retiring federation is trying to sign a tx of the active one"); return; } diff --git a/rskj-core/src/main/java/co/rsk/peg/Federation.java b/rskj-core/src/main/java/co/rsk/peg/Federation.java index 38a82488b5a..38cb23b8727 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Federation.java +++ b/rskj-core/src/main/java/co/rsk/peg/Federation.java @@ -68,7 +68,8 @@ public Optional getMemberByBtcPublicKey(BtcECKey btcPublicKey) if (btcPublicKey == null){ return Optional.empty(); } - return members.stream().filter(federationMember -> Arrays.equals(federationMember.getBtcPublicKey().getPubKey(), btcPublicKey.getPubKey())).findAny(); + final BtcECKey btcPublicKeyOnly = BtcECKey.fromPublicOnly(btcPublicKey.getPubKey()); + return members.stream().filter(federationMember -> federationMember.getBtcPublicKey().equals(btcPublicKeyOnly)).findAny(); } public List getBtcPublicKeys() { diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index 3628b361b60..105c1431e1b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -77,14 +77,17 @@ public void logUpdateCollections(Transaction rskTx) { @Override public void logAddSignature(FederationMember federationMember, BtcTransaction btcTx, byte[] rskTxHash) { + String federatorRskAddress = getFederatorRskAddress(federationMember); + logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddress, federationMember.getBtcPublicKey()); + } + + private String getFederatorRskAddress(FederationMember federationMember){ if (shouldUseRskPublicKey()){ - String federatorRskAddress = ByteUtil.toHexString(federationMember.getRskPublicKey().getAddress()); - logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddress, federationMember.getBtcPublicKey()); - } else { - ECKey ecKeyFromBtcPublicKey = ECKey.fromPublicOnly(federationMember.getBtcPublicKey().getPubKey()); - String federatorRskAddressFromBtcPublicKey = ByteUtil.toHexString(ecKeyFromBtcPublicKey.getAddress()); - logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddressFromBtcPublicKey, federationMember.getBtcPublicKey()); + return ByteUtil.toHexString(federationMember.getRskPublicKey().getAddress()); } + + ECKey ecKeyFromBtcPublicKey = ECKey.fromPublicOnly(federationMember.getBtcPublicKey().getPubKey()); + return ByteUtil.toHexString(ecKeyFromBtcPublicKey.getAddress()); } private boolean shouldUseRskPublicKey() { diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index 863524a0e81..106da4e4a59 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -181,50 +181,62 @@ void logUpdateCollections() { } private static Stream logAddSignatureArgProvider() { - ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); - ActivationConfig.ForBlock arrowHeadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); - - FederationMember multiKeyFedMember = new FederationMember( - BtcECKey.fromPrivate(BigInteger.valueOf(100)), - ECKey.fromPrivate(BigInteger.valueOf(200)), - ECKey.fromPrivate(BigInteger.valueOf(300)) - ); - ECKey rskKeyFromMultiFedMemberBtcKey = ECKey.fromPublicOnly(multiKeyFedMember.getBtcPublicKey().getPubKey()); - String wrongDerivedRskAddressFromMultiKeyFedMember = ByteUtil.toHexString(rskKeyFromMultiFedMemberBtcKey.getAddress()); - String derivedRskAddressFromMultiKeyFedMember = ByteUtil.toHexString(multiKeyFedMember.getRskPublicKey().getAddress()); - - Arguments before_arrowhead_should_log_wrong_rskAddress_for_multiKey_FedMember = Arguments.of(fingerrootActivations, multiKeyFedMember, wrongDerivedRskAddressFromMultiKeyFedMember); - Arguments after_arrowhead_should_log_correct_rskAddress_for_multiKey_FedMember = Arguments.of(arrowHeadActivations, multiKeyFedMember, derivedRskAddressFromMultiKeyFedMember); - FederationMember singleKeyFedMember = new FederationMember( BtcECKey.fromPrivate(BigInteger.valueOf(100)), ECKey.fromPrivate(BigInteger.valueOf(100)), ECKey.fromPrivate(BigInteger.valueOf(100)) ); - ECKey rskKeyFromSingleFedMemberBtcKey = ECKey.fromPublicOnly(singleKeyFedMember.getBtcPublicKey().getPubKey()); - String derivedRskAddressFromSingleBtcKeyFedMember = ByteUtil.toHexString(rskKeyFromSingleFedMemberBtcKey.getAddress()); - String derivedRskAddressFromSingleRskKeyFedMember = ByteUtil.toHexString(singleKeyFedMember.getRskPublicKey().getAddress()); - - Arguments before_arrowhead_should_log_correct_rskAddress_for_single_FedMember = Arguments.of(fingerrootActivations, singleKeyFedMember, derivedRskAddressFromSingleBtcKeyFedMember); - Arguments after_arrowhead_should_log_correct_rskAddress_for_single_FedMember = Arguments.of(arrowHeadActivations, singleKeyFedMember, derivedRskAddressFromSingleRskKeyFedMember); + FederationMember multiKeyFedMember = new FederationMember( + BtcECKey.fromPrivate(BigInteger.valueOf(100)), + ECKey.fromPrivate(BigInteger.valueOf(200)), + ECKey.fromPrivate(BigInteger.valueOf(300)) + ); return Stream.of( - before_arrowhead_should_log_wrong_rskAddress_for_multiKey_FedMember, - after_arrowhead_should_log_correct_rskAddress_for_multiKey_FedMember, - before_arrowhead_should_log_correct_rskAddress_for_single_FedMember, - after_arrowhead_should_log_correct_rskAddress_for_single_FedMember + Arguments.of(singleKeyFedMember, multiKeyFedMember) ); } @ParameterizedTest() @MethodSource("logAddSignatureArgProvider") - void logAddSignature(ActivationConfig.ForBlock activations, FederationMember federationMember, RskAddress expectedRskAddress) { + void logAddSignature_before_rskip415(FederationMember federationMember) { // Arrange + ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); LinkedList eventLogs = new LinkedList<>(); - BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, activations, eventLogs, signatureCache); + BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, fingerrootActivations, eventLogs, signatureCache); + + + BtcECKey federatorBtcPubKey = federationMember.getBtcPublicKey(); + + Keccak256 rskTxHash = PegTestUtils.createHash3(1); + + BtcTransaction btcTxMock = mock(BtcTransaction.class); + when(btcTxMock.getHash()).thenReturn(BitcoinTestUtils.createHash(1)); + when(btcTxMock.getHashAsString()).thenReturn(rskTxHash.toHexString()); + + // Act + eventLogger.logAddSignature(federationMember, btcTxMock, rskTxHash.getBytes()); + + // Assert + commonAssertLogs(eventLogs); + assertTopics(3, eventLogs); + ECKey federatorECKeyFromBtcPubKey = ECKey.fromPublicOnly(federationMember.getBtcPublicKey().getPubKey()); + String derivedRskAddress = ByteUtil.toHexString(federatorECKeyFromBtcPubKey.getAddress()); + assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), derivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); + } + + @ParameterizedTest() + @MethodSource("logAddSignatureArgProvider") + void logAddSignature_after_rskip415(FederationMember federationMember) { + // Arrange + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); + BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); + BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); + LinkedList eventLogs = new LinkedList<>(); + BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, arrowheadActivations, eventLogs, signatureCache); BtcECKey federatorBtcPubKey = federationMember.getBtcPublicKey(); @@ -241,7 +253,8 @@ void logAddSignature(ActivationConfig.ForBlock activations, FederationMember fed commonAssertLogs(eventLogs); assertTopics(3, eventLogs); - assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), ByteUtil.toHexString(expectedRskAddress.getBytes())}, new Object[]{federatorBtcPubKey.getPubKey()}); + String derivedRskAddress = ByteUtil.toHexString(federationMember.getRskPublicKey().getAddress()); + assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), derivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); } @Test diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java index f354cf6c380..14748d67147 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java @@ -178,11 +178,11 @@ private static List getFingerroot500Rskips() { private static List getArrowhead600Rskips() { List rskips = new ArrayList<>(); rskips.addAll(Arrays.asList( + ConsensusRule.RSKIP203, ConsensusRule.RSKIP376, ConsensusRule.RSKIP379, ConsensusRule.RSKIP398, ConsensusRule.RSKIP400, - ConsensusRule.RSKIP203, ConsensusRule.RSKIP415 )); From 542f4335d80c7b18a4feb11c446feb78f027b09e Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Wed, 31 Jan 2024 23:51:03 -0400 Subject: [PATCH 070/137] Add tests for BridgeSupport.AddSignature method before and after RSKIP415 --- .../peg/BridgeSupportAddSignatureTest.java | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index 941aed257b3..81a91db8311 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -5,9 +5,12 @@ import java.util.*; import co.rsk.config.BridgeConstants; +import co.rsk.config.BridgeMainNetConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; +import org.ethereum.crypto.ECKey; +import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; import org.ethereum.util.RLPList; import org.ethereum.vm.LogInfo; @@ -543,6 +546,177 @@ void addSignatureMultipleInputsPartiallyValid() throws Exception { } } + @Test + void addSignature_beforeRSKIP415_should_derived_rskAddress_from_btcPublicKey() throws Exception { + // Arrange + BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); + NetworkParameters btcParams = bridgeMainNetConstants.getBtcParams(); + + ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); + + List federationMembers = FederationTestUtils.getFederationMembersFromPks(150, 250, 350); + Federation federation = new StandardMultisigFederation( + federationMembers, + Instant.EPOCH, + 0, + btcParams + ); + + BridgeStorageProvider provider = mock(BridgeStorageProvider.class); + when(provider.getNewFederation()) + .thenReturn(federation); + LinkedList eventLogs = new LinkedList<>(); + BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); + BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, fingerrootActivations, eventLogs, signatureCache); + + // Build prev btc tx + BtcTransaction prevTx = new BtcTransaction(btcParams); + TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, federation.getAddress()); + prevTx.addOutput(prevOut); + + // Build btc tx to be signed + BtcTransaction btcTx = new BtcTransaction(btcParams); + btcTx.addInput(prevOut).setScriptSig(createBaseInputScriptThatSpendsFromTheFederation(federation)); + TransactionOutput output = new TransactionOutput(btcParams, btcTx, Coin.COIN, new BtcECKey().toAddress(btcParams)); + btcTx.addOutput(output); + + // Save btc tx to be signed + SortedMap pegoutWaitingForSignatures = new TreeMap<>(); + + final Keccak256 rskTxHash = createHash3(1); + pegoutWaitingForSignatures.put(rskTxHash, btcTx); + when(provider.getPegoutsWaitingForSignatures()) + .thenReturn(pegoutWaitingForSignatures); + + BridgeSupport bridgeSupport = bridgeSupportBuilder + .withBridgeConstants(bridgeMainNetConstants) + .withProvider(provider) + .withEventLogger(eventLogger) + .withBtcLockSenderProvider(new BtcLockSenderProvider()) + .withActivations(fingerrootActivations) + .build(); + + BtcECKey privateKeyToSignWith = BtcECKey.fromPrivate(BigInteger.valueOf(150)); + Optional federationMember = federation.getMemberByBtcPublicKey(privateKeyToSignWith); + assertTrue(federationMember.isPresent()); + FederationMember federationMemberToSignWith = federationMember.get(); + BtcECKey federatorBtcPubKey = federationMemberToSignWith.getBtcPublicKey(); + + Script inputScript = btcTx.getInputs().get(0).getScriptSig(); + List chunks = inputScript.getChunks(); + byte[] program = chunks.get(chunks.size() - 1).data; + Script redeemScript = new Script(program); + Sha256Hash sigHash = btcTx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false); + BtcECKey.ECDSASignature sig = privateKeyToSignWith.sign(sigHash); + List derEncodedSigs = Collections.singletonList(sig.encodeToDER()); + + // Act + bridgeSupport.addSignature(federationMemberToSignWith.getBtcPublicKey(), derEncodedSigs, rskTxHash.getBytes()); + + // Assert + commonAssertLogs(eventLogs); + assertTopics(3, eventLogs); + + ECKey federatorECKeyFromBtcPubKey = ECKey.fromPublicOnly(federationMemberToSignWith.getBtcPublicKey().getPubKey()); + String derivedRskAddress = ByteUtil.toHexString(federatorECKeyFromBtcPubKey.getAddress()); + + assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), derivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); + } + + @Test + void addSignature_afterRSKIP415_should_derived_rskAddress_from_rskPublicKey() throws Exception { + // Arrange + BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); + NetworkParameters btcParams = bridgeMainNetConstants.getBtcParams(); + + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); + + List federationMembers = FederationTestUtils.getFederationMembersFromPks(150, 250, 350); + Federation federation = new StandardMultisigFederation( + federationMembers, + Instant.EPOCH, + 0, + btcParams + ); + + BridgeStorageProvider provider = mock(BridgeStorageProvider.class); + when(provider.getNewFederation()) + .thenReturn(federation); + LinkedList eventLogs = new LinkedList<>(); + BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); + BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, arrowheadActivations, eventLogs, signatureCache); + + // Build prev btc tx + BtcTransaction prevTx = new BtcTransaction(btcParams); + TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, federation.getAddress()); + prevTx.addOutput(prevOut); + + // Build btc tx to be signed + BtcTransaction btcTx = new BtcTransaction(btcParams); + btcTx.addInput(prevOut).setScriptSig(createBaseInputScriptThatSpendsFromTheFederation(federation)); + TransactionOutput output = new TransactionOutput(btcParams, btcTx, Coin.COIN, new BtcECKey().toAddress(btcParams)); + btcTx.addOutput(output); + + // Save btc tx to be signed + SortedMap pegoutWaitingForSignatures = new TreeMap<>(); + + final Keccak256 rskTxHash = createHash3(1); + pegoutWaitingForSignatures.put(rskTxHash, btcTx); + when(provider.getPegoutsWaitingForSignatures()) + .thenReturn(pegoutWaitingForSignatures); + + BridgeSupport bridgeSupport = bridgeSupportBuilder + .withBridgeConstants(bridgeMainNetConstants) + .withProvider(provider) + .withEventLogger(eventLogger) + .withBtcLockSenderProvider(new BtcLockSenderProvider()) + .withActivations(arrowheadActivations) + .build(); + + BtcECKey privateKeyToSignWith = BtcECKey.fromPrivate(BigInteger.valueOf(150)); + Optional federationMember = federation.getMemberByBtcPublicKey(privateKeyToSignWith); + assertTrue(federationMember.isPresent()); + FederationMember federationMemberToSignWith = federationMember.get(); + BtcECKey federatorBtcPubKey = federationMemberToSignWith.getBtcPublicKey(); + + Script inputScript = btcTx.getInputs().get(0).getScriptSig(); + List chunks = inputScript.getChunks(); + byte[] program = chunks.get(chunks.size() - 1).data; + Script redeemScript = new Script(program); + Sha256Hash sigHash = btcTx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false); + BtcECKey.ECDSASignature sig = privateKeyToSignWith.sign(sigHash); + List derEncodedSigs = Collections.singletonList(sig.encodeToDER()); + + // Act + bridgeSupport.addSignature(federationMemberToSignWith.getBtcPublicKey(), derEncodedSigs, rskTxHash.getBytes()); + + // Assert + commonAssertLogs(eventLogs); + assertTopics(3, eventLogs); + + String derivedRskAddress = ByteUtil.toHexString(federationMemberToSignWith.getRskPublicKey().getAddress()); + assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), derivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); + } + + private static void assertEvent(List logs, int index, CallTransaction.Function event, Object[] topics, Object[] params) { + final LogInfo log = logs.get(index); + assertEquals(LogInfo.byteArrayToList(event.encodeEventTopics(topics)), log.getTopics()); + assertArrayEquals(event.encodeEventData(params), log.getData()); + } + + private void assertTopics(int topics, List logs) { + assertEquals(topics, logs.get(0).getTopics().size()); + } + + private void commonAssertLogs(List logs) { + assertEquals(1, logs.size()); + LogInfo entry = logs.get(0); + + // Assert address that made the log + assertEquals(PrecompiledContracts.BRIDGE_ADDR, new RskAddress(entry.getAddress())); + assertArrayEquals(PrecompiledContracts.BRIDGE_ADDR.getBytes(), entry.getAddress()); + } + /** * Helper method to test addSignature() with a valid federatorPublicKey parameter and both valid/invalid signatures * From f7b8869391b0c36716c8f9f19833424dd30a8030 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Thu, 1 Feb 2024 14:27:22 -0400 Subject: [PATCH 071/137] - Reorder logic for getFederatorPublicKey method, now default behaviour is the latest rskip. - Refactored logAddSignature and getFederatorPublicKey to simplify legacy and latest logic - Update addSignature log when none federation match supplied btc public key. --- .../main/java/co/rsk/peg/BridgeSupport.java | 6 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 11 +- .../peg/BridgeSupportAddSignatureTest.java | 116 +++++------------- .../peg/utils/BridgeEventLoggerImplTest.java | 21 +++- 4 files changed, 58 insertions(+), 96 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 9afaa4a330c..fc9e8f0c332 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -1428,7 +1428,7 @@ public void addSignature(BtcECKey federatorPublicKey, List signatures, b Optional optionalFederation = getFederationFromPublicKey(federatorPublicKey); if (!optionalFederation.isPresent()) { logger.warn( - "Supplied federator public key {} does not belong to any of the federators.", + "[addSignature] Supplied federator btc public key {} does not belong to any of the federators.", federatorPublicKey ); return; @@ -1438,8 +1438,8 @@ public void addSignature(BtcECKey federatorPublicKey, List signatures, b Optional federationMember = federation.getMemberByBtcPublicKey(federatorPublicKey); if (!federationMember.isPresent()){ logger.warn( - "Supplied federator public key {} does not belong to any of the federators.", - federatorPublicKey + "[addSignature] Supplied federator btc public key {} doest not match any of the federator member btc public keys {}.", + federatorPublicKey, federation.getBtcPublicKeys() ); return; } diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index 105c1431e1b..70e1fbf0892 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -77,17 +77,16 @@ public void logUpdateCollections(Transaction rskTx) { @Override public void logAddSignature(FederationMember federationMember, BtcTransaction btcTx, byte[] rskTxHash) { - String federatorRskAddress = getFederatorRskAddress(federationMember); + String federatorRskAddress = ByteUtil.toHexString(getFederatorPublicKey(federationMember).getAddress());; logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddress, federationMember.getBtcPublicKey()); } - private String getFederatorRskAddress(FederationMember federationMember){ - if (shouldUseRskPublicKey()){ - return ByteUtil.toHexString(federationMember.getRskPublicKey().getAddress()); + private ECKey getFederatorPublicKey(FederationMember federationMember) { + if (!shouldUseRskPublicKey()) { + return ECKey.fromPublicOnly(federationMember.getBtcPublicKey().getPubKey()); } - ECKey ecKeyFromBtcPublicKey = ECKey.fromPublicOnly(federationMember.getBtcPublicKey().getPubKey()); - return ByteUtil.toHexString(ecKeyFromBtcPublicKey.getAddress()); + return federationMember.getRskPublicKey(); } private boolean shouldUseRskPublicKey() { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index 81a91db8311..cb29cd1a39a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -3,6 +3,7 @@ import java.time.Instant; import java.math.BigInteger; import java.util.*; +import java.util.stream.Stream; import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; @@ -41,6 +42,9 @@ 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 static co.rsk.peg.PegTestUtils.*; import static org.hamcrest.Matchers.hasItem; @@ -546,92 +550,44 @@ void addSignatureMultipleInputsPartiallyValid() throws Exception { } } - @Test - void addSignature_beforeRSKIP415_should_derived_rskAddress_from_btcPublicKey() throws Exception { - // Arrange - BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); - NetworkParameters btcParams = bridgeMainNetConstants.getBtcParams(); - + private static Stream addSignatureArgProvider() { ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); - List federationMembers = FederationTestUtils.getFederationMembersFromPks(150, 250, 350); - Federation federation = new StandardMultisigFederation( - federationMembers, - Instant.EPOCH, - 0, - btcParams - ); - - BridgeStorageProvider provider = mock(BridgeStorageProvider.class); - when(provider.getNewFederation()) - .thenReturn(federation); - LinkedList eventLogs = new LinkedList<>(); - BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); - BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, fingerrootActivations, eventLogs, signatureCache); - - // Build prev btc tx - BtcTransaction prevTx = new BtcTransaction(btcParams); - TransactionOutput prevOut = new TransactionOutput(btcParams, prevTx, Coin.FIFTY_COINS, federation.getAddress()); - prevTx.addOutput(prevOut); - - // Build btc tx to be signed - BtcTransaction btcTx = new BtcTransaction(btcParams); - btcTx.addInput(prevOut).setScriptSig(createBaseInputScriptThatSpendsFromTheFederation(federation)); - TransactionOutput output = new TransactionOutput(btcParams, btcTx, Coin.COIN, new BtcECKey().toAddress(btcParams)); - btcTx.addOutput(output); - - // Save btc tx to be signed - SortedMap pegoutWaitingForSignatures = new TreeMap<>(); - - final Keccak256 rskTxHash = createHash3(1); - pegoutWaitingForSignatures.put(rskTxHash, btcTx); - when(provider.getPegoutsWaitingForSignatures()) - .thenReturn(pegoutWaitingForSignatures); - - BridgeSupport bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeMainNetConstants) - .withProvider(provider) - .withEventLogger(eventLogger) - .withBtcLockSenderProvider(new BtcLockSenderProvider()) - .withActivations(fingerrootActivations) - .build(); - - BtcECKey privateKeyToSignWith = BtcECKey.fromPrivate(BigInteger.valueOf(150)); - Optional federationMember = federation.getMemberByBtcPublicKey(privateKeyToSignWith); - assertTrue(federationMember.isPresent()); - FederationMember federationMemberToSignWith = federationMember.get(); - BtcECKey federatorBtcPubKey = federationMemberToSignWith.getBtcPublicKey(); - - Script inputScript = btcTx.getInputs().get(0).getScriptSig(); - List chunks = inputScript.getChunks(); - byte[] program = chunks.get(chunks.size() - 1).data; - Script redeemScript = new Script(program); - Sha256Hash sigHash = btcTx.hashForSignature(0, redeemScript, BtcTransaction.SigHash.ALL, false); - BtcECKey.ECDSASignature sig = privateKeyToSignWith.sign(sigHash); - List derEncodedSigs = Collections.singletonList(sig.encodeToDER()); - - // Act - bridgeSupport.addSignature(federationMemberToSignWith.getBtcPublicKey(), derEncodedSigs, rskTxHash.getBytes()); + BtcECKey btcKey = BtcECKey.fromPrivate(BigInteger.valueOf(350)); + ECKey rskKey = ECKey.fromPrivate(BigInteger.valueOf(350 + 1)); + ECKey mstKey = ECKey.fromPrivate(BigInteger.valueOf(350+2)); - // Assert - commonAssertLogs(eventLogs); - assertTopics(3, eventLogs); + FederationMember singleKeyFedMember = new FederationMember( + btcKey, + ECKey.fromPublicOnly(btcKey.getPubKey()), + ECKey.fromPublicOnly(btcKey.getPubKey()) + ); - ECKey federatorECKeyFromBtcPubKey = ECKey.fromPublicOnly(federationMemberToSignWith.getBtcPublicKey().getPubKey()); - String derivedRskAddress = ByteUtil.toHexString(federatorECKeyFromBtcPubKey.getAddress()); + FederationMember multiKeyFedMember = new FederationMember( + btcKey, + rskKey, + mstKey + ); - assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), derivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); + return Stream.of( + Arguments.of(fingerrootActivations, singleKeyFedMember, btcKey, ECKey.fromPublicOnly(singleKeyFedMember.getBtcPublicKey().getPubKey())), + Arguments.of(fingerrootActivations, multiKeyFedMember, btcKey, ECKey.fromPublicOnly(multiKeyFedMember.getBtcPublicKey().getPubKey())), + Arguments.of(arrowheadActivations, singleKeyFedMember, btcKey, singleKeyFedMember.getRskPublicKey()), + Arguments.of(arrowheadActivations, multiKeyFedMember, btcKey, multiKeyFedMember.getRskPublicKey()) + ); } - @Test - void addSignature_afterRSKIP415_should_derived_rskAddress_from_rskPublicKey() throws Exception { + @ParameterizedTest + @MethodSource("addSignatureArgProvider") + void addSignature(ActivationConfig.ForBlock activations, FederationMember federationMemberToSignWith, BtcECKey privateKeyToSignWith, ECKey expectedFederatorPublicKey) throws Exception { // Arrange BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); NetworkParameters btcParams = bridgeMainNetConstants.getBtcParams(); - ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); + List federationMembers = FederationTestUtils.getFederationMembersFromPks(150, 250); + federationMembers.add(federationMemberToSignWith); - List federationMembers = FederationTestUtils.getFederationMembersFromPks(150, 250, 350); Federation federation = new StandardMultisigFederation( federationMembers, Instant.EPOCH, @@ -644,7 +600,7 @@ void addSignature_afterRSKIP415_should_derived_rskAddress_from_rskPublicKey() th .thenReturn(federation); LinkedList eventLogs = new LinkedList<>(); BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); - BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, arrowheadActivations, eventLogs, signatureCache); + BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, activations, eventLogs, signatureCache); // Build prev btc tx BtcTransaction prevTx = new BtcTransaction(btcParams); @@ -670,13 +626,9 @@ void addSignature_afterRSKIP415_should_derived_rskAddress_from_rskPublicKey() th .withProvider(provider) .withEventLogger(eventLogger) .withBtcLockSenderProvider(new BtcLockSenderProvider()) - .withActivations(arrowheadActivations) + .withActivations(activations) .build(); - BtcECKey privateKeyToSignWith = BtcECKey.fromPrivate(BigInteger.valueOf(150)); - Optional federationMember = federation.getMemberByBtcPublicKey(privateKeyToSignWith); - assertTrue(federationMember.isPresent()); - FederationMember federationMemberToSignWith = federationMember.get(); BtcECKey federatorBtcPubKey = federationMemberToSignWith.getBtcPublicKey(); Script inputScript = btcTx.getInputs().get(0).getScriptSig(); @@ -694,8 +646,8 @@ void addSignature_afterRSKIP415_should_derived_rskAddress_from_rskPublicKey() th commonAssertLogs(eventLogs); assertTopics(3, eventLogs); - String derivedRskAddress = ByteUtil.toHexString(federationMemberToSignWith.getRskPublicKey().getAddress()); - assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), derivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); + String expectedDerivedRskAddress = ByteUtil.toHexString(expectedFederatorPublicKey.getAddress()); + assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), expectedDerivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); } private static void assertEvent(List logs, int index, CallTransaction.Function event, Object[] topics, Object[] params) { diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index 106da4e4a59..1c4e112236d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -193,7 +193,8 @@ private static Stream logAddSignatureArgProvider() { ); return Stream.of( - Arguments.of(singleKeyFedMember, multiKeyFedMember) + Arguments.of(singleKeyFedMember), + Arguments.of(multiKeyFedMember) ); } @@ -224,8 +225,13 @@ void logAddSignature_before_rskip415(FederationMember federationMember) { assertTopics(3, eventLogs); ECKey federatorECKeyFromBtcPubKey = ECKey.fromPublicOnly(federationMember.getBtcPublicKey().getPubKey()); - String derivedRskAddress = ByteUtil.toHexString(federatorECKeyFromBtcPubKey.getAddress()); - assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), derivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); + String expectedRskAddress = ByteUtil.toHexString(federatorECKeyFromBtcPubKey.getAddress()); + + CallTransaction.Function bridgeEvent = BridgeEvents.ADD_SIGNATURE.getEvent(); + Object[] eventTopics = new Object[]{rskTxHash.getBytes(), expectedRskAddress}; + Object[] eventParams = new Object[]{federatorBtcPubKey.getPubKey()}; + + assertEvent(eventLogs, 0, bridgeEvent, eventTopics, eventParams); } @ParameterizedTest() @@ -253,8 +259,13 @@ void logAddSignature_after_rskip415(FederationMember federationMember) { commonAssertLogs(eventLogs); assertTopics(3, eventLogs); - String derivedRskAddress = ByteUtil.toHexString(federationMember.getRskPublicKey().getAddress()); - assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), derivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); + String expectedRskAddress = ByteUtil.toHexString(federationMember.getRskPublicKey().getAddress()); + + CallTransaction.Function bridgeEvent = BridgeEvents.ADD_SIGNATURE.getEvent(); + Object[] eventTopics = new Object[]{rskTxHash.getBytes(), expectedRskAddress}; + Object[] eventParams = new Object[]{federatorBtcPubKey.getPubKey()}; + + assertEvent(eventLogs, 0, bridgeEvent, eventTopics, eventParams); } @Test From e52364fd4bf941d25a694c94f0705c651276e93f Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Fri, 2 Feb 2024 10:36:50 -0400 Subject: [PATCH 072/137] Put expected result hardcode for unit tests related to derived rsk address --- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 2 +- .../peg/BridgeSupportAddSignatureTest.java | 23 +++--- .../peg/utils/BridgeEventLoggerImplTest.java | 73 ++++++------------- 3 files changed, 36 insertions(+), 62 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index 70e1fbf0892..3472375b67e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -77,7 +77,7 @@ public void logUpdateCollections(Transaction rskTx) { @Override public void logAddSignature(FederationMember federationMember, BtcTransaction btcTx, byte[] rskTxHash) { - String federatorRskAddress = ByteUtil.toHexString(getFederatorPublicKey(federationMember).getAddress());; + String federatorRskAddress = ByteUtil.toHexString(getFederatorPublicKey(federationMember).getAddress()); logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddress, federationMember.getBtcPublicKey()); } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java index cb29cd1a39a..41ddd7aef87 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportAddSignatureTest.java @@ -11,7 +11,6 @@ import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; -import org.ethereum.util.ByteUtil; import org.ethereum.util.RLP; import org.ethereum.util.RLPList; import org.ethereum.vm.LogInfo; @@ -554,9 +553,12 @@ private static Stream addSignatureArgProvider() { ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); - BtcECKey btcKey = BtcECKey.fromPrivate(BigInteger.valueOf(350)); - ECKey rskKey = ECKey.fromPrivate(BigInteger.valueOf(350 + 1)); - ECKey mstKey = ECKey.fromPrivate(BigInteger.valueOf(350+2)); + BtcECKey btcKey = BtcECKey.fromPrivate(Hex.decode("000000000000000000000000000000000000000000000000000000000000015e")); // 350 + ECKey rskKey = ECKey.fromPrivate(Hex.decode("000000000000000000000000000000000000000000000000000000000000015f")); // 351 + ECKey mstKey = ECKey.fromPrivate(Hex.decode("0000000000000000000000000000000000000000000000000000000000000160")); // 352 + + String addressDerivedFromBtcKey = "dbc29273d4de3d5645e308c7e629d28d4499b3d3"; + String addressDerivedFromRskKey = "74891a05ad4d7ec87c1cffe9bd00bb4e1382b586"; FederationMember singleKeyFedMember = new FederationMember( btcKey, @@ -571,16 +573,16 @@ private static Stream addSignatureArgProvider() { ); return Stream.of( - Arguments.of(fingerrootActivations, singleKeyFedMember, btcKey, ECKey.fromPublicOnly(singleKeyFedMember.getBtcPublicKey().getPubKey())), - Arguments.of(fingerrootActivations, multiKeyFedMember, btcKey, ECKey.fromPublicOnly(multiKeyFedMember.getBtcPublicKey().getPubKey())), - Arguments.of(arrowheadActivations, singleKeyFedMember, btcKey, singleKeyFedMember.getRskPublicKey()), - Arguments.of(arrowheadActivations, multiKeyFedMember, btcKey, multiKeyFedMember.getRskPublicKey()) + Arguments.of(fingerrootActivations, singleKeyFedMember, btcKey, addressDerivedFromBtcKey), + Arguments.of(fingerrootActivations, multiKeyFedMember, btcKey, addressDerivedFromBtcKey), + Arguments.of(arrowheadActivations, singleKeyFedMember, btcKey, addressDerivedFromBtcKey), // Given this is a single key fed member, the rsk address is equal to the one obtained from btc key + Arguments.of(arrowheadActivations, multiKeyFedMember, btcKey, addressDerivedFromRskKey) ); } @ParameterizedTest @MethodSource("addSignatureArgProvider") - void addSignature(ActivationConfig.ForBlock activations, FederationMember federationMemberToSignWith, BtcECKey privateKeyToSignWith, ECKey expectedFederatorPublicKey) throws Exception { + void addSignature(ActivationConfig.ForBlock activations, FederationMember federationMemberToSignWith, BtcECKey privateKeyToSignWith, String expectedRskAddress) throws Exception { // Arrange BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); NetworkParameters btcParams = bridgeMainNetConstants.getBtcParams(); @@ -646,8 +648,7 @@ void addSignature(ActivationConfig.ForBlock activations, FederationMember federa commonAssertLogs(eventLogs); assertTopics(3, eventLogs); - String expectedDerivedRskAddress = ByteUtil.toHexString(expectedFederatorPublicKey.getAddress()); - assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), expectedDerivedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); + assertEvent(eventLogs, 0, BridgeEvents.ADD_SIGNATURE.getEvent(), new Object[]{rskTxHash.getBytes(), expectedRskAddress}, new Object[]{federatorBtcPubKey.getPubKey()}); } private static void assertEvent(List logs, int index, CallTransaction.Function event, Object[] topics, Object[] params) { diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java index 1c4e112236d..9aa61dc3e1d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerImplTest.java @@ -32,7 +32,6 @@ import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; -import org.ethereum.util.ByteUtil; import org.ethereum.vm.LogInfo; import org.ethereum.vm.PrecompiledContracts; import org.junit.jupiter.api.Assertions; @@ -181,68 +180,44 @@ void logUpdateCollections() { } private static Stream logAddSignatureArgProvider() { + ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); + + BtcECKey btcKey = BtcECKey.fromPrivate(Hex.decode("000000000000000000000000000000000000000000000000000000000000015e")); // 350 + ECKey rskKey = ECKey.fromPrivate(Hex.decode("000000000000000000000000000000000000000000000000000000000000015f")); // 351 + ECKey mstKey = ECKey.fromPrivate(Hex.decode("0000000000000000000000000000000000000000000000000000000000000160")); // 352 + + String addressDerivedFromBtcKey = "dbc29273d4de3d5645e308c7e629d28d4499b3d3"; + String addressDerivedFromRskKey = "74891a05ad4d7ec87c1cffe9bd00bb4e1382b586"; + FederationMember singleKeyFedMember = new FederationMember( - BtcECKey.fromPrivate(BigInteger.valueOf(100)), - ECKey.fromPrivate(BigInteger.valueOf(100)), - ECKey.fromPrivate(BigInteger.valueOf(100)) + btcKey, + ECKey.fromPublicOnly(btcKey.getPubKey()), + ECKey.fromPublicOnly(btcKey.getPubKey()) ); + FederationMember multiKeyFedMember = new FederationMember( - BtcECKey.fromPrivate(BigInteger.valueOf(100)), - ECKey.fromPrivate(BigInteger.valueOf(200)), - ECKey.fromPrivate(BigInteger.valueOf(300)) + btcKey, + rskKey, + mstKey ); return Stream.of( - Arguments.of(singleKeyFedMember), - Arguments.of(multiKeyFedMember) + Arguments.of(fingerrootActivations, singleKeyFedMember, addressDerivedFromBtcKey), + Arguments.of(fingerrootActivations, multiKeyFedMember, addressDerivedFromBtcKey), + Arguments.of(arrowheadActivations, singleKeyFedMember, addressDerivedFromBtcKey), // Given this is a single key fed member, the rsk address is equal to the one obtained from btc key + Arguments.of(arrowheadActivations, multiKeyFedMember, addressDerivedFromRskKey) ); } @ParameterizedTest() @MethodSource("logAddSignatureArgProvider") - void logAddSignature_before_rskip415(FederationMember federationMember) { - // Arrange - ActivationConfig.ForBlock fingerrootActivations = ActivationConfigsForTest.fingerroot500().forBlock(0); - BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); - BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); - LinkedList eventLogs = new LinkedList<>(); - BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, fingerrootActivations, eventLogs, signatureCache); - - - BtcECKey federatorBtcPubKey = federationMember.getBtcPublicKey(); - - Keccak256 rskTxHash = PegTestUtils.createHash3(1); - - BtcTransaction btcTxMock = mock(BtcTransaction.class); - when(btcTxMock.getHash()).thenReturn(BitcoinTestUtils.createHash(1)); - when(btcTxMock.getHashAsString()).thenReturn(rskTxHash.toHexString()); - - // Act - eventLogger.logAddSignature(federationMember, btcTxMock, rskTxHash.getBytes()); - - // Assert - commonAssertLogs(eventLogs); - assertTopics(3, eventLogs); - - ECKey federatorECKeyFromBtcPubKey = ECKey.fromPublicOnly(federationMember.getBtcPublicKey().getPubKey()); - String expectedRskAddress = ByteUtil.toHexString(federatorECKeyFromBtcPubKey.getAddress()); - - CallTransaction.Function bridgeEvent = BridgeEvents.ADD_SIGNATURE.getEvent(); - Object[] eventTopics = new Object[]{rskTxHash.getBytes(), expectedRskAddress}; - Object[] eventParams = new Object[]{federatorBtcPubKey.getPubKey()}; - - assertEvent(eventLogs, 0, bridgeEvent, eventTopics, eventParams); - } - - @ParameterizedTest() - @MethodSource("logAddSignatureArgProvider") - void logAddSignature_after_rskip415(FederationMember federationMember) { + void logAddSignature(ActivationConfig.ForBlock activations, FederationMember federationMember, String expectedRskAddress) { // Arrange - ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0); BridgeMainNetConstants bridgeMainNetConstants = BridgeMainNetConstants.getInstance(); BlockTxSignatureCache signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); LinkedList eventLogs = new LinkedList<>(); - BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, arrowheadActivations, eventLogs, signatureCache); + BridgeEventLogger eventLogger = new BridgeEventLoggerImpl(bridgeMainNetConstants, activations, eventLogs, signatureCache); BtcECKey federatorBtcPubKey = federationMember.getBtcPublicKey(); @@ -259,8 +234,6 @@ void logAddSignature_after_rskip415(FederationMember federationMember) { commonAssertLogs(eventLogs); assertTopics(3, eventLogs); - String expectedRskAddress = ByteUtil.toHexString(federationMember.getRskPublicKey().getAddress()); - CallTransaction.Function bridgeEvent = BridgeEvents.ADD_SIGNATURE.getEvent(); Object[] eventTopics = new Object[]{rskTxHash.getBytes(), expectedRskAddress}; Object[] eventParams = new Object[]{federatorBtcPubKey.getPubKey()}; From 21683e6de788bc136b708ceb715dfb908aee0c0e Mon Sep 17 00:00:00 2001 From: Marcos Irisarri <53787863+marcos-iov@users.noreply.github.com> Date: Fri, 2 Feb 2024 13:41:04 -0300 Subject: [PATCH 073/137] Update BridgeEventLoggerImpl.java --- .../src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java index 3472375b67e..cfddb9a2008 100644 --- a/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/utils/BridgeEventLoggerImpl.java @@ -77,7 +77,8 @@ public void logUpdateCollections(Transaction rskTx) { @Override public void logAddSignature(FederationMember federationMember, BtcTransaction btcTx, byte[] rskTxHash) { - String federatorRskAddress = ByteUtil.toHexString(getFederatorPublicKey(federationMember).getAddress()); + ECKey federatorPublicKey = getFederatorPublicKey(federationMember); + String federatorRskAddress = ByteUtil.toHexString(federatorPublicKey.getAddress()); logAddSignatureInSolidityFormat(rskTxHash, federatorRskAddress, federationMember.getBtcPublicKey()); } From b834f08ecfaaa19cc72e32501a3d499744936d58 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Tue, 6 Feb 2024 23:57:56 -0400 Subject: [PATCH 074/137] Fixed misused of activation config passing wrong execution block number. --- .../src/main/java/co/rsk/remasc/Remasc.java | 33 ++++++++++--------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/remasc/Remasc.java b/rskj-core/src/main/java/co/rsk/remasc/Remasc.java index 4ea53fbb837..28b215b2c82 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/Remasc.java +++ b/rskj-core/src/main/java/co/rsk/remasc/Remasc.java @@ -51,7 +51,7 @@ public class Remasc { private static final Logger logger = LoggerFactory.getLogger(Remasc.class); private final Constants constants; - private final ActivationConfig activationConfig; + private final ActivationConfig.ForBlock activations; private final Repository repository; private final BlockStore blockStore; private final RemascConfig remascConstants; @@ -82,7 +82,7 @@ public Remasc( this.provider = new RemascStorageProvider(repository, contractAddress); this.feesPayer = new RemascFeesPayer(repository, contractAddress); this.constants = constants; - this.activationConfig = activationConfig; + this.activations = activationConfig.forBlock(executionBlock.getNumber()); } public void save() { @@ -113,11 +113,11 @@ void processMinersFees() { throw new RemascInvalidInvocationException("Invoked Remasc outside last tx of the block"); } - long blockNbr = executionBlock.getNumber(); + long executionBlockNumber = executionBlock.getNumber(); - long processingBlockNumber = blockNbr - remascConstants.getMaturity(); - if (processingBlockNumber < 1 ) { - logger.debug("First block has not reached maturity yet, current block is {}", blockNbr); + long candidateBlockNumberToReward = executionBlockNumber - remascConstants.getMaturity(); + if (candidateBlockNumberToReward < 1 ) { + logger.debug("First block has not reached maturity yet, current block is {}", executionBlockNumber); return; } @@ -149,20 +149,20 @@ void processMinersFees() { rewardBalance = rewardBalance.add(processingBlockReward); provider.setRewardBalance(rewardBalance); - if (processingBlockNumber - remascConstants.getSyntheticSpan() < 0 ) { + if (candidateBlockNumberToReward - remascConstants.getSyntheticSpan() < 0 ) { logger.debug("First block has not reached maturity+syntheticSpan yet, current block is {}", executionBlock.getNumber()); return; } - List siblings = getSiblingsToReward(descendantsBlocks, processingBlockNumber); + List siblings = getSiblingsToReward(descendantsBlocks, candidateBlockNumberToReward); boolean previousBrokenSelectionRule = provider.getBrokenSelectionRule(); boolean brokenSelectionRule = SelectionRule.isBrokenSelectionRule(processingBlockHeader, siblings); provider.setBrokenSelectionRule(!siblings.isEmpty() && brokenSelectionRule); // Takes from rewardBalance this block's height reward. Coin syntheticReward = rewardBalance.divide(BigInteger.valueOf(remascConstants.getSyntheticSpan())); - boolean isRskip85Enabled = activationConfig.isActive(ConsensusRule.RSKIP85, blockNbr); - if (isRskip85Enabled) { + + if (shouldRewardBeAboveMinimumPayableGas()) { BigInteger minimumPayableGas = constants.getMinimumPayableGas(); Coin minPayableFees = executionBlock.getMinimumGasPrice().multiply(minimumPayableGas); if (syntheticReward.compareTo(minPayableFees) < 0) { @@ -197,22 +197,23 @@ void processMinersFees() { } } + private boolean shouldRewardBeAboveMinimumPayableGas() { + return activations.isActive(ConsensusRule.RSKIP85); + } + RskAddress getRskLabsAddress() { - boolean isRskip218Enabled = activationConfig.isActive(ConsensusRule.RSKIP218, executionBlock.getNumber()); + boolean isRskip218Enabled = activations.isActive(ConsensusRule.RSKIP218); return isRskip218Enabled ? remascConstants.getRskLabsAddressRskip218() : remascConstants.getRskLabsAddress(); } private Coin payToFederation(Constants constants, Block processingBlock, BlockHeader processingBlockHeader, Coin syntheticReward) { - - ActivationConfig.ForBlock activations = activationConfig.forBlock(processingBlock.getNumber()); - BridgeConstants bridgeConstants = constants.getBridgeConstants(); BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( repository, PrecompiledContracts.BRIDGE_ADDR, bridgeConstants, - activations + activations ); FederationSupport federationSupport = new FederationSupport(bridgeConstants, bridgeStorageProvider, processingBlock, activations); @@ -227,7 +228,7 @@ private Coin payToFederation(Constants constants, Block processingBlock, BlockHe Coin payToFederator = payAndRemainderToFederator[0]; Coin restToLastFederator = payAndRemainderToFederator[1]; - if (activations.isActive(ConsensusRule.RSKIP85)) { + if (shouldRewardBeAboveMinimumPayableGas()) { BigInteger minimumFederatorPayableGas = constants.getFederatorMinimumPayableGas(); Coin minPayableFederatorFees = executionBlock.getMinimumGasPrice().multiply(minimumFederatorPayableGas); if (payToFederator.compareTo(minPayableFederatorFees) < 0) { From 76e7a5f39fcdb85f02618bc0210b6d0006a6b9b3 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Wed, 7 Feb 2024 08:38:36 -0400 Subject: [PATCH 075/137] Refactored RemascRskAddressActivationTest --- .../RemascRskAddressActivationTest.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/remasc/RemascRskAddressActivationTest.java b/rskj-core/src/test/java/co/rsk/remasc/RemascRskAddressActivationTest.java index ffbce207cdb..60dde908511 100644 --- a/rskj-core/src/test/java/co/rsk/remasc/RemascRskAddressActivationTest.java +++ b/rskj-core/src/test/java/co/rsk/remasc/RemascRskAddressActivationTest.java @@ -53,31 +53,40 @@ void testActivation() { final RemascConfig remascConfig = spy(new RemascConfigFactory(RemascContract.REMASC_CONFIG) .createRemascConfig("regtest")); - final Remasc remasc = new Remasc(Constants.regtest(), activationConfig, repositoryMock, - blockStoreMock, remascConfig, txMock, PrecompiledContracts.REMASC_ADDR, blockMock, logs); - when(remascConfig.getRskLabsAddress()).thenReturn(rskLabsAddress); when(remascConfig.getRskLabsAddressRskip218()).thenReturn(rskLabsAddressRskip218); - when(activationConfig.isActive(ConsensusRule.RSKIP218, 1)).thenReturn(false); - when(activationConfig.isActive(ConsensusRule.RSKIP218, 2)).thenReturn(true); + ActivationConfig.ForBlock activationsBeforeRSKIP218 = mock(ActivationConfig.ForBlock.class); + when(activationsBeforeRSKIP218.isActive(ConsensusRule.RSKIP218)).thenReturn(false); + + ActivationConfig.ForBlock activationsAfterRSKIP218 = mock(ActivationConfig.ForBlock.class); + when(activationsAfterRSKIP218.isActive(ConsensusRule.RSKIP218)).thenReturn(true); + + when(activationConfig.forBlock(1)).thenReturn(activationsBeforeRSKIP218); + when(activationConfig.forBlock(2)).thenReturn(activationsAfterRSKIP218); when(blockMock.getNumber()).thenReturn(1L); + Remasc remasc = new Remasc(Constants.regtest(), activationConfig, repositoryMock, + blockStoreMock, remascConfig, txMock, PrecompiledContracts.REMASC_ADDR, blockMock, logs); + RskAddress actualAddress = remasc.getRskLabsAddress(); - Assertions.assertEquals(rskLabsAddress, actualAddress); Assertions.assertEquals(1L, blockMock.getNumber()); + Assertions.assertEquals(rskLabsAddress, actualAddress); + Assertions.assertFalse(activationConfig.isActive(ConsensusRule.RSKIP218, blockMock.getNumber())); verify(remascConfig).getRskLabsAddress(); when(blockMock.getNumber()).thenReturn(2L); + remasc = new Remasc(Constants.regtest(), activationConfig, repositoryMock, + blockStoreMock, remascConfig, txMock, PrecompiledContracts.REMASC_ADDR, blockMock, logs); + actualAddress = remasc.getRskLabsAddress(); Assertions.assertEquals(rskLabsAddressRskip218, actualAddress); Assertions.assertEquals(2L, blockMock.getNumber()); - Assertions.assertTrue(activationConfig.isActive(ConsensusRule.RSKIP218, blockMock.getNumber())); verify(remascConfig).getRskLabsAddressRskip218(); } } From f4547e6100bc931150f89702d0f6cf821da65bbc Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Wed, 7 Feb 2024 16:09:20 -0400 Subject: [PATCH 076/137] Added unit tests for processMinersFees method, testing before and after rskip85 --- .../src/main/java/co/rsk/remasc/Remasc.java | 6 +- .../test/java/co/rsk/remasc/RemascTest.java | 164 ++++++++++++++++++ 2 files changed, 167 insertions(+), 3 deletions(-) create mode 100644 rskj-core/src/test/java/co/rsk/remasc/RemascTest.java diff --git a/rskj-core/src/main/java/co/rsk/remasc/Remasc.java b/rskj-core/src/main/java/co/rsk/remasc/Remasc.java index 28b215b2c82..e59291f21d3 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/Remasc.java +++ b/rskj-core/src/main/java/co/rsk/remasc/Remasc.java @@ -180,7 +180,7 @@ void processMinersFees() { Coin payToRskLabs = syntheticReward.divide(BigInteger.valueOf(remascConstants.getRskLabsDivisor())); feesPayer.payMiningFees(processingBlockHeader.getHash().getBytes(), payToRskLabs, rskLabsAddress, logs); syntheticReward = syntheticReward.subtract(payToRskLabs); - Coin payToFederation = payToFederation(constants, processingBlock, processingBlockHeader, syntheticReward); + Coin payToFederation = payToFederation(constants, processingBlock, syntheticReward); syntheticReward = syntheticReward.subtract(payToFederation); if (!siblings.isEmpty()) { @@ -206,7 +206,7 @@ RskAddress getRskLabsAddress() { return isRskip218Enabled ? remascConstants.getRskLabsAddressRskip218() : remascConstants.getRskLabsAddress(); } - private Coin payToFederation(Constants constants, Block processingBlock, BlockHeader processingBlockHeader, Coin syntheticReward) { + private Coin payToFederation(Constants constants, Block processingBlock, Coin syntheticReward) { BridgeConstants bridgeConstants = constants.getBridgeConstants(); BridgeStorageProvider bridgeStorageProvider = new BridgeStorageProvider( @@ -222,7 +222,7 @@ private Coin payToFederation(Constants constants, Block processingBlock, BlockHe Coin federationReward = syntheticReward.divide(BigInteger.valueOf(remascConstants.getFederationDivisor())); Coin payToFederation = provider.getFederationBalance().add(federationReward); - byte[] processingBlockHash = processingBlockHeader.getHash().getBytes(); + byte[] processingBlockHash = processingBlock.getHeader().getHash().getBytes(); int nfederators = federationProvider.getFederationSize(); Coin[] payAndRemainderToFederator = payToFederation.divideAndRemainder(BigInteger.valueOf(nfederators)); Coin payToFederator = payAndRemainderToFederator[0]; diff --git a/rskj-core/src/test/java/co/rsk/remasc/RemascTest.java b/rskj-core/src/test/java/co/rsk/remasc/RemascTest.java new file mode 100644 index 00000000000..60184870ff6 --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/remasc/RemascTest.java @@ -0,0 +1,164 @@ +package co.rsk.remasc; + +import co.rsk.config.RemascConfig; +import co.rsk.config.RemascConfigFactory; +import co.rsk.core.Coin; +import co.rsk.core.RskAddress; +import co.rsk.peg.PegTestUtils; +import org.ethereum.config.Constants; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; +import org.ethereum.core.Block; +import org.ethereum.core.BlockHeader; +import org.ethereum.core.Repository; +import org.ethereum.db.BlockStore; +import org.ethereum.vm.DataWord; +import org.ethereum.vm.LogInfo; +import org.ethereum.vm.PrecompiledContracts; +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.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.when; + +class RemascTest { + + private final static ActivationConfig genesisActivations = ActivationConfigsForTest.genesis(); + private final static ActivationConfig orchidActivations = ActivationConfigsForTest.orchid(); + private final static Constants mainnet = Constants.mainnet(); + private final static Coin minimumGasPrice = Coin.valueOf(100L); + + Repository repository; + BlockStore blockStore; + Block nextBlockToReward; + + private final static RemascConfig remascConfig = new RemascConfigFactory(RemascContract.REMASC_CONFIG).createRemascConfig("main"); + + RemascTransaction executionTx; + + RskAddress remascAddr; + + Block executionBlock; + + BlockHeader blockHeader; + + List logs; + + List blocks; + + DataWord rewardBalanceKey = DataWord.fromString("rewardBalance"); + + @BeforeEach + void setUp() { + repository = mock(Repository.class); + blockStore = mock(BlockStore.class); + nextBlockToReward = mock(Block.class); + long blockNumber = 3992L; + when(nextBlockToReward.getParentHash()).thenReturn(PegTestUtils.createHash3((int) (blockNumber-1))); + when(nextBlockToReward.getHash()).thenReturn(PegTestUtils.createHash3((int) blockNumber)); + when(nextBlockToReward.getNumber()).thenReturn(blockNumber); + when(blockStore.getBlockByHash(nextBlockToReward.getParentHash().getBytes())).thenReturn(nextBlockToReward); + + when(blockStore.getBlockAtDepthStartingAt(anyLong(), any(byte[].class))).thenReturn(nextBlockToReward); + + executionTx = mock(RemascTransaction.class); + + remascAddr = PrecompiledContracts.REMASC_ADDR; + + executionBlock = mock(Block.class); + when(executionBlock.getMinimumGasPrice()).thenReturn(minimumGasPrice); + when(executionBlock.getNumber()).thenReturn(4100L); + when(executionBlock.getHash()).thenReturn(PegTestUtils.createHash3(4100)); + + blockHeader = mock(BlockHeader.class); + when(executionBlock.getHeader()).thenReturn(blockHeader); + when(executionBlock.getParentHash()).thenReturn(PegTestUtils.createHash3(1)); + + logs = new ArrayList<>(); + } + + private void mockBlockStore(Coin feesPerBlock) { + blocks = new ArrayList<>(); + int uncleGenerationLimit = mainnet.getUncleGenerationLimit(); + + for (int i = 0; i < uncleGenerationLimit + 1; i++) { + Block currentBlock = mock(Block.class); + int currentBlockNumber = (int) (nextBlockToReward.getNumber() - i); + when(currentBlock.getParentHash()).thenReturn(PegTestUtils.createHash3(currentBlockNumber - 1)); + when(currentBlock.getHash()).thenReturn(PegTestUtils.createHash3(currentBlockNumber)); + when(currentBlock.getNumber()).thenReturn((long) currentBlockNumber); + + BlockHeader blockHeader = mock(BlockHeader.class); + + when(blockHeader.getPaidFees()).thenReturn(feesPerBlock); + when(blockHeader.getHash()).thenReturn(PegTestUtils.createHash3(currentBlockNumber)); + when(blockHeader.getCoinbase()).thenReturn(PegTestUtils.createRandomRskAddress()); + + when(currentBlock.getHeader()).thenReturn(blockHeader); + + when(blockStore.getBlockByHash(currentBlock.getHash().getBytes())).thenReturn(currentBlock); + blocks.add(currentBlock); + } + } + + private static Stream processMinersFeesArgProvider() { + Coin minimumPayableGas = Coin.valueOf(mainnet.getMinimumPayableGas().longValue()); + Coin minPayableFees = minimumGasPrice.multiply(minimumPayableGas.asBigInteger()); + + Coin equalToMinPayableFees = minPayableFees.multiply(BigInteger.valueOf(remascConfig.getSyntheticSpan())); + Coin belowMinPayableFees = equalToMinPayableFees.subtract(Coin.valueOf(1L)); + + return Stream.of( + Arguments.of(genesisActivations, belowMinPayableFees, true), + Arguments.of(orchidActivations, belowMinPayableFees, false), + Arguments.of(orchidActivations, equalToMinPayableFees, true) + ); + } + + @ParameterizedTest + @MethodSource("processMinersFeesArgProvider") + void test_processMinersFees(ActivationConfig activationConfig, Coin feesPerBlock, boolean success) { + mockBlockStore(feesPerBlock); + + // Arrange + Remasc remasc = new Remasc( + mainnet, + activationConfig, + repository, + blockStore, + remascConfig, + executionTx, + remascAddr, + executionBlock, + logs + ); + + // Act + remasc.processMinersFees(); + remasc.save(); + + // Assert + Coin syntheticReward = feesPerBlock.divide(BigInteger.valueOf(remascConfig.getSyntheticSpan())); + Coin expectedRemascPayment = feesPerBlock.subtract(syntheticReward); + Coin expectedRskLabPayment = syntheticReward.divide(BigInteger.valueOf(remascConfig.getRskLabsDivisor())); + RskAddress iovLabsAddress = remasc.getRskLabsAddress(); + + if (success) { + verify(this.repository, times(1)).addStorageRow(remascAddr, rewardBalanceKey, DataWord.valueOf(expectedRemascPayment.getBytes())); + verify(this.repository, times(1)).addBalance(remascAddr, expectedRskLabPayment.negate()); + verify(this.repository, times(1)).addBalance(iovLabsAddress, expectedRskLabPayment); + } else { + verify(this.repository, times(1)).addStorageRow(remascAddr, rewardBalanceKey, DataWord.valueOf(feesPerBlock.getBytes())); + verify(this.repository, never()).addBalance(any(), any()); + verify(this.repository, never()).addBalance(any(),any()); + } + } +} From 171193ba5dc3dd4041eaf7c9d4e6226a2646577b Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Thu, 8 Feb 2024 23:09:19 -0400 Subject: [PATCH 077/137] - Added RSKIP134 as part of papyrus200 rskips in ActivationConfigsForTest class - Updated tests to consider locking cap RSKIP134 - Removed unused imports. --- ...ridgeStorageProviderPegoutTxIndexTests.java | 18 ++++++++++++++---- ...ridgeSupportRegisterBtcTransactionTest.java | 8 ++++++-- .../java/co/rsk/peg/PowpegMigrationTest.java | 3 +++ .../test/java/co/rsk/remasc/RemascTest.java | 1 - .../upgrades/ActivationConfigsForTest.java | 1 + 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderPegoutTxIndexTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderPegoutTxIndexTests.java index 2f5b725423b..35ae28447b7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderPegoutTxIndexTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderPegoutTxIndexTests.java @@ -18,9 +18,11 @@ import org.mockito.Mockito; import java.io.IOException; +import java.util.Collections; import java.util.stream.Stream; import static co.rsk.peg.BridgeStorageIndexKey.PEGOUT_TX_SIG_HASH; +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP134; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; @@ -285,8 +287,8 @@ void hasPegoutTxSigHash_passing_existing_sigHash() throws IOException { void setPegoutTxSigHash_null(boolean isRskip379HardForkActive) throws IOException { // Arrange ActivationConfig.ForBlock activations = isRskip379HardForkActive ? - ActivationConfigsForTest.arrowhead600().forBlock(0) : - ActivationConfigsForTest.fingerroot500().forBlock(0); + getArrowHeadActivationExceptLockingCap() : + getFingerrootActivationsExceptLockingCap(); Repository repository = mock(Repository.class); @@ -319,8 +321,8 @@ void setPegoutTxSigHash_null(boolean isRskip379HardForkActive) throws IOExceptio void setPegoutTxSigHash_non_null(boolean isRskip379HardForkActive, Sha256Hash sigHash) throws IOException { // Arrange ActivationConfig.ForBlock activations = isRskip379HardForkActive ? - ActivationConfigsForTest.arrowhead600().forBlock(0) : - ActivationConfigsForTest.fingerroot500().forBlock(0); + getArrowHeadActivationExceptLockingCap() : + getFingerrootActivationsExceptLockingCap(); Repository repository = mock(Repository.class); BridgeStorageProvider provider = new BridgeStorageProvider( @@ -360,6 +362,14 @@ void setPegoutTxSigHash_non_null(boolean isRskip379HardForkActive, Sha256Hash si } } + private ActivationConfig.ForBlock getFingerrootActivationsExceptLockingCap() { + return ActivationConfigsForTest.fingerroot500(Collections.singletonList(RSKIP134)).forBlock(0); + } + + private ActivationConfig.ForBlock getArrowHeadActivationExceptLockingCap() { + return ActivationConfigsForTest.arrowhead600(Collections.singletonList(RSKIP134)).forBlock(0); + } + @Test void setPegoutTxSigHash_passing_existing() throws IOException { // Arrange diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java index 143ba162990..a200fe18340 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportRegisterBtcTransactionTest.java @@ -35,6 +35,7 @@ import org.ethereum.core.Block; import org.ethereum.core.BlockTxSignatureCache; import org.ethereum.core.ReceivedTxSignatureCache; +import org.ethereum.core.Repository; import org.ethereum.core.SignatureCache; import org.ethereum.core.Transaction; import org.ethereum.crypto.ECKey; @@ -503,9 +504,14 @@ private PartialMerkleTree createPmtAndMockBlockStore(BtcTransaction btcTransacti } private BridgeSupport buildBridgeSupport(ActivationConfig.ForBlock activations) { + Repository repository = mock(Repository.class); + when(repository.getBalance(PrecompiledContracts.BRIDGE_ADDR)).thenReturn(co.rsk.core.Coin.fromBitcoin(bridgeMainnetConstants.getMaxRbtc())); + when(provider.getLockingCap()).thenReturn(bridgeMainnetConstants.getMaxRbtc()); + return new BridgeSupportBuilder() .withBtcBlockStoreFactory(mockFactory) .withBridgeConstants(bridgeMainnetConstants) + .withRepository(repository) .withProvider(provider) .withActivations(activations) .withSignatureCache(signatureCache) @@ -535,8 +541,6 @@ void registering_btc_transaction_sending_funds_to_unknown_address( btcTransaction.addInput(BitcoinTestUtils.createHash(1), FIRST_OUTPUT_INDEX, ScriptBuilder.createInputScript(null, senderBtcKey)); - - Coin amountToSend = shouldSendAmountBelowMinimum ? belowMinimumPeginTxValue : minimumPeginTxValue; btcTransaction.addOutput(amountToSend, userAddress); diff --git a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java index c682f43c700..972fdb68309 100644 --- a/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/PowpegMigrationTest.java @@ -88,6 +88,9 @@ private void testChangePowpeg( activations ); + repository.addBalance(PrecompiledContracts.BRIDGE_ADDR, co.rsk.core.Coin.fromBitcoin(bridgeConstants.getMaxRbtc())); + bridgeStorageProvider.setLockingCap(bridgeConstants.getMaxRbtc()); + BtcBlockStoreWithCache.Factory btcBlockStoreFactory = new RepositoryBtcBlockStoreWithCache.Factory( bridgeConstants.getBtcParams(), 100, diff --git a/rskj-core/src/test/java/co/rsk/remasc/RemascTest.java b/rskj-core/src/test/java/co/rsk/remasc/RemascTest.java index 60184870ff6..896d2744285 100644 --- a/rskj-core/src/test/java/co/rsk/remasc/RemascTest.java +++ b/rskj-core/src/test/java/co/rsk/remasc/RemascTest.java @@ -16,7 +16,6 @@ import org.ethereum.vm.LogInfo; import org.ethereum.vm.PrecompiledContracts; 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; diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java index 14748d67147..dfaaeeb5889 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java @@ -95,6 +95,7 @@ private static List getTwoToThreeRskips() { private static List getPapyrus200Rskips() { List rskips = new ArrayList<>(); rskips.addAll(Arrays.asList( + ConsensusRule.RSKIP134, ConsensusRule.RSKIP137, ConsensusRule.RSKIP140, ConsensusRule.RSKIP143, From c8d41fe50a4a12c344f48bc5e8f8ccd260ff379b Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Fri, 9 Feb 2024 10:43:14 -0400 Subject: [PATCH 078/137] Refactored tests to remove logic that do not include locking cap rskip in certain tests --- .../co/rsk/peg/BridgeStorageProvider.java | 2 +- ...idgeStorageProviderPegoutTxIndexTests.java | 20 ++++++------------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 256059905fa..cf60e67005c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -956,7 +956,7 @@ public void setPegoutTxSigHash(Sha256Hash sigHash) { pegoutTxSigHashes.add(sigHash); } - private void savePegoutTxSigHashes() { + protected void savePegoutTxSigHashes() { if (!activations.isActive(RSKIP379) || pegoutTxSigHashes == null) { return; } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderPegoutTxIndexTests.java b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderPegoutTxIndexTests.java index 35ae28447b7..668bc9427d5 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderPegoutTxIndexTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeStorageProviderPegoutTxIndexTests.java @@ -287,8 +287,8 @@ void hasPegoutTxSigHash_passing_existing_sigHash() throws IOException { void setPegoutTxSigHash_null(boolean isRskip379HardForkActive) throws IOException { // Arrange ActivationConfig.ForBlock activations = isRskip379HardForkActive ? - getArrowHeadActivationExceptLockingCap() : - getFingerrootActivationsExceptLockingCap(); + ActivationConfigsForTest.arrowhead600().forBlock(0) : + ActivationConfigsForTest.fingerroot500().forBlock(0); Repository repository = mock(Repository.class); @@ -301,7 +301,7 @@ void setPegoutTxSigHash_null(boolean isRskip379HardForkActive) throws IOExceptio // Act provider.setPegoutTxSigHash(null); - provider.save(); + provider.savePegoutTxSigHashes(); // Assert verify(repository, never()).getStorageBytes( @@ -321,8 +321,8 @@ void setPegoutTxSigHash_null(boolean isRskip379HardForkActive) throws IOExceptio void setPegoutTxSigHash_non_null(boolean isRskip379HardForkActive, Sha256Hash sigHash) throws IOException { // Arrange ActivationConfig.ForBlock activations = isRskip379HardForkActive ? - getArrowHeadActivationExceptLockingCap() : - getFingerrootActivationsExceptLockingCap(); + ActivationConfigsForTest.arrowhead600().forBlock(0) : + ActivationConfigsForTest.fingerroot500().forBlock(0); Repository repository = mock(Repository.class); BridgeStorageProvider provider = new BridgeStorageProvider( @@ -334,7 +334,7 @@ void setPegoutTxSigHash_non_null(boolean isRskip379HardForkActive, Sha256Hash si // Act provider.setPegoutTxSigHash(sigHash); - provider.save(); + provider.savePegoutTxSigHashes(); // Assert if (isRskip379HardForkActive) { @@ -362,14 +362,6 @@ void setPegoutTxSigHash_non_null(boolean isRskip379HardForkActive, Sha256Hash si } } - private ActivationConfig.ForBlock getFingerrootActivationsExceptLockingCap() { - return ActivationConfigsForTest.fingerroot500(Collections.singletonList(RSKIP134)).forBlock(0); - } - - private ActivationConfig.ForBlock getArrowHeadActivationExceptLockingCap() { - return ActivationConfigsForTest.arrowhead600(Collections.singletonList(RSKIP134)).forBlock(0); - } - @Test void setPegoutTxSigHash_passing_existing() throws IOException { // Arrange From 5c459e4f8865b6eb037f908bf44af1295f3d4b1e Mon Sep 17 00:00:00 2001 From: Volodymyr Kravets Date: Thu, 11 Jan 2024 18:41:21 +0200 Subject: [PATCH 079/137] Added msg type propagation to precompiled contracts --- .../java/org/ethereum/vm/PrecompiledContractArgs.java | 10 ++++++++++ .../ethereum/vm/PrecompiledContractArgsBuilder.java | 10 ++++++++++ .../src/main/java/org/ethereum/vm/program/Program.java | 1 + 3 files changed, 21 insertions(+) diff --git a/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgs.java b/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgs.java index ccbd160bc9e..7e4b50ce9be 100644 --- a/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgs.java +++ b/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgs.java @@ -45,6 +45,8 @@ public class PrecompiledContractArgs { @Nullable private ProgramInvoke programInvoke; + private MessageCall.MsgType msgType; + public PrecompiledContractArgs() { } @@ -76,6 +78,10 @@ void setProgramInvoke(ProgramInvoke programInvoke) { this.programInvoke = programInvoke; } + public void setMsgType(MessageCall.MsgType msgType) { + this.msgType = msgType; + } + public Transaction getTransaction() { return transaction; } @@ -103,4 +109,8 @@ public List getLogs() { public ProgramInvoke getProgramInvoke() { return programInvoke; } + + public MessageCall.MsgType getMsgType() { + return msgType; + } } diff --git a/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgsBuilder.java b/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgsBuilder.java index 75d41347eb6..0d9abffd6c5 100644 --- a/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgsBuilder.java +++ b/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgsBuilder.java @@ -25,7 +25,9 @@ import org.ethereum.db.ReceiptStore; import org.ethereum.vm.program.invoke.ProgramInvoke; +import javax.annotation.Nonnull; import java.util.List; +import java.util.Objects; public class PrecompiledContractArgsBuilder { private Transaction transaction; @@ -36,6 +38,8 @@ public class PrecompiledContractArgsBuilder { private List logs; private ProgramInvoke programInvoke; + private MessageCall.MsgType msgType = MessageCall.MsgType.CALL; + private PrecompiledContractArgsBuilder() {} public static PrecompiledContractArgsBuilder builder() { @@ -77,6 +81,11 @@ public PrecompiledContractArgsBuilder programInvoke(ProgramInvoke programInvoke) return this; } + public PrecompiledContractArgsBuilder msgType(@Nonnull MessageCall.MsgType msgType) { + this.msgType = Objects.requireNonNull(msgType); + return this; + } + public PrecompiledContractArgs build() { PrecompiledContractArgs args = new PrecompiledContractArgs(); args.setTransaction(this.transaction); @@ -86,6 +95,7 @@ public PrecompiledContractArgs build() { args.setReceiptStore(this.receiptStore); args.setLogs(this.logs); args.setProgramInvoke(this.programInvoke); + args.setMsgType(this.msgType); return args; } diff --git a/rskj-core/src/main/java/org/ethereum/vm/program/Program.java b/rskj-core/src/main/java/org/ethereum/vm/program/Program.java index 2effc052c13..5a799524d32 100644 --- a/rskj-core/src/main/java/org/ethereum/vm/program/Program.java +++ b/rskj-core/src/main/java/org/ethereum/vm/program/Program.java @@ -1422,6 +1422,7 @@ public void callToPrecompiledAddress(MessageCall msg, PrecompiledContract contra .blockStore(this.invoke.getBlockStore()) .logs(result.getLogInfoList()) .programInvoke(this.invoke) + .msgType(msg.getType()) .build(); contract.init(args); From ccaac4109f53416dad741ed251ff924826bd4793 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Dahlquist?= Date: Fri, 12 Jan 2024 11:57:45 -0300 Subject: [PATCH 080/137] WIP Bridge message type check - Use propagated message type from Program in Bridge - Add verification per Bridge method about the acceptedt message type - Include check in Bridge execution to avoid executing method with restricted message type This is a WIP and not ready for production yet. --- .../src/main/java/co/rsk/peg/Bridge.java | 13 ++ .../main/java/co/rsk/peg/BridgeMethods.java | 117 +++++++++++++----- .../blockchain/upgrades/ConsensusRule.java | 1 + 3 files changed, 99 insertions(+), 32 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 30b3030fead..a8566df7680 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -17,6 +17,8 @@ */ package co.rsk.peg; +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP_ARROWHEAD; + import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.store.BlockStoreException; @@ -37,6 +39,7 @@ import org.ethereum.core.*; import org.ethereum.util.ByteUtil; import org.ethereum.vm.DataWord; +import org.ethereum.vm.MessageCall.MsgType; import org.ethereum.vm.PrecompiledContractArgs; import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.exception.VMException; @@ -223,6 +226,7 @@ public class Bridge extends PrecompiledContracts.PrecompiledContract { private final BiFunction, Integer, MerkleBranch> merkleBranchFactory; private final SignatureCache signatureCache; + private MsgType msgType; public Bridge(RskAddress contractAddress, Constants constants, ActivationConfig activationConfig, BridgeSupportFactory bridgeSupportFactory, SignatureCache signatureCache) { @@ -316,6 +320,7 @@ public void init(PrecompiledContractArgs args) { Block rskExecutionBlock = args.getExecutionBlock(); this.activations = activationConfig.forBlock(rskExecutionBlock.getNumber()); this.rskTx = args.getTransaction(); + this.msgType = args.getMsgType(); this.bridgeSupport = bridgeSupportFactory.newInstance( args.getRepository(), @@ -361,6 +366,14 @@ public byte[] execute(byte[] data) throws VMException { throw new BridgeIllegalArgumentException(errorMessage); } + if (activations.isActive(RSKIP_ARROWHEAD) && + !bridgeParsedData.bridgeMethod.acceptsThisTypeOfCall(this.activations, this.msgType)) { + String errorMessage = String.format("Call type (%s) not accepted by %s. Returning without execution.", this.msgType.name(), bridgeParsedData.bridgeMethod.getFunction().name); + logger.info(errorMessage); + // TODO: determine which type of exception makes sense for this case + throw new BridgeIllegalArgumentException(errorMessage); + } + Optional result; try { // bridgeParsedData.function should be one of the CallTransaction.Function declared above. diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index dfbeb4923ac..598a86eea22 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -17,7 +17,10 @@ */ package co.rsk.peg; +import java.util.function.BiFunction; import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.CallTransaction; import org.ethereum.db.ByteArrayWrapper; @@ -26,6 +29,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.ethereum.vm.MessageCall.MsgType; import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; @@ -34,26 +38,28 @@ */ public enum BridgeMethods { ADD_FEDERATOR_PUBLIC_KEY( - CallTransaction.Function.fromSignature( - "addFederatorPublicKey", - new String[]{"bytes"}, - new String[]{"int256"} - ), - fixedCost(13000L), - (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKey, - activations -> !activations.isActive(RSKIP123), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "addFederatorPublicKey", + new String[]{"bytes"}, + new String[]{"int256"} + ), + fixedCost(13000L), + (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKey, + activations -> !activations.isActive(RSKIP123), + fixedPermission(false), + CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY( - CallTransaction.Function.fromSignature( - "addFederatorPublicKeyMultikey", - new String[]{"bytes", "bytes", "bytes"}, - new String[]{"int256"} - ), - fixedCost(13000L), - (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKeyMultikey, - activations -> activations.isActive(RSKIP123), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "addFederatorPublicKeyMultikey", + new String[]{"bytes", "bytes", "bytes"}, + new String[]{"int256"} + ), + fixedCost(13000L), + (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKeyMultikey, + activations -> activations.isActive(RSKIP123), + fixedPermission(false), + CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), ADD_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -64,7 +70,8 @@ public enum BridgeMethods { fixedCost(25000L), (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, activations -> !activations.isActive(RSKIP87), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -75,7 +82,8 @@ public enum BridgeMethods { fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, activations -> activations.isActive(RSKIP87), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -86,7 +94,8 @@ public enum BridgeMethods { fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS (BridgeMethodExecutorTyped) Bridge::addUnlimitedLockWhitelistAddress, activations -> activations.isActive(RSKIP87), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), ADD_SIGNATURE( CallTransaction.Function.fromSignature( @@ -96,7 +105,8 @@ public enum BridgeMethods { ), fixedCost(70000L), Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::addSignature, "addSignature"), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), COMMIT_FEDERATION( CallTransaction.Function.fromSignature( @@ -106,7 +116,8 @@ public enum BridgeMethods { ), fixedCost(38000L), (BridgeMethodExecutorTyped) Bridge::commitFederation, - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), CREATE_FEDERATION( CallTransaction.Function.fromSignature( @@ -116,7 +127,8 @@ public enum BridgeMethods { ), fixedCost(11000L), (BridgeMethodExecutorTyped) Bridge::createFederation, - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT( CallTransaction.Function.fromSignature( @@ -137,7 +149,8 @@ public enum BridgeMethods { fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainInitialBlockHeight, activations -> activations.isActive(RSKIP89), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.UNRESTRICTED_METHOD ), GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR( CallTransaction.Function.fromSignature( @@ -148,7 +161,8 @@ public enum BridgeMethods { fixedCost(76000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockLocator, activations -> !activations.isActive(RSKIP89), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.UNRESTRICTED_METHOD ), GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH( CallTransaction.Function.fromSignature( @@ -159,7 +173,8 @@ public enum BridgeMethods { fixedCost(20000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHashAtDepth, activations -> activations.isActive(RSKIP89), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.UNRESTRICTED_METHOD ), GET_BTC_TRANSACTION_CONFIRMATIONS( CallTransaction.Function.fromSignature( @@ -170,7 +185,8 @@ public enum BridgeMethods { fromMethod(Bridge::getBtcTransactionConfirmationsGetCost), (BridgeMethodExecutorTyped) Bridge::getBtcTransactionConfirmations, activations -> activations.isActive(RSKIP122), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.UNRESTRICTED_METHOD ), GET_BTC_TX_HASH_PROCESSED_HEIGHT( CallTransaction.Function.fromSignature( @@ -180,7 +196,8 @@ public enum BridgeMethods { ), fixedCost(22000L), (BridgeMethodExecutorTyped) Bridge::getBtcTxHashProcessedHeight, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.UNRESTRICTED_METHOD ), GET_FEDERATION_ADDRESS( CallTransaction.Function.fromSignature( @@ -700,14 +717,24 @@ public enum BridgeMethods { fixedCost(10_000L), (BridgeMethodExecutorTyped) Bridge::getEstimatedFeesForNextPegOutEvent, activations -> activations.isActive(RSKIP271), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.UNRESTRICTED_METHOD ); + private static class CallTypeHelper { + private static final Function UNRESTRICTED_METHOD = + (callType) -> callType == MsgType.CALL || callType == MsgType.STATICCALL; + private static final Function RESTRICTED_TO_CALL_METHOD = (callType) -> callType == MsgType.CALL; + } + + + private final CallTransaction.Function function; private final CostProvider costProvider; private final Function isEnabledFunction; private final BridgeMethodExecutor executor; private final BridgeCallPermissionProvider callPermissionProvider; + private final Function callTypeVerifier; BridgeMethods( CallTransaction.Function function, @@ -715,7 +742,17 @@ public enum BridgeMethods { BridgeMethodExecutor executor, BridgeCallPermissionProvider callPermissionProvider) { - this(function, costProvider, executor, activations -> Boolean.TRUE, callPermissionProvider); + this(function, costProvider, executor, activations -> Boolean.TRUE, callPermissionProvider, CallTypeHelper.RESTRICTED_TO_CALL_METHOD); + } + + BridgeMethods( + CallTransaction.Function function, + CostProvider costProvider, + BridgeMethodExecutor executor, + BridgeCallPermissionProvider callPermissionProvider, + Function callTypeVerifier) { + + this(function, costProvider, executor, activations -> Boolean.TRUE, callPermissionProvider, callTypeVerifier); } BridgeMethods( @@ -723,13 +760,25 @@ public enum BridgeMethods { CostProvider costProvider, BridgeMethodExecutor executor, Function isEnabled, - BridgeCallPermissionProvider callPermissionProvider) { + BridgeCallPermissionProvider callPermissionProvider, + Function callTypeVerifier) { this.function = function; this.costProvider = costProvider; this.executor = executor; this.isEnabledFunction = isEnabled; this.callPermissionProvider = callPermissionProvider; + this.callTypeVerifier = callTypeVerifier; + } + + BridgeMethods( + CallTransaction.Function function, + CostProvider costProvider, + BridgeMethodExecutor executor, + Function isEnabled, + BridgeCallPermissionProvider callPermissionProvider) { + + this(function, costProvider, executor, isEnabled, callPermissionProvider, CallTypeHelper.RESTRICTED_TO_CALL_METHOD); } public static Optional findBySignature(byte[] encoding) { @@ -756,6 +805,10 @@ public boolean onlyAllowsLocalCalls(Bridge bridge, Object[] args) { return callPermissionProvider.getOnlyAllowLocalCallsPermission(bridge, args); } + public boolean acceptsThisTypeOfCall(MsgType callType) { + return callTypeVerifier.apply(callType); + } + public interface BridgeCondition { boolean isTrue(Bridge bridge); } diff --git a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java index 9ce0be35761..9b7b37315d0 100644 --- a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java +++ b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java @@ -92,6 +92,7 @@ public enum ConsensusRule { RSKIP400("rskip400"), // From EIP-2028 calldata gas cost reduction RSKIP412("rskip412"), // From EIP-3198 BASEFEE opcode RSKIP415("rskip415"), + RSKIP_ARROWHEAD("RSKIP_ARROWHEAD"), // TODO: define what activation we will be using for the bridge patch ; private String configKey; From f17bc41fcb987d701f0b1d73cb9bf6d6dc6e54e3 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 12:08:14 -0300 Subject: [PATCH 081/137] Refactor CallTypeHelper to use a Predicate instead of Function --- .../main/java/co/rsk/peg/BridgeMethods.java | 80 +++++++++++-------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 598a86eea22..42b168e134c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -17,10 +17,8 @@ */ package co.rsk.peg; -import java.util.function.BiFunction; +import java.util.function.Predicate; import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.CallTransaction; import org.ethereum.db.ByteArrayWrapper; @@ -39,9 +37,9 @@ public enum BridgeMethods { ADD_FEDERATOR_PUBLIC_KEY( CallTransaction.Function.fromSignature( - "addFederatorPublicKey", - new String[]{"bytes"}, - new String[]{"int256"} + "addFederatorPublicKey", + new String[]{"bytes"}, + new String[]{"int256"} ), fixedCost(13000L), (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKey, @@ -98,14 +96,14 @@ public enum BridgeMethods { CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), ADD_SIGNATURE( - CallTransaction.Function.fromSignature( - "addSignature", - new String[]{"bytes", "bytes[]", "bytes"}, - new String[]{} - ), - fixedCost(70000L), - Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::addSignature, "addSignature"), - fixedPermission(false), + CallTransaction.Function.fromSignature( + "addSignature", + new String[]{"bytes", "bytes[]", "bytes"}, + new String[]{} + ), + fixedCost(70000L), + Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::addSignature, "addSignature"), + fixedPermission(false), CallTypeHelper.RESTRICTED_TO_CALL_METHOD ), COMMIT_FEDERATION( @@ -722,19 +720,17 @@ public enum BridgeMethods { ); private static class CallTypeHelper { - private static final Function UNRESTRICTED_METHOD = - (callType) -> callType == MsgType.CALL || callType == MsgType.STATICCALL; - private static final Function RESTRICTED_TO_CALL_METHOD = (callType) -> callType == MsgType.CALL; + private static final Predicate UNRESTRICTED_METHOD = callType -> + callType == MsgType.CALL || callType == MsgType.STATICCALL; + private static final Predicate RESTRICTED_TO_CALL_METHOD = callType -> callType == MsgType.CALL; } - - private final CallTransaction.Function function; private final CostProvider costProvider; private final Function isEnabledFunction; private final BridgeMethodExecutor executor; private final BridgeCallPermissionProvider callPermissionProvider; - private final Function callTypeVerifier; + private final Predicate callTypeVerifier; BridgeMethods( CallTransaction.Function function, @@ -742,7 +738,14 @@ private static class CallTypeHelper { BridgeMethodExecutor executor, BridgeCallPermissionProvider callPermissionProvider) { - this(function, costProvider, executor, activations -> Boolean.TRUE, callPermissionProvider, CallTypeHelper.RESTRICTED_TO_CALL_METHOD); + this( + function, + costProvider, + executor, + activations -> Boolean.TRUE, + callPermissionProvider, + CallTypeHelper.RESTRICTED_TO_CALL_METHOD + ); } BridgeMethods( @@ -750,9 +753,16 @@ private static class CallTypeHelper { CostProvider costProvider, BridgeMethodExecutor executor, BridgeCallPermissionProvider callPermissionProvider, - Function callTypeVerifier) { - - this(function, costProvider, executor, activations -> Boolean.TRUE, callPermissionProvider, callTypeVerifier); + Predicate callTypeVerifier) { + + this( + function, + costProvider, + executor, + activations -> Boolean.TRUE, + callPermissionProvider, + callTypeVerifier + ); } BridgeMethods( @@ -761,7 +771,7 @@ private static class CallTypeHelper { BridgeMethodExecutor executor, Function isEnabled, BridgeCallPermissionProvider callPermissionProvider, - Function callTypeVerifier) { + Predicate callTypeVerifier) { this.function = function; this.costProvider = costProvider; @@ -778,7 +788,14 @@ private static class CallTypeHelper { Function isEnabled, BridgeCallPermissionProvider callPermissionProvider) { - this(function, costProvider, executor, isEnabled, callPermissionProvider, CallTypeHelper.RESTRICTED_TO_CALL_METHOD); + this( + function, + costProvider, + executor, + isEnabled, + callPermissionProvider, + CallTypeHelper.RESTRICTED_TO_CALL_METHOD + ); } public static Optional findBySignature(byte[] encoding) { @@ -806,7 +823,7 @@ public boolean onlyAllowsLocalCalls(Bridge bridge, Object[] args) { } public boolean acceptsThisTypeOfCall(MsgType callType) { - return callTypeVerifier.apply(callType); + return callTypeVerifier.test(callType); } public interface BridgeCondition { @@ -865,9 +882,8 @@ private static BridgeCallPermissionProvider fromMethod(BridgeCallPermissionProvi } private static final Map SIGNATURES = Stream.of(BridgeMethods.values()) - .collect(Collectors.toMap( - m -> new ByteArrayWrapper(m.getFunction().encodeSignature()), - Function.identity() - )); - + .collect(Collectors.toMap( + m -> new ByteArrayWrapper(m.getFunction().encodeSignature()), + Function.identity() + )); } From 60c7e5cf12919a72f04e6b0658cf9e1b3fe28a0a Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 12:10:36 -0300 Subject: [PATCH 082/137] Rename CallTypeHelper predicates --- .../main/java/co/rsk/peg/BridgeMethods.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 42b168e134c..86728dac809 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -45,7 +45,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKey, activations -> !activations.isActive(RSKIP123), fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ), ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY( CallTransaction.Function.fromSignature( @@ -57,7 +57,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKeyMultikey, activations -> activations.isActive(RSKIP123), fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ), ADD_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -69,7 +69,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, activations -> !activations.isActive(RSKIP87), fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ), ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -81,7 +81,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, activations -> activations.isActive(RSKIP87), fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ), ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -93,7 +93,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::addUnlimitedLockWhitelistAddress, activations -> activations.isActive(RSKIP87), fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ), ADD_SIGNATURE( CallTransaction.Function.fromSignature( @@ -104,7 +104,7 @@ public enum BridgeMethods { fixedCost(70000L), Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::addSignature, "addSignature"), fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ), COMMIT_FEDERATION( CallTransaction.Function.fromSignature( @@ -115,7 +115,7 @@ public enum BridgeMethods { fixedCost(38000L), (BridgeMethodExecutorTyped) Bridge::commitFederation, fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ), CREATE_FEDERATION( CallTransaction.Function.fromSignature( @@ -126,7 +126,7 @@ public enum BridgeMethods { fixedCost(11000L), (BridgeMethodExecutorTyped) Bridge::createFederation, fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ), GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT( CallTransaction.Function.fromSignature( @@ -148,7 +148,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainInitialBlockHeight, activations -> activations.isActive(RSKIP89), fixedPermission(true), - CallTypeHelper.UNRESTRICTED_METHOD + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR( CallTransaction.Function.fromSignature( @@ -160,7 +160,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockLocator, activations -> !activations.isActive(RSKIP89), fixedPermission(true), - CallTypeHelper.UNRESTRICTED_METHOD + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH( CallTransaction.Function.fromSignature( @@ -172,7 +172,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHashAtDepth, activations -> activations.isActive(RSKIP89), fixedPermission(true), - CallTypeHelper.UNRESTRICTED_METHOD + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_TRANSACTION_CONFIRMATIONS( CallTransaction.Function.fromSignature( @@ -184,7 +184,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBtcTransactionConfirmations, activations -> activations.isActive(RSKIP122), fixedPermission(false), - CallTypeHelper.UNRESTRICTED_METHOD + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_TX_HASH_PROCESSED_HEIGHT( CallTransaction.Function.fromSignature( @@ -195,7 +195,7 @@ public enum BridgeMethods { fixedCost(22000L), (BridgeMethodExecutorTyped) Bridge::getBtcTxHashProcessedHeight, fixedPermission(true), - CallTypeHelper.UNRESTRICTED_METHOD + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_ADDRESS( CallTransaction.Function.fromSignature( @@ -716,13 +716,13 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getEstimatedFeesForNextPegOutEvent, activations -> activations.isActive(RSKIP271), fixedPermission(false), - CallTypeHelper.UNRESTRICTED_METHOD + CallTypeHelper.ALLOW_STATIC_CALL ); private static class CallTypeHelper { - private static final Predicate UNRESTRICTED_METHOD = callType -> + private static final Predicate ALLOW_STATIC_CALL = callType -> callType == MsgType.CALL || callType == MsgType.STATICCALL; - private static final Predicate RESTRICTED_TO_CALL_METHOD = callType -> callType == MsgType.CALL; + private static final Predicate RESTRICTED_TO_CALL = callType -> callType == MsgType.CALL; } private final CallTransaction.Function function; @@ -744,7 +744,7 @@ private static class CallTypeHelper { executor, activations -> Boolean.TRUE, callPermissionProvider, - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ); } @@ -794,7 +794,7 @@ private static class CallTypeHelper { executor, isEnabled, callPermissionProvider, - CallTypeHelper.RESTRICTED_TO_CALL_METHOD + CallTypeHelper.RESTRICTED_TO_CALL ); } From 6ac2e41cb2aa566b48b8ae810cd0985e270ee33f Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 12:25:58 -0300 Subject: [PATCH 083/137] Allow static calls to getter methods --- .../main/java/co/rsk/peg/BridgeMethods.java | 158 +++++++++++------- 1 file changed, 93 insertions(+), 65 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 86728dac809..d69de5810e1 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -17,20 +17,19 @@ */ package co.rsk.peg; -import java.util.function.Predicate; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.core.CallTransaction; -import org.ethereum.db.ByteArrayWrapper; +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; import java.util.Map; import java.util.Optional; import java.util.function.Function; +import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.core.CallTransaction; +import org.ethereum.db.ByteArrayWrapper; import org.ethereum.vm.MessageCall.MsgType; -import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; - /** * This enum holds the basic information of the Bridge contract methods: the ABI, the cost and the implementation. */ @@ -44,8 +43,7 @@ public enum BridgeMethods { fixedCost(13000L), (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKey, activations -> !activations.isActive(RSKIP123), - fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL + fixedPermission(false) ), ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY( CallTransaction.Function.fromSignature( @@ -56,8 +54,7 @@ public enum BridgeMethods { fixedCost(13000L), (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKeyMultikey, activations -> activations.isActive(RSKIP123), - fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL + fixedPermission(false) ), ADD_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -68,8 +65,7 @@ public enum BridgeMethods { fixedCost(25000L), (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, activations -> !activations.isActive(RSKIP87), - fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL + fixedPermission(false) ), ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -80,8 +76,7 @@ public enum BridgeMethods { fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, activations -> activations.isActive(RSKIP87), - fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL + fixedPermission(false) ), ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -92,8 +87,7 @@ public enum BridgeMethods { fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS (BridgeMethodExecutorTyped) Bridge::addUnlimitedLockWhitelistAddress, activations -> activations.isActive(RSKIP87), - fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL + fixedPermission(false) ), ADD_SIGNATURE( CallTransaction.Function.fromSignature( @@ -103,8 +97,7 @@ public enum BridgeMethods { ), fixedCost(70000L), Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::addSignature, "addSignature"), - fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL + fixedPermission(false) ), COMMIT_FEDERATION( CallTransaction.Function.fromSignature( @@ -114,8 +107,7 @@ public enum BridgeMethods { ), fixedCost(38000L), (BridgeMethodExecutorTyped) Bridge::commitFederation, - fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL + fixedPermission(false) ), CREATE_FEDERATION( CallTransaction.Function.fromSignature( @@ -125,8 +117,7 @@ public enum BridgeMethods { ), fixedCost(11000L), (BridgeMethodExecutorTyped) Bridge::createFederation, - fixedPermission(false), - CallTypeHelper.RESTRICTED_TO_CALL + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT( CallTransaction.Function.fromSignature( @@ -136,7 +127,8 @@ public enum BridgeMethods { ), fixedCost(19000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestChainHeight, - fromMethod(Bridge::getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls) + fromMethod(Bridge::getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT( CallTransaction.Function.fromSignature( @@ -148,7 +140,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainInitialBlockHeight, activations -> activations.isActive(RSKIP89), fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR( CallTransaction.Function.fromSignature( @@ -160,7 +152,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockLocator, activations -> !activations.isActive(RSKIP89), fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH( CallTransaction.Function.fromSignature( @@ -172,7 +164,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHashAtDepth, activations -> activations.isActive(RSKIP89), fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_TRANSACTION_CONFIRMATIONS( CallTransaction.Function.fromSignature( @@ -184,7 +176,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getBtcTransactionConfirmations, activations -> activations.isActive(RSKIP122), fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_TX_HASH_PROCESSED_HEIGHT( CallTransaction.Function.fromSignature( @@ -195,7 +187,7 @@ public enum BridgeMethods { fixedCost(22000L), (BridgeMethodExecutorTyped) Bridge::getBtcTxHashProcessedHeight, fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_ADDRESS( CallTransaction.Function.fromSignature( @@ -205,7 +197,8 @@ public enum BridgeMethods { ), fixedCost(11000L), (BridgeMethodExecutorTyped) Bridge::getFederationAddress, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_CREATION_BLOCK_NUMBER( CallTransaction.Function.fromSignature( @@ -215,7 +208,8 @@ public enum BridgeMethods { ), fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederationCreationBlockNumber, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_CREATION_TIME( CallTransaction.Function.fromSignature( @@ -225,7 +219,8 @@ public enum BridgeMethods { ), fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederationCreationTime, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_SIZE( CallTransaction.Function.fromSignature( @@ -235,7 +230,8 @@ public enum BridgeMethods { ), fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederationSize, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_THRESHOLD( CallTransaction.Function.fromSignature( @@ -245,7 +241,8 @@ public enum BridgeMethods { ), fixedCost(11000L), (BridgeMethodExecutorTyped) Bridge::getFederationThreshold, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATOR_PUBLIC_KEY( CallTransaction.Function.fromSignature( @@ -256,7 +253,8 @@ public enum BridgeMethods { fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederatorPublicKey, activations -> !activations.isActive(RSKIP123), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATOR_PUBLIC_KEY_OF_TYPE( CallTransaction.Function.fromSignature( @@ -267,7 +265,8 @@ public enum BridgeMethods { fixedCost(10000L), (BridgeMethodExecutorTyped) Bridge::getFederatorPublicKeyOfType, activations -> activations.isActive(RSKIP123), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEE_PER_KB( CallTransaction.Function.fromSignature( @@ -277,7 +276,8 @@ public enum BridgeMethods { ), fixedCost(2000L), (BridgeMethodExecutorTyped) Bridge::getFeePerKb, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( @@ -287,7 +287,8 @@ public enum BridgeMethods { ), fixedCost(16000L), (BridgeMethodExecutorTyped) Bridge::getLockWhitelistAddress, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_LOCK_WHITELIST_ENTRY_BY_ADDRESS( CallTransaction.Function.fromSignature( @@ -298,7 +299,8 @@ public enum BridgeMethods { fixedCost(16000L), (BridgeMethodExecutorTyped) Bridge::getLockWhitelistEntryByAddress, activations -> activations.isActive(RSKIP87), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_LOCK_WHITELIST_SIZE( CallTransaction.Function.fromSignature( @@ -308,7 +310,8 @@ public enum BridgeMethods { ), fixedCost(16000L), (BridgeMethodExecutorTyped) Bridge::getLockWhitelistSize, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_MINIMUM_LOCK_TX_VALUE( CallTransaction.Function.fromSignature( @@ -318,7 +321,8 @@ public enum BridgeMethods { ), fixedCost(2000L), (BridgeMethodExecutorTyped) Bridge::getMinimumLockTxValue, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATION_HASH( CallTransaction.Function.fromSignature( @@ -328,7 +332,8 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getPendingFederationHash, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATION_SIZE( CallTransaction.Function.fromSignature( @@ -338,7 +343,8 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getPendingFederationSize, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATOR_PUBLIC_KEY( CallTransaction.Function.fromSignature( @@ -349,7 +355,8 @@ public enum BridgeMethods { fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getPendingFederatorPublicKey, activations -> !activations.isActive(RSKIP123), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATOR_PUBLIC_KEY_OF_TYPE( CallTransaction.Function.fromSignature( @@ -360,7 +367,8 @@ public enum BridgeMethods { fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getPendingFederatorPublicKeyOfType, activations -> activations.isActive(RSKIP123), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_ADDRESS( CallTransaction.Function.fromSignature( @@ -370,7 +378,8 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationAddress, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_CREATION_BLOCK_NUMBER( CallTransaction.Function.fromSignature( @@ -380,7 +389,8 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationCreationBlockNumber, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_CREATION_TIME( CallTransaction.Function.fromSignature( @@ -390,7 +400,8 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationCreationTime, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_SIZE( CallTransaction.Function.fromSignature( @@ -400,7 +411,8 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationSize, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_THRESHOLD( CallTransaction.Function.fromSignature( @@ -410,7 +422,8 @@ public enum BridgeMethods { ), fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederationThreshold, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATOR_PUBLIC_KEY( CallTransaction.Function.fromSignature( @@ -421,7 +434,8 @@ public enum BridgeMethods { fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederatorPublicKey, activations -> !activations.isActive(RSKIP123), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATOR_PUBLIC_KEY_OF_TYPE( CallTransaction.Function.fromSignature( @@ -432,7 +446,8 @@ public enum BridgeMethods { fixedCost(3000L), (BridgeMethodExecutorTyped) Bridge::getRetiringFederatorPublicKeyOfType, activations -> activations.isActive(RSKIP123), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_STATE_FOR_BTC_RELEASE_CLIENT( CallTransaction.Function.fromSignature( @@ -442,7 +457,8 @@ public enum BridgeMethods { ), fixedCost(4000L), (BridgeMethodExecutorTyped) Bridge::getStateForBtcReleaseClient, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_STATE_FOR_DEBUGGING( CallTransaction.Function.fromSignature( @@ -452,7 +468,8 @@ public enum BridgeMethods { ), fixedCost(3_000_000L), (BridgeMethodExecutorTyped) Bridge::getStateForDebugging, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_LOCKING_CAP( CallTransaction.Function.fromSignature( @@ -463,7 +480,8 @@ public enum BridgeMethods { fixedCost(3_000L), (BridgeMethodExecutorTyped) Bridge::getLockingCap, activations -> activations.isActive(RSKIP134), - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_ACTIVE_POWPEG_REDEEM_SCRIPT( CallTransaction.Function.fromSignature( @@ -474,7 +492,8 @@ public enum BridgeMethods { fixedCost(30_000L), (BridgeMethodExecutorTyped) Bridge::getActivePowpegRedeemScript, activations -> activations.isActive(RSKIP293), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT( CallTransaction.Function.fromSignature( @@ -485,7 +504,8 @@ public enum BridgeMethods { fixedCost(3_000L), (BridgeMethodExecutorTyped) Bridge::getActiveFederationCreationBlockHeight, activations -> activations.isActive(RSKIP186), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), INCREASE_LOCKING_CAP( CallTransaction.Function.fromSignature( @@ -506,7 +526,8 @@ public enum BridgeMethods { ), fixedCost(23000L), (BridgeMethodExecutorTyped) Bridge::isBtcTxHashAlreadyProcessed, - fixedPermission(true) + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), RECEIVE_HEADERS( CallTransaction.Function.fromSignature( @@ -627,7 +648,8 @@ public enum BridgeMethods { fixedCost(5000L), (BridgeMethodExecutorTyped) Bridge::hasBtcBlockCoinbaseTransactionInformation, activations -> activations.isActive(RSKIP143), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), REGISTER_FAST_BRIDGE_BTC_TRANSACTION( CallTransaction.Function.fromSignature( @@ -649,7 +671,8 @@ public enum BridgeMethods { fixedCost(3_800L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestBlockHeader, activations -> activations.isActive(RSKIP220), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HASH( CallTransaction.Function.fromSignature( @@ -660,7 +683,8 @@ public enum BridgeMethods { fixedCost(4_600L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHash, activations -> activations.isActive(RSKIP220), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HEIGHT( CallTransaction.Function.fromSignature( @@ -671,7 +695,8 @@ public enum BridgeMethods { fixedCost(5_000L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHeight, activations -> activations.isActive(RSKIP220), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_PARENT_BLOCK_HEADER_BY_HASH( CallTransaction.Function.fromSignature( @@ -682,7 +707,8 @@ public enum BridgeMethods { fixedCost(4_900L), (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainParentBlockHeaderByHash, activations -> activations.isActive(RSKIP220), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER( CallTransaction.Function.fromSignature( @@ -693,7 +719,8 @@ public enum BridgeMethods { fixedCost(3_000L), (BridgeMethodExecutorTyped) Bridge::getNextPegoutCreationBlockNumber, activations -> activations.isActive(RSKIP271), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_QUEUED_PEGOUTS_COUNT( CallTransaction.Function.fromSignature( @@ -704,7 +731,8 @@ public enum BridgeMethods { fixedCost(3_000L), (BridgeMethodExecutorTyped) Bridge::getQueuedPegoutsCount, activations -> activations.isActive(RSKIP271), - fixedPermission(false) + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT( CallTransaction.Function.fromSignature( @@ -716,7 +744,7 @@ public enum BridgeMethods { (BridgeMethodExecutorTyped) Bridge::getEstimatedFeesForNextPegOutEvent, activations -> activations.isActive(RSKIP271), fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTypeHelper.ALLOW_STATIC_CALL ); private static class CallTypeHelper { From 1ccaede5cb43719341382b265dd73019b9d819cb Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 12:57:58 -0300 Subject: [PATCH 084/137] Extract Bridge call validations to their own methods --- .../src/main/java/co/rsk/peg/Bridge.java | 92 +++++++++++++------ 1 file changed, 64 insertions(+), 28 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index a8566df7680..9bb0f75dc2b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -228,14 +228,32 @@ public class Bridge extends PrecompiledContracts.PrecompiledContract { private final SignatureCache signatureCache; private MsgType msgType; - public Bridge(RskAddress contractAddress, Constants constants, ActivationConfig activationConfig, - BridgeSupportFactory bridgeSupportFactory, SignatureCache signatureCache) { - this(contractAddress, constants, activationConfig, bridgeSupportFactory, MerkleBranch::new, signatureCache); + public Bridge( + RskAddress contractAddress, + Constants constants, + ActivationConfig activationConfig, + BridgeSupportFactory bridgeSupportFactory, + SignatureCache signatureCache) { + + this( + contractAddress, + constants, + activationConfig, + bridgeSupportFactory, + MerkleBranch::new, + signatureCache + ); } @VisibleForTesting - Bridge(RskAddress contractAddress, Constants constants, ActivationConfig activationConfig, - BridgeSupportFactory bridgeSupportFactory, BiFunction, Integer, MerkleBranch> merkleBranchFactory, SignatureCache signatureCache) { + Bridge( + RskAddress contractAddress, + Constants constants, + ActivationConfig activationConfig, + BridgeSupportFactory bridgeSupportFactory, + BiFunction, Integer, MerkleBranch> merkleBranchFactory, + SignatureCache signatureCache) { + this.bridgeSupportFactory = bridgeSupportFactory; this.contractAddress = contractAddress; this.constants = constants; @@ -323,10 +341,11 @@ public void init(PrecompiledContractArgs args) { this.msgType = args.getMsgType(); this.bridgeSupport = bridgeSupportFactory.newInstance( - args.getRepository(), - rskExecutionBlock, - contractAddress, - args.getLogs()); + args.getRepository(), + rskExecutionBlock, + contractAddress, + args.getLogs() + ); } @Override @@ -347,7 +366,7 @@ public byte[] execute(byte[] data) throws VMException { // Function parsing from data returned null => invalid function selected, halt! if (bridgeParsedData == null) { String errorMessage = String.format("Invalid data given: %s.", ByteUtil.toHexString(data)); - logger.info(errorMessage); + logger.info("[execute] {}", errorMessage); if (activations.isActive(ConsensusRule.RSKIP88)) { throw new BridgeIllegalArgumentException(errorMessage); } @@ -355,24 +374,7 @@ public byte[] execute(byte[] data) throws VMException { return null; } - // If this is not a local call, then first check whether the function - // allows for non-local calls - if (activations.isActive(ConsensusRule.RSKIP88) && - !isLocalCall() && - bridgeParsedData.bridgeMethod.onlyAllowsLocalCalls(this, bridgeParsedData.args)) { - - String errorMessage = String.format("Non-local-call to %s. Returning without execution.", bridgeParsedData.bridgeMethod.getFunction().name); - logger.info(errorMessage); - throw new BridgeIllegalArgumentException(errorMessage); - } - - if (activations.isActive(RSKIP_ARROWHEAD) && - !bridgeParsedData.bridgeMethod.acceptsThisTypeOfCall(this.activations, this.msgType)) { - String errorMessage = String.format("Call type (%s) not accepted by %s. Returning without execution.", this.msgType.name(), bridgeParsedData.bridgeMethod.getFunction().name); - logger.info(errorMessage); - // TODO: determine which type of exception makes sense for this case - throw new BridgeIllegalArgumentException(errorMessage); - } + validateCall(bridgeParsedData); Optional result; try { @@ -399,6 +401,40 @@ public byte[] execute(byte[] data) throws VMException { } } + private void validateCall(BridgeParsedData bridgeParsedData) throws BridgeIllegalArgumentException { + validateLocalCall(bridgeParsedData); + validateCallMessageType(bridgeParsedData); + } + + private void validateLocalCall(BridgeParsedData bridgeParsedData) throws BridgeIllegalArgumentException { + // If this is not a local call, then check whether the function allows for non-local calls + if (activations.isActive(ConsensusRule.RSKIP88) && + !isLocalCall() && + bridgeParsedData.bridgeMethod.onlyAllowsLocalCalls(this, bridgeParsedData.args)) { + + String errorMessage = String.format( + "Non-local-call to %s. Returning without execution.", + bridgeParsedData.bridgeMethod.getFunction().name + ); + logger.info("[validateLocalCall] {}", errorMessage); + throw new BridgeIllegalArgumentException(errorMessage); + } + } + + private void validateCallMessageType(BridgeParsedData bridgeParsedData) throws BridgeIllegalArgumentException { + if (activations.isActive(RSKIP_ARROWHEAD) && + !bridgeParsedData.bridgeMethod.acceptsThisTypeOfCall(this.msgType)) { + String errorMessage = String.format( + "Call type (%s) not accepted by %s. Returning without execution.", + this.msgType.name(), + bridgeParsedData.bridgeMethod.getFunction().name + ); + logger.info("[validateCallMessageType] {}", errorMessage); + // TODO: determine which type of exception makes sense for this case + throw new BridgeIllegalArgumentException(errorMessage); + } + } + private void teardown() throws IOException { bridgeSupport.save(); } From 3d5fb0527ea269e83e7675d01fa1fc5b0ce20ac4 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 13:07:38 -0300 Subject: [PATCH 085/137] Remove explicit array creation from Bridge tests --- .../src/test/java/co/rsk/peg/BridgeTest.java | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 2bfee1299fc..4c48a0232cb 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -60,7 +60,7 @@ void getActivePowpegRedeemScript_before_RSKIP293_activation() throws VMException BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = getBridgeInstance(bridgeSupportMock, activationConfig); - byte[] data = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction().encode(new Object[]{}); + byte[] data = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction().encode(); assertNull(bridge.execute(data)); } @@ -71,12 +71,12 @@ void getActivePowpegRedeemScript_after_RSKIP293_activation() throws VMException BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); when(bridgeSupportMock.getActivePowpegRedeemScript()).thenReturn( - Optional.of(BridgeRegTestConstants.getInstance().getGenesisFederation().getRedeemScript()) + Optional.of(BridgeRegTestConstants.getInstance().getGenesisFederation().getRedeemScript()) ); Bridge bridge = getBridgeInstance(bridgeSupportMock, activationConfig); - byte[] data = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction().encode(new Object[]{}); + byte[] data = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction().encode(); byte[] result = (byte[]) BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction().decodeResult(bridge.execute(data))[0]; assertArrayEquals(constants.bridgeConstants.getGenesisFederation().getRedeemScript().getProgram(), result); @@ -89,7 +89,7 @@ void getLockingCap_before_RSKIP134_activation() throws VMException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = getBridgeInstance(bridgeSupportMock); - byte[] data = BridgeMethods.GET_LOCKING_CAP.getFunction().encode(new Object[]{}); + byte[] data = BridgeMethods.GET_LOCKING_CAP.getFunction().encode(); assertNull(bridge.execute(data)); } @@ -104,7 +104,7 @@ void getLockingCap_after_RSKIP134_activation() throws VMException { // Don't really care about the internal logic, just checking if the method is active when(bridgeSupportMock.getLockingCap()).thenReturn(Coin.COIN); - byte[] data = Bridge.GET_LOCKING_CAP.encode(new Object[]{}); + byte[] data = Bridge.GET_LOCKING_CAP.encode(); byte[] result = bridge.execute(data); assertEquals(Coin.COIN.getValue(), ((BigInteger) Bridge.GET_LOCKING_CAP.decodeResult(result)[0]).longValue()); // Also test the method itself @@ -118,7 +118,7 @@ void increaseLockingCap_before_RSKIP134_activation() throws VMException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = getBridgeInstance(bridgeSupportMock); - byte[] data = BridgeMethods.INCREASE_LOCKING_CAP.getFunction().encode(new Object[]{}); + byte[] data = BridgeMethods.INCREASE_LOCKING_CAP.getFunction().encode(); assertNull(bridge.execute(data)); } @@ -133,17 +133,17 @@ void increaseLockingCap_after_RSKIP134_activation() throws VMException { // Don't really care about the internal logic, just checking if the method is active when(bridgeSupportMock.increaseLockingCap(any(), any())).thenReturn(true); - byte[] data = Bridge.INCREASE_LOCKING_CAP.encode(new Object[]{1}); + byte[] data = Bridge.INCREASE_LOCKING_CAP.encode(1); byte[] result = bridge.execute(data); assertTrue((boolean) Bridge.INCREASE_LOCKING_CAP.decodeResult(result)[0]); // Also test the method itself - assertEquals(true, bridge.increaseLockingCap(new Object[]{BigInteger.valueOf(1)})); + assertTrue(bridge.increaseLockingCap(new Object[]{BigInteger.valueOf(1)})); - data = Bridge.INCREASE_LOCKING_CAP.encode(new Object[]{21_000_000}); + data = Bridge.INCREASE_LOCKING_CAP.encode(21_000_000); result = bridge.execute(data); assertTrue((boolean) Bridge.INCREASE_LOCKING_CAP.decodeResult(result)[0]); // Also test the method itself - assertEquals(true, bridge.increaseLockingCap(new Object[]{BigInteger.valueOf(21_000_000)})); + assertTrue(bridge.increaseLockingCap(new Object[]{BigInteger.valueOf(21_000_000)})); } @Test @@ -186,9 +186,9 @@ void registerBtcCoinbaseTransaction_before_RSKIP143_activation() throws VMExcept Bridge bridge = getBridgeInstance(bridgeSupportMock, activations); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); - Integer zero = new Integer(0); + Integer zero = 0; - byte[] data = Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encode(new Object[]{value, zero, value, zero, zero}); + byte[] data = Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encode(value, zero, value, zero, zero); assertNull(bridge.execute(data)); } @@ -202,9 +202,9 @@ void registerBtcCoinbaseTransaction_after_RSKIP143_activation() throws VMExcepti Bridge bridge = getBridgeInstance(bridgeSupportMock, activations); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); - Integer zero = new Integer(0); + Integer zero = 0; - byte[] data = Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encode(new Object[]{value, zero, value, zero, zero}); + byte[] data = Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encode(value, zero, value, zero, zero); bridge.execute(data); verify(bridgeSupportMock, times(1)).registerBtcCoinbaseTransaction(value, Sha256Hash.wrap(value), value, Sha256Hash.wrap(value), value); @@ -325,7 +325,7 @@ void registerBtcTransaction_afterRskip199_acceptsExternalCalls() byte[] value = Sha256Hash.ZERO_HASH.getBytes(); int zero = 0; - byte[] data = Bridge.REGISTER_BTC_TRANSACTION.encode(new Object[]{ value, zero, value }); + byte[] data = Bridge.REGISTER_BTC_TRANSACTION.encode(value, zero, value); bridge.execute(data); @@ -344,7 +344,7 @@ void getActiveFederationCreationBlockHeight_before_RSKIP186_activation() throws BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = getBridgeInstance(bridgeSupportMock); - byte[] data = BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT.getFunction().encode(new Object[]{}); + byte[] data = BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT.getFunction().encode(); assertNull(bridge.execute(data)); } @@ -360,7 +360,7 @@ void getActiveFederationCreationBlockHeight_after_RSKIP186_activation() throws V when(bridgeSupportMock.getActiveFederationCreationBlockHeight()).thenReturn(1L); CallTransaction.Function function = BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT.getFunction(); - byte[] data = function.encode(new Object[]{ }); + byte[] data = function.encode(); byte[] result = bridge.execute(data); assertEquals(1L, ((BigInteger)function.decodeResult(result)[0]).longValue()); // Also test the method itself @@ -624,7 +624,7 @@ void receiveHeader_empty_parameter() throws VMException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = spy(getBridgeInstance(bridgeSupportMock, activations)); - byte[] data = Bridge.RECEIVE_HEADER.encode(new Object[]{}); + byte[] data = Bridge.RECEIVE_HEADER.encode(); assertNull(bridge.execute(data)); verify(bridge, never()).receiveHeader(any(Object[].class)); @@ -859,7 +859,7 @@ void getNextPegoutCreationBlockNumber_before_RSKIP271_activation() throws VMExce BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = getBridgeInstance(bridgeSupportMock); - byte[] data = BridgeMethods.GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER.getFunction().encode(new Object[]{}); + byte[] data = BridgeMethods.GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER.getFunction().encode(); assertNull(bridge.execute(data)); } @@ -874,7 +874,7 @@ void getNextPegoutCreationBlockNumber_after_RSKIP271_activation() throws VMExcep when(bridgeSupportMock.getNextPegoutCreationBlockNumber()).thenReturn(1L); CallTransaction.Function function = BridgeMethods.GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER.getFunction(); - byte[] data = function.encode(new Object[]{ }); + byte[] data = function.encode(); byte[] result = bridge.execute(data); assertEquals(1L, ((BigInteger)function.decodeResult(result)[0]).longValue()); @@ -889,7 +889,7 @@ void getQueuedPegoutsCount_before_RSKIP271_activation() throws VMException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = getBridgeInstance(bridgeSupportMock); - byte[] data = BridgeMethods.GET_QUEUED_PEGOUTS_COUNT.getFunction().encode(new Object[]{}); + byte[] data = BridgeMethods.GET_QUEUED_PEGOUTS_COUNT.getFunction().encode(); assertNull(bridge.execute(data)); } @@ -904,7 +904,7 @@ void getQueuedPegoutsCount_after_RSKIP271_activation() throws VMException, IOExc when(bridgeSupportMock.getQueuedPegoutsCount()).thenReturn(1); CallTransaction.Function function = BridgeMethods.GET_QUEUED_PEGOUTS_COUNT.getFunction(); - byte[] data = function.encode(new Object[]{ }); + byte[] data = function.encode(); byte[] result = bridge.execute(data); assertEquals(1, ((BigInteger)function.decodeResult(result)[0]).intValue()); @@ -919,7 +919,7 @@ void getEstimatedFeesForNextPegOutEvent_before_RSKIP271_activation() throws VMEx BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = getBridgeInstance(bridgeSupportMock); - byte[] data = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction().encode(new Object[]{}); + byte[] data = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction().encode(); assertNull(bridge.execute(data)); } @@ -934,7 +934,7 @@ void getEstimatedFeesForNextPegOutEvent_after_RSKIP271_activation() throws VMExc when(bridgeSupportMock.getEstimatedFeesForNextPegOutEvent()).thenReturn(Coin.SATOSHI); CallTransaction.Function function = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction(); - byte[] data = function.encode(new Object[]{ }); + byte[] data = function.encode(); byte[] result = bridge.execute(data); assertEquals(Coin.SATOSHI.value, ((BigInteger)function.decodeResult(result)[0]).intValue()); From b7b0d1da679d360445825c35843f4fb22810c336 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 13:18:43 -0300 Subject: [PATCH 086/137] Remove unused config object from Bridge tests --- .../src/test/java/co/rsk/peg/BridgeTest.java | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 4c48a0232cb..ecb811fabff 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1,13 +1,23 @@ package co.rsk.peg; +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.store.BlockStoreException; import co.rsk.blockchain.utils.BlockGenerator; import co.rsk.config.BridgeRegTestConstants; -import co.rsk.config.TestSystemProperties; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.flyover.FlyoverTxResponseCodes; +import java.io.IOException; +import java.math.BigInteger; +import java.time.Instant; +import java.util.*; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -17,39 +27,20 @@ import org.ethereum.util.ByteUtil; import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.exception.VMException; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.io.IOException; -import java.math.BigInteger; -import java.time.Instant; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; -import static org.junit.jupiter.api.Assertions.*; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.anyBoolean; -import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.*; - class BridgeTest { - private TestSystemProperties config = new TestSystemProperties(); private Constants constants; private ActivationConfig activationConfig; private SignatureCache signatureCache; @BeforeEach void resetConfigToRegTest() { - config = spy(new TestSystemProperties()); constants = Constants.regtest(); - when(config.getNetworkConstants()).thenReturn(constants); activationConfig = spy(ActivationConfigsForTest.genesis()); - when(config.getActivationConfig()).thenReturn(activationConfig); signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); } From 04610aabb8f7c18f113b382af5facf5984f632a9 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 13:19:06 -0300 Subject: [PATCH 087/137] Add rskipArrowhead to the missing config files --- rskj-core/src/main/resources/reference.conf | 1 + .../config/blockchain/upgrades/ActivationConfigsForTest.java | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 00da71ef4b3..34b7e01bfae 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -78,6 +78,7 @@ blockchain = { rskip400 = arrowhead600 rskip412 = arrowhead600 rskip415 = arrowhead600 + rskipArrowhead = arrowhead600 } } gc = { diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java index dfaaeeb5889..afb38d7564e 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java @@ -184,7 +184,8 @@ private static List getArrowhead600Rskips() { ConsensusRule.RSKIP379, ConsensusRule.RSKIP398, ConsensusRule.RSKIP400, - ConsensusRule.RSKIP415 + ConsensusRule.RSKIP415, + ConsensusRule.RSKIP_ARROWHEAD )); return rskips; From f48437c4fa131731c55a3815dac52f4fd4ab11c4 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 13:42:33 -0300 Subject: [PATCH 088/137] Remove empty constructor from PrecompiledContractArgs --- .../main/java/org/ethereum/vm/PrecompiledContractArgs.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgs.java b/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgs.java index 7e4b50ce9be..9a395805e6d 100644 --- a/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgs.java +++ b/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgs.java @@ -44,12 +44,8 @@ public class PrecompiledContractArgs { */ @Nullable private ProgramInvoke programInvoke; - private MessageCall.MsgType msgType; - public PrecompiledContractArgs() { - } - void setTransaction(Transaction transaction) { this.transaction = transaction; } From 1c88079132a6cd0d025ccf62d3f74dc025432dce Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 13:43:06 -0300 Subject: [PATCH 089/137] Make msg type CALL by default in PrecompiledContractArgsBuilder --- .../org/ethereum/vm/PrecompiledContractArgsBuilder.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgsBuilder.java b/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgsBuilder.java index 0d9abffd6c5..5acdbe87ff4 100644 --- a/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgsBuilder.java +++ b/rskj-core/src/main/java/org/ethereum/vm/PrecompiledContractArgsBuilder.java @@ -37,10 +37,11 @@ public class PrecompiledContractArgsBuilder { private ReceiptStore receiptStore; private List logs; private ProgramInvoke programInvoke; + private MessageCall.MsgType msgType; - private MessageCall.MsgType msgType = MessageCall.MsgType.CALL; - - private PrecompiledContractArgsBuilder() {} + private PrecompiledContractArgsBuilder() { + msgType = MessageCall.MsgType.CALL; + } public static PrecompiledContractArgsBuilder builder() { return new PrecompiledContractArgsBuilder(); From 9f6540c47b760f2d528bd39f7b3fbe0c37bbf0a5 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 15 Jan 2024 18:14:59 -0300 Subject: [PATCH 090/137] Create BridgeBuilder class and refactor Bridge tests --- .../src/test/java/co/rsk/peg/BridgeTest.java | 576 ++++++++++-------- .../co/rsk/test/builders/BridgeBuilder.java | 102 ++++ 2 files changed, 417 insertions(+), 261 deletions(-) create mode 100644 rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index ecb811fabff..8bff43fc576 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -8,16 +8,18 @@ import static org.mockito.Mockito.*; import co.rsk.bitcoinj.core.*; +import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.store.BlockStoreException; -import co.rsk.blockchain.utils.BlockGenerator; import co.rsk.config.BridgeRegTestConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.flyover.FlyoverTxResponseCodes; +import co.rsk.test.builders.BridgeBuilder; import java.io.IOException; import java.math.BigInteger; import java.time.Instant; import java.util.*; +import java.util.stream.Stream; import org.bouncycastle.util.encoders.Hex; import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -25,172 +27,208 @@ import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; -import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.exception.VMException; import org.junit.jupiter.api.Assertions; 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; class BridgeTest { private Constants constants; private ActivationConfig activationConfig; - private SignatureCache signatureCache; + private BridgeBuilder bridgeBuilder; @BeforeEach void resetConfigToRegTest() { constants = Constants.regtest(); activationConfig = spy(ActivationConfigsForTest.genesis()); - signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); + bridgeBuilder = new BridgeBuilder(); } @Test - void getActivePowpegRedeemScript_before_RSKIP293_activation() throws VMException { - doReturn(false).when(activationConfig).isActive(eq(RSKIP293), anyLong()); + void getActivePowpegRedeemScript_before_RSKIP293_activation() { + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock, activationConfig); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] data = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction().encode(); - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void getActivePowpegRedeemScript_after_RSKIP293_activation() throws VMException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP293), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.hop400(); + CallTransaction.Function getActivePowpegRedeemScriptFunction = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Script activePowpegRedeemScript = BridgeRegTestConstants.getInstance().getGenesisFederation().getRedeemScript(); when(bridgeSupportMock.getActivePowpegRedeemScript()).thenReturn( - Optional.of(BridgeRegTestConstants.getInstance().getGenesisFederation().getRedeemScript()) + Optional.of(activePowpegRedeemScript) ); - Bridge bridge = getBridgeInstance(bridgeSupportMock, activationConfig); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); - byte[] data = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction().encode(); - byte[] result = (byte[]) BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction().decodeResult(bridge.execute(data))[0]; + byte[] data = getActivePowpegRedeemScriptFunction.encode(); + byte[] result = bridge.execute(data); + byte[] decodedResult = (byte[]) getActivePowpegRedeemScriptFunction.decodeResult(result)[0]; + Script obtainedRedeemScript = new Script(decodedResult); - assertArrayEquals(constants.bridgeConstants.getGenesisFederation().getRedeemScript().getProgram(), result); + assertEquals(activePowpegRedeemScript, obtainedRedeemScript); } @Test - void getLockingCap_before_RSKIP134_activation() throws VMException { - doReturn(false).when(activationConfig).isActive(eq(RSKIP134), anyLong()); + void getLockingCap_before_RSKIP134_activation() { + ActivationConfig activationConfig = ActivationConfigsForTest.wasabi100(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] data = BridgeMethods.GET_LOCKING_CAP.getFunction().encode(); - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void getLockingCap_after_RSKIP134_activation() throws VMException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP134), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + CallTransaction.Function getLockingCapFunction = Bridge.GET_LOCKING_CAP; BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Coin lockingCap = Coin.COIN; + when(bridgeSupportMock.getLockingCap()).thenReturn(lockingCap); + + Transaction tx = mock(Transaction.class); + when(tx.isLocalCallTransaction()).thenReturn(true); - // Don't really care about the internal logic, just checking if the method is active - when(bridgeSupportMock.getLockingCap()).thenReturn(Coin.COIN); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .transaction(tx) + .bridgeSupport(bridgeSupportMock) + .build(); - byte[] data = Bridge.GET_LOCKING_CAP.encode(); + byte[] data = getLockingCapFunction.encode(); byte[] result = bridge.execute(data); - assertEquals(Coin.COIN.getValue(), ((BigInteger) Bridge.GET_LOCKING_CAP.decodeResult(result)[0]).longValue()); + BigInteger decodedResult = (BigInteger) getLockingCapFunction.decodeResult(result)[0]; + Coin obtainedLockingCap = Coin.valueOf(decodedResult.longValue()); + + assertEquals(lockingCap, obtainedLockingCap); + // Also test the method itself - assertEquals(Coin.COIN.getValue(), bridge.getLockingCap(new Object[]{})); + long lockingCapFromTheBridge = bridge.getLockingCap(new Object[]{}); + assertEquals(lockingCap.getValue(), lockingCapFromTheBridge); } @Test - void increaseLockingCap_before_RSKIP134_activation() throws VMException { - doReturn(false).when(activationConfig).isActive(eq(RSKIP134), anyLong()); + void increaseLockingCap_before_RSKIP134_activation() { + ActivationConfig activationConfig = ActivationConfigsForTest.wasabi100(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] data = BridgeMethods.INCREASE_LOCKING_CAP.getFunction().encode(); - - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } - @Test - void increaseLockingCap_after_RSKIP134_activation() throws VMException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP134), anyLong()); + @ParameterizedTest() + @MethodSource("lockingCapValues") + void increaseLockingCap_after_RSKIP134_activation(long newLockingCapValue) throws VMException { + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + CallTransaction.Function increaseLockingCapFunction = Bridge.INCREASE_LOCKING_CAP; BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); - - // Don't really care about the internal logic, just checking if the method is active when(bridgeSupportMock.increaseLockingCap(any(), any())).thenReturn(true); - byte[] data = Bridge.INCREASE_LOCKING_CAP.encode(1); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); + + byte[] data = increaseLockingCapFunction.encode(newLockingCapValue); byte[] result = bridge.execute(data); - assertTrue((boolean) Bridge.INCREASE_LOCKING_CAP.decodeResult(result)[0]); - // Also test the method itself - assertTrue(bridge.increaseLockingCap(new Object[]{BigInteger.valueOf(1)})); + boolean decodedResult = (boolean) increaseLockingCapFunction.decodeResult(result)[0]; + + assertTrue(decodedResult); - data = Bridge.INCREASE_LOCKING_CAP.encode(21_000_000); - result = bridge.execute(data); - assertTrue((boolean) Bridge.INCREASE_LOCKING_CAP.decodeResult(result)[0]); // Also test the method itself - assertTrue(bridge.increaseLockingCap(new Object[]{BigInteger.valueOf(21_000_000)})); + boolean resultFromTheBridge = bridge.increaseLockingCap(new Object[]{BigInteger.valueOf(newLockingCapValue)}); + assertTrue(resultFromTheBridge); + } + + private static Stream lockingCapValues() { + return Stream.of( + Arguments.of(1), + Arguments.of(21_000_0000) + ); } @Test - void increaseLockingCap_invalidParameter() throws VMException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP134), anyLong()); + void increaseLockingCap_invalidParameter() { + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + CallTransaction.Function increaseLockingCapFunction = BridgeMethods.INCREASE_LOCKING_CAP.getFunction(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); // Uses the proper signature but with no argument - // The solidity decoder in the Bridge will convert the undefined argument as 0, but the initial validation in the method will reject said value - byte[] data = Bridge.INCREASE_LOCKING_CAP.encodeSignature(); - byte[] result = bridge.execute(data); - assertNull(result); + // The solidity decoder in the Bridge will convert the undefined argument as 0, + // but the initial validation in the method will reject said value + final byte[] noArgumentData = increaseLockingCapFunction.encodeSignature(); + assertThrows(VMException.class, () -> bridge.execute(noArgumentData)); // Uses the proper signature but appends invalid data type // This will be rejected by the solidity decoder in the Bridge directly - data = ByteUtil.merge(Bridge.INCREASE_LOCKING_CAP.encodeSignature(), Hex.decode("ab")); - result = bridge.execute(data); - assertNull(result); + final byte[] invalidTypeData = ByteUtil.merge(increaseLockingCapFunction.encodeSignature(), Hex.decode("ab")); + assertThrows(VMException.class, () -> bridge.execute(invalidTypeData)); // Uses the proper signature and data type, but with an invalid value // This will be rejected by the initial validation in the method - data = Bridge.INCREASE_LOCKING_CAP.encode(new Object[]{-1}); - result = bridge.execute(data); - assertNull(result); + final byte[] invalidValueData = increaseLockingCapFunction.encode(-1); + assertThrows(VMException.class, () -> bridge.execute(invalidValueData)); // Uses the proper signature and data type, but with a value that exceeds the long max value - data = ByteUtil.merge(Bridge.INCREASE_LOCKING_CAP.encodeSignature(), Hex.decode("0000000000000000000000000000000000000000000000080000000000000000")); - result = bridge.execute(data); - assertNull(result); + final byte[] aboveMaxLengthData = ByteUtil.merge( + increaseLockingCapFunction.encodeSignature(), + Hex.decode("0000000000000000000000000000000000000000000000080000000000000000") + ); + assertThrows(VMException.class, () -> bridge.execute(aboveMaxLengthData)); } @Test - void registerBtcCoinbaseTransaction_before_RSKIP143_activation() throws VMException { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(false).when(activations).isActive(eq(RSKIP143), anyLong()); + void registerBtcCoinbaseTransaction_before_RSKIP143_activation() { + ActivationConfig activationConfig = ActivationConfigsForTest.wasabi100(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock, activations); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); Integer zero = 0; - byte[] data = Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encode(value, zero, value, zero, zero); - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void registerBtcCoinbaseTransaction_after_RSKIP143_activation() throws VMException { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP143), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock, activations); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); Integer zero = 0; @@ -198,36 +236,37 @@ void registerBtcCoinbaseTransaction_after_RSKIP143_activation() throws VMExcepti byte[] data = Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encode(value, zero, value, zero, zero); bridge.execute(data); - verify(bridgeSupportMock, times(1)).registerBtcCoinbaseTransaction(value, Sha256Hash.wrap(value), value, Sha256Hash.wrap(value), value); + verify(bridgeSupportMock, times(1)).registerBtcCoinbaseTransaction( + value, + Sha256Hash.wrap(value), + value, + Sha256Hash.wrap(value), + value + ); } @Test - void registerBtcCoinbaseTransaction_after_RSKIP143_activation_null_data() throws VMException { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP143), anyLong()); + void registerBtcCoinbaseTransaction_after_RSKIP143_activation_null_data() { + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + CallTransaction.Function registerBtcCoinbaseTransactionFunction = Bridge.REGISTER_BTC_COINBASE_TRANSACTION; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock, activations); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); - byte[] data = Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encodeSignature(); - byte[] result = bridge.execute(data); - assertNull(result); + final byte[] emptyData = registerBtcCoinbaseTransactionFunction.encodeSignature(); + assertThrows(VMException.class, () -> bridge.execute(emptyData)); - data = ByteUtil.merge(Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encodeSignature(), Hex.decode("ab")); - result = bridge.execute(data); - assertNull(result); + final byte[] invalidStringData = ByteUtil.merge(registerBtcCoinbaseTransactionFunction.encodeSignature(), Hex.decode("ab")); + assertThrows(VMException.class, () -> bridge.execute(invalidStringData)); - data = ByteUtil.merge(Bridge.REGISTER_BTC_COINBASE_TRANSACTION.encodeSignature(), Hex.decode("0000000000000000000000000000000000000000000000080000000000000000")); - result = bridge.execute(data); - assertNull(result); + final byte[] invalidHexData = ByteUtil.merge(registerBtcCoinbaseTransactionFunction.encodeSignature(), Hex.decode("0000000000000000000000000000000000000000000000080000000000000000")); + assertThrows(VMException.class, () -> bridge.execute(invalidHexData)); } @Test - void registerBtcTransaction_beforeRskip199_rejectsExternalCalls() - throws VMException, IOException, BlockStoreException { - - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(false).when(activations).isActive(eq(RSKIP199), anyLong()); + void registerBtcTransaction_beforeRskip199_rejectsExternalCalls() throws VMException, IOException, BlockStoreException { + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); Federation activeFederation = new StandardMultisigFederation( FederationTestUtils.getFederationMembers(3), @@ -240,13 +279,18 @@ void registerBtcTransaction_beforeRskip199_rejectsExternalCalls() when(bridgeSupportMock.getActiveFederation()).thenReturn(activeFederation); Transaction rskTx = mock(Transaction.class); - when(rskTx.getSender(any(SignatureCache.class))).thenReturn(new RskAddress("0000000000000000000000000000000000000001")); + RskAddress senderAddress = new RskAddress("0000000000000000000000000000000000000001"); + when(rskTx.getSender(any(SignatureCache.class))).thenReturn(senderAddress); - Bridge bridge = getBridgeInstance(rskTx, bridgeSupportMock, activations, signatureCache); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .transaction(rskTx) + .build(); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); int zero = 0; - byte[] data = Bridge.REGISTER_BTC_TRANSACTION.encode(new Object[]{ value, zero, value }); + byte[] data = Bridge.REGISTER_BTC_TRANSACTION.encode(value, zero, value); try { bridge.execute(data); @@ -264,11 +308,8 @@ void registerBtcTransaction_beforeRskip199_rejectsExternalCalls() } @Test - void registerBtcTransaction_beforeRskip199_acceptsCallFromFederationMember() - throws VMException, IOException, BlockStoreException { - - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(false).when(activations).isActive(eq(RSKIP199), anyLong()); + void registerBtcTransaction_beforeRskip199_acceptsCallFromFederationMember() throws VMException, IOException, BlockStoreException { + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); BtcECKey fed1Key = new BtcECKey(); RskAddress fed1Address = new RskAddress(ECKey.fromPublicOnly(fed1Key.getPubKey()).getAddress()); @@ -288,11 +329,15 @@ void registerBtcTransaction_beforeRskip199_acceptsCallFromFederationMember() Transaction rskTx = mock(Transaction.class); when(rskTx.getSender(any(SignatureCache.class))).thenReturn(fed1Address); - Bridge bridge = getBridgeInstance(rskTx, bridgeSupportMock, activations, signatureCache); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .transaction(rskTx) + .build(); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); int zero = 0; - byte[] data = Bridge.REGISTER_BTC_TRANSACTION.encode(new Object[]{ value, zero, value }); + byte[] data = Bridge.REGISTER_BTC_TRANSACTION.encode(value, zero, value); bridge.execute(data); @@ -305,14 +350,14 @@ void registerBtcTransaction_beforeRskip199_acceptsCallFromFederationMember() } @Test - void registerBtcTransaction_afterRskip199_acceptsExternalCalls() - throws VMException, IOException, BlockStoreException { - - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP199), anyLong()); - + void registerBtcTransaction_afterRskip199_acceptsExternalCalls() throws VMException, IOException, BlockStoreException { + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock, activations); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); int zero = 0; @@ -329,41 +374,50 @@ void registerBtcTransaction_afterRskip199_acceptsExternalCalls() } @Test - void getActiveFederationCreationBlockHeight_before_RSKIP186_activation() throws VMException { - doReturn(false).when(activationConfig).isActive(eq(RSKIP186), anyLong()); + void getActiveFederationCreationBlockHeight_before_RSKIP186_activation() { + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] data = BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT.getFunction().encode(); - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void getActiveFederationCreationBlockHeight_after_RSKIP186_activation() throws VMException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP186), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); + long activeFederationCreationBlockHeight = 1L; BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + when(bridgeSupportMock.getActiveFederationCreationBlockHeight()).thenReturn(activeFederationCreationBlockHeight); - // Don't really care about the internal logic, just checking if the method is active - when(bridgeSupportMock.getActiveFederationCreationBlockHeight()).thenReturn(1L); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); CallTransaction.Function function = BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT.getFunction(); byte[] data = function.encode(); byte[] result = bridge.execute(data); - assertEquals(1L, ((BigInteger)function.decodeResult(result)[0]).longValue()); + BigInteger decodedResult = (BigInteger)function.decodeResult(result)[0]; + + assertEquals(activeFederationCreationBlockHeight, decodedResult.longValue()); + // Also test the method itself - assertEquals(1L, bridge.getActiveFederationCreationBlockHeight(new Object[]{ })); + long resultFromTheBridge = bridge.getActiveFederationCreationBlockHeight(new Object[]{}); + assertEquals(activeFederationCreationBlockHeight, resultFromTheBridge); } @Test - void registerFlyoverBtcTransaction_before_RSKIP176_activation() throws VMException { - doReturn(false).when(activationConfig).isActive(eq(RSKIP176), anyLong()); + void registerFlyoverBtcTransaction_before_RSKIP176_activation() { + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); byte[] pubKeyHash = new BtcECKey().getPubKeyHash(); @@ -380,19 +434,16 @@ void registerFlyoverBtcTransaction_before_RSKIP176_activation() throws VMExcepti ); //Assert - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address_before_RSKIP284_activation_fails() throws VMException, IOException, BlockStoreException { NetworkParameters networkParameters = constants.getBridgeConstants().getBtcParams(); - doReturn(true).when(activationConfig).isActive(eq(RSKIP176), anyLong()); - doReturn(false).when(activationConfig).isActive(eq(RSKIP284), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); - when(bridgeSupportMock.registerFlyoverBtcTransaction( any(Transaction.class), any(byte[].class), @@ -405,18 +456,23 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address anyBoolean() )).thenReturn(BigInteger.valueOf(2)); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); + byte[] value = Sha256Hash.ZERO_HASH.getBytes(); Address refundBtcAddress = Address.fromBase58(networkParameters, "2MyEXHyt2fXqdFm3r4xXEkTdbwdZm7qFiDP"); byte[] refundBtcAddressBytes = BridgeUtils.serializeBtcAddressWithVersion( - activationConfig.forBlock(anyLong()), + activationConfig.forBlock(0), refundBtcAddress ); BtcECKey btcECKeyLp = new BtcECKey(); Address lpBtcAddress = btcECKeyLp.toAddress(networkParameters); byte[] lpBtcAddressBytes = BridgeUtils.serializeBtcAddressWithVersion( - activationConfig.forBlock(anyLong()), + activationConfig.forBlock(0), lpBtcAddress ); @@ -435,9 +491,10 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address ); byte[] result = bridge.execute(data); + BigInteger decodedResult = (BigInteger) Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.decodeResult(result)[0]; //Assert - assertEquals(BigInteger.valueOf(-900), Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.decodeResult(result)[0]); + assertEquals(FlyoverTxResponseCodes.GENERIC_ERROR.value(), decodedResult.longValue()); verify(bridgeSupportMock, times(0)).registerFlyoverBtcTransaction( any(Transaction.class), eq(value), @@ -455,12 +512,9 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address_after_RSKIP284_activation_ok() throws VMException, IOException, BlockStoreException { NetworkParameters networkParameters = constants.getBridgeConstants().getBtcParams(); - doReturn(true).when(activationConfig).isActive(eq(RSKIP176), anyLong()); - doReturn(true).when(activationConfig).isActive(eq(RSKIP284), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.hop400(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); - when(bridgeSupportMock.registerFlyoverBtcTransaction( any(Transaction.class), any(byte[].class), @@ -473,18 +527,23 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address anyBoolean() )).thenReturn(BigInteger.valueOf(2)); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); + byte[] value = Sha256Hash.ZERO_HASH.getBytes(); Address refundBtcAddress = Address.fromBase58(networkParameters, "2MyEXHyt2fXqdFm3r4xXEkTdbwdZm7qFiDP"); byte[] refundBtcAddressBytes = BridgeUtils.serializeBtcAddressWithVersion( - activationConfig.forBlock(anyLong()), + activationConfig.forBlock(0), refundBtcAddress ); BtcECKey btcECKeyLp = new BtcECKey(); Address lpBtcAddress = btcECKeyLp.toAddress(networkParameters); byte[] lpBtcAddressBytes = BridgeUtils.serializeBtcAddressWithVersion( - activationConfig.forBlock(anyLong()), + activationConfig.forBlock(0), lpBtcAddress ); @@ -520,13 +579,10 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address } @Test - void registerFlyoverBtcTransaction_after_RSKIP176_activation_generic_error() - throws VMException, IOException, BlockStoreException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP176), anyLong()); + void registerFlyoverBtcTransaction_after_RSKIP176_activation_generic_error() throws VMException, IOException, BlockStoreException { + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); - when(bridgeSupportMock.registerFlyoverBtcTransaction( any(Transaction.class), any(byte[].class), @@ -539,6 +595,11 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_generic_error() anyBoolean() )).thenReturn(BigInteger.valueOf(FlyoverTxResponseCodes.GENERIC_ERROR.value())); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); + byte[] value = Sha256Hash.ZERO_HASH.getBytes(); BtcECKey btcECKeyRefund = new BtcECKey(); byte[] pubKeyHashRefund = btcECKeyRefund.getPubKeyHash(); @@ -558,174 +619,183 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_generic_error() true ); byte[] result = bridge.execute(data); + BigInteger decodedResult = (BigInteger)Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.decodeResult(result)[0]; - assertEquals(FlyoverTxResponseCodes.GENERIC_ERROR.value(), - ((BigInteger)Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.decodeResult(result)[0]).longValue()); + assertEquals(FlyoverTxResponseCodes.GENERIC_ERROR.value(), decodedResult.longValue()); } @Test void registerFlyoverBtcTransaction_after_RSKIP176_null_parameter() throws VMException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP176), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); - byte[] value = Sha256Hash.ZERO_HASH.getBytes(); + byte[] noArgumentData = Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.encodeSignature(); + assertThrows(VMException.class, () -> bridge.execute(noArgumentData)); - byte[] data = Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.encodeSignature(); - byte[] result = bridge.execute(data); - assertNull(result); - - data = ByteUtil.merge(Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.encodeSignature(), value); - result = bridge.execute(data); - assertNull(result); + byte[] value = Sha256Hash.ZERO_HASH.getBytes(); + byte[] zeroValueData = ByteUtil.merge(Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.encodeSignature(), value); + assertThrows(VMException.class, () -> bridge.execute(zeroValueData)); } @Test void receiveHeader_before_RSKIP200() throws VMException { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(false).when(activations).isActive(eq(RSKIP200), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = spy(getBridgeInstance(bridgeSupportMock, activations)); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); NetworkParameters networkParameters = constants.bridgeConstants.getBtcParams(); co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock( - networkParameters, - 1, - PegTestUtils.createHash(1), - PegTestUtils.createHash(1), - 1, - Utils.encodeCompactBits(networkParameters.getMaxTarget() - ), 1, new ArrayList<>()).cloneAsHeader(); + networkParameters, + 1, + PegTestUtils.createHash(1), + PegTestUtils.createHash(1), + 1, + Utils.encodeCompactBits(networkParameters.getMaxTarget()), + 1, + new ArrayList<>() + ).cloneAsHeader(); Object[] parameters = new Object[]{block.bitcoinSerialize()}; byte[] data = Bridge.RECEIVE_HEADER.encode(parameters); - bridge.execute(data); - assertNull(bridge.execute(data)); - verify(bridge, never()).receiveHeader(any(Object[].class)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void receiveHeader_empty_parameter() throws VMException { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP200), anyLong()); - + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = spy(getBridgeInstance(bridgeSupportMock, activations)); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); byte[] data = Bridge.RECEIVE_HEADER.encode(); - assertNull(bridge.execute(data)); - verify(bridge, never()).receiveHeader(any(Object[].class)); + assertThrows(VMException.class, () -> bridge.execute(data)); verifyNoInteractions(bridgeSupportMock); } @Test void receiveHeader_after_RSKIP200_Ok() throws VMException { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP200), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); - Bridge bridge = spy(getBridgeInstance(mock(BridgeSupport.class), activations)); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); NetworkParameters networkParameters = constants.bridgeConstants.getBtcParams(); co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock( - networkParameters, - 1, - PegTestUtils.createHash(1), - PegTestUtils.createHash(1), - 1, - Utils.encodeCompactBits(networkParameters.getMaxTarget() - ), 1, new ArrayList<>()).cloneAsHeader(); + networkParameters, + 1, + PegTestUtils.createHash(1), + PegTestUtils.createHash(1), + 1, + Utils.encodeCompactBits(networkParameters.getMaxTarget()), + 1, + new ArrayList<>() + ).cloneAsHeader(); Object[] parameters = new Object[]{block.bitcoinSerialize()}; byte[] data = Bridge.RECEIVE_HEADER.encode(parameters); - byte[] result = bridge.execute(data); - verify(bridge, times(1)).receiveHeader(eq(parameters)); // NOSONAR: eq is needed - assertEquals(BigInteger.valueOf(0), Bridge.RECEIVE_HEADER.decodeResult(result)[0]); + BigInteger decodedResult = (BigInteger) Bridge.RECEIVE_HEADER.decodeResult(result)[0]; + + assertEquals(BigInteger.valueOf(0), decodedResult); } @Test void receiveHeader_bridgeSupport_Exception() throws IOException, BlockStoreException { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP200), anyLong()); - + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - doThrow(new IOException()).when(bridgeSupportMock).receiveHeader(any()); - Bridge bridge = getBridgeInstance(bridgeSupportMock, activations); + doThrow(new IOException()).when(bridgeSupportMock).receiveHeader(any()) + ; + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); NetworkParameters networkParameters = constants.bridgeConstants.getBtcParams(); co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock( - networkParameters, - 1, - PegTestUtils.createHash(1), - PegTestUtils.createHash(1), - 1, - Utils.encodeCompactBits(networkParameters.getMaxTarget() - ), 1, new ArrayList<>()).cloneAsHeader(); + networkParameters, + 1, + PegTestUtils.createHash(1), + PegTestUtils.createHash(1), + 1, + Utils.encodeCompactBits(networkParameters.getMaxTarget()), + 1, + new ArrayList<>() + ).cloneAsHeader(); Object[] parameters = new Object[]{block.bitcoinSerialize()}; byte[] data = Bridge.RECEIVE_HEADER.encode(parameters); - Assertions.assertThrows(VMException.class, () -> bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void receiveHeaders_after_RSKIP200_notFederation() { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP200), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); when(bridgeSupportMock.getRetiringFederation()).thenReturn(null); when(bridgeSupportMock.getActiveFederation()).thenReturn(BridgeRegTestConstants.getInstance().getGenesisFederation()); Transaction txMock = mock(Transaction.class); - when(txMock.getSender(any(SignatureCache.class))).thenReturn(new RskAddress(new ECKey().getAddress())); //acces for anyone + RskAddress txSender = new RskAddress(new ECKey().getAddress()); + when(txMock.getSender(any(SignatureCache.class))).thenReturn(txSender); //access for anyone - Bridge bridge = getBridgeInstance(txMock, bridgeSupportMock, activations, signatureCache); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .transaction(txMock) + .bridgeSupport(bridgeSupportMock) + .build(); - try { - bridge.execute(Bridge.RECEIVE_HEADERS.encode()); - fail(); - } catch (Exception ex) { - assertTrue(ex.getMessage().contains("Sender is not part of the active or retiring federation")); - } + byte[] data = Bridge.RECEIVE_HEADERS.encode(); + + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test - void receiveHeaders_after_RSKIP200_header_wrong_size() throws VMException, IOException { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP200), anyLong()); - // It is used to check the size of the header - doReturn(true).when(activations).isActive(eq(RSKIP124), anyLong()); + void receiveHeaders_after_RSKIP200_header_wrong_size() throws VMException { + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); - Bridge bridge = getBridgeInstance(mock(BridgeSupport.class), activations); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); Object[] parameters = new Object[]{Sha256Hash.ZERO_HASH.getBytes()}; byte[] data = Bridge.RECEIVE_HEADER.encode(parameters); byte[] result = bridge.execute(data); - assertEquals(BigInteger.valueOf(-20), Bridge.RECEIVE_HEADER.decodeResult(result)[0]); + BigInteger decodedResult = (BigInteger) Bridge.RECEIVE_HEADER.decodeResult(result)[0]; + assertEquals(BigInteger.valueOf(-20), decodedResult); } @Test void getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls_afterRskip220() { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP220), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); - Bridge bridge = getBridgeInstance(mock(BridgeSupport.class), activations); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); assertFalse(bridge.getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls(new Object[0])); } @Test void getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls_beforeRskip220() { - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(false).when(activations).isActive(eq(RSKIP220), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); - Bridge bridge = getBridgeInstance(mock(BridgeSupport.class), activations); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); assertTrue(bridge.getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls(new Object[0])); } @@ -734,8 +804,8 @@ void getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls_beforeRskip220() { void activeAndRetiringFederationOnly_activeFederationIsNotFromFederateMember_retiringFederationIsNull_throwsVMException() throws Exception { // Given BridgeMethods.BridgeMethodExecutor executor = Bridge.activeAndRetiringFederationOnly( - null, - null + null, + null ); int senderPK = 999; // Sender PK does not belong to Member PKs @@ -942,10 +1012,13 @@ private Bridge getBridgeInstance(Federation activeFederation, Federation retirin Transaction rskTxMock = mock(Transaction.class); doReturn(new RskAddress(key.getAddress())).when(rskTxMock).getSender(any(SignatureCache.class)); - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP143), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); - return getBridgeInstance(rskTxMock, bridgeSupportMock, activations, signatureCache); + return bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); } private Bridge getBridgeInstance(Federation activeFederation, Federation retiringFederation, int senderPK, BridgeSupport bridgeSupportMock) { @@ -956,39 +1029,20 @@ private Bridge getBridgeInstance(Federation activeFederation, Federation retirin Transaction rskTxMock = mock(Transaction.class); doReturn(new RskAddress(key.getAddress())).when(rskTxMock).getSender(any(SignatureCache.class)); - ActivationConfig activations = spy(ActivationConfigsForTest.genesis()); - doReturn(true).when(activations).isActive(eq(RSKIP143), anyLong()); - - return getBridgeInstance(rskTxMock, bridgeSupportMock, activations, signatureCache); - } - - /** - * Gets a bridge instance mocking the transaction and BridgeSupportFactory - * - * @param txMock Provide the transaction to be used - * @param bridgeSupportInstance Provide the bridgeSupport to be used - * @param activationConfig Provide the activationConfig to be used - * @return Bridge instance - */ - private Bridge getBridgeInstance(Transaction txMock, BridgeSupport bridgeSupportInstance, ActivationConfig activationConfig, SignatureCache signatureCache) { - BridgeSupportFactory bridgeSupportFactoryMock = mock(BridgeSupportFactory.class); - - when(bridgeSupportFactoryMock.newInstance(any(), any(), any(), any())).thenReturn(bridgeSupportInstance); - Bridge bridge = new Bridge(PrecompiledContracts.BRIDGE_ADDR, constants, activationConfig, bridgeSupportFactoryMock, signatureCache); - bridge.init(txMock, getGenesisBlock(), null, null, null, null); - return bridge; - } + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); - private Bridge getBridgeInstance(BridgeSupport bridgeSupportInstance, ActivationConfig activationConfig) { - return getBridgeInstance(mock(Transaction.class), bridgeSupportInstance, activationConfig, signatureCache); + return bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); } @Deprecated private Bridge getBridgeInstance(BridgeSupport bridgeSupportInstance) { - return getBridgeInstance(bridgeSupportInstance, activationConfig); - } - - private Block getGenesisBlock() { - return new BlockGenerator().getGenesisBlock(); + return bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportInstance) + .build(); } } diff --git a/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java new file mode 100644 index 00000000000..0ac87c9f5ea --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java @@ -0,0 +1,102 @@ +package co.rsk.test.builders; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import co.rsk.blockchain.utils.BlockGenerator; +import co.rsk.core.RskAddress; +import co.rsk.peg.Bridge; +import co.rsk.peg.BridgeSupport; +import co.rsk.peg.BridgeSupportFactory; +import org.ethereum.config.Constants; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.core.Block; +import org.ethereum.core.BlockTxSignatureCache; +import org.ethereum.core.ReceivedTxSignatureCache; +import org.ethereum.core.SignatureCache; +import org.ethereum.core.Transaction; +import org.ethereum.vm.PrecompiledContractArgs; +import org.ethereum.vm.PrecompiledContractArgsBuilder; +import org.ethereum.vm.PrecompiledContracts; + +public class BridgeBuilder { + private RskAddress contractAddress; + private Constants constants; + private ActivationConfig activationConfig; + private BridgeSupportFactory bridgeSupportFactory; + private SignatureCache signatureCache; + + private Transaction transaction; + private Block executionBlock; + + public BridgeBuilder() { + bridgeSupportFactory = mock(BridgeSupportFactory.class); + when(bridgeSupportFactory.newInstance( + any(), + any(), + any(), + any()) + ).thenReturn(mock(BridgeSupport.class)); + + constants = Constants.regtest(); + contractAddress = PrecompiledContracts.BRIDGE_ADDR; + signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); + + transaction = mock(Transaction.class); + executionBlock = new BlockGenerator().getGenesisBlock(); + } + + public BridgeBuilder contractAddress(RskAddress contractAddress) { + this.contractAddress = contractAddress; + return this; + } + + public BridgeBuilder constants(Constants constants) { + this.constants = constants; + return this; + } + + public BridgeBuilder activationConfig(ActivationConfig activationConfig) { + this.activationConfig = activationConfig; + return this; + } + + public BridgeBuilder signatureCache(SignatureCache signatureCache) { + this.signatureCache = signatureCache; + return this; + } + + public BridgeBuilder bridgeSupport(BridgeSupport bridgeSupport) { + when(bridgeSupportFactory.newInstance(any(), any(), any(), any())).thenReturn(bridgeSupport); + return this; + } + + public BridgeBuilder transaction(Transaction transaction) { + this.transaction = transaction; + return this; + } + + public BridgeBuilder executionBlock(Block executionBlock) { + this.executionBlock = executionBlock; + return this; + } + + public Bridge build() { + Bridge bridge = new Bridge( + contractAddress, + constants, + activationConfig, + bridgeSupportFactory, + signatureCache + ); + + PrecompiledContractArgs args = PrecompiledContractArgsBuilder.builder() + .transaction(transaction) + .executionBlock(executionBlock) + .build(); + bridge.init(args); + + return bridge; + } +} From d417ce753e74878aceb62b68b564696d8167aec4 Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 16 Jan 2024 12:31:15 -0300 Subject: [PATCH 091/137] Refactor remaining Bridge tests --- .../src/test/java/co/rsk/peg/BridgeTest.java | 244 +++++++++--------- 1 file changed, 129 insertions(+), 115 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 8bff43fc576..ee970a07e36 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1,9 +1,7 @@ package co.rsk.peg; -import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.*; @@ -28,7 +26,6 @@ import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; import org.ethereum.vm.exception.VMException; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -38,13 +35,11 @@ class BridgeTest { private Constants constants; - private ActivationConfig activationConfig; private BridgeBuilder bridgeBuilder; @BeforeEach void resetConfigToRegTest() { constants = Constants.regtest(); - activationConfig = spy(ActivationConfigsForTest.genesis()); bridgeBuilder = new BridgeBuilder(); } @@ -809,70 +804,95 @@ void activeAndRetiringFederationOnly_activeFederationIsNotFromFederateMember_ret ); int senderPK = 999; // Sender PK does not belong to Member PKs - Integer[] memberPKs = new Integer[]{100, 200, 300, 400, 500, 600}; + Integer[] memberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; Federation activeFederation = FederationTestUtils.getFederation(memberPKs); - Bridge bridge = getBridgeInstance(activeFederation, null, senderPK); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + doReturn(null).when(bridgeSupportMock).getRetiringFederation(); - // Then - try { - executor.execute(bridge, null); - fail("VMException should be thrown!"); - } catch (VMException vme) { - assertEquals( - "Sender is not part of the active or retiring federations, so he is not enabled to call the function 'null'", - vme.getMessage() - ); - } + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + Transaction rskTxMock = mock(Transaction.class); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); + + assertThrows(VMException.class, () -> executor.execute(bridge, null)); } @Test void activeAndRetiringFederationOnly_activeFederationIsNotFromFederateMember_retiringFederationIsNotNull_retiringFederationIsNotFromFederateMember_throwsVMException() throws Exception { // Given BridgeMethods.BridgeMethodExecutor executor = Bridge.activeAndRetiringFederationOnly( - null, - null + null, + null ); int senderPK = 999; // Sender PK does not belong to Member PKs of active nor retiring fed - Integer[] activeMemberPKs = new Integer[]{100, 200, 300, 400, 500, 600}; - Integer[] retiringMemberPKs = new Integer[]{101, 202, 303, 404, 505, 606}; + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Integer[] retiringMemberPKs = new Integer[]{ 101, 202, 303, 404, 505, 606 }; Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); Federation retiringFederation = FederationTestUtils.getFederation(retiringMemberPKs); - Bridge bridge = getBridgeInstance(activeFederation, retiringFederation, senderPK); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + doReturn(retiringFederation).when(bridgeSupportMock).getRetiringFederation(); - // Then - try { - executor.execute(bridge, null); - fail("VMException should be thrown!"); - } catch (VMException vme) { - assertEquals( - "Sender is not part of the active or retiring federations, so he is not enabled to call the function 'null'", - vme.getMessage() - ); - } + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + Transaction rskTxMock = mock(Transaction.class); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); + + assertThrows(VMException.class, () -> executor.execute(bridge, null)); } @Test void activeAndRetiringFederationOnly_activeFederationIsFromFederateMember_OK() throws Exception { // Given BridgeMethods.BridgeMethodExecutor decorate = mock( - BridgeMethods.BridgeMethodExecutor.class + BridgeMethods.BridgeMethodExecutor.class ); BridgeMethods.BridgeMethodExecutor executor = Bridge.activeAndRetiringFederationOnly( - decorate, - null + decorate, + null ); int senderPK = 101; // Sender PK belongs to active federation member PKs - Integer[] memberPKs = new Integer[]{100, 200, 300, 400, 500, 600}; - + Integer[] memberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; Federation activeFederation = FederationTestUtils.getFederation(memberPKs); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(activeFederation, null, senderPK, bridgeSupportMock); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + doReturn(null).when(bridgeSupportMock).getRetiringFederation(); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + Transaction rskTxMock = mock(Transaction.class); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); // When executor.execute(bridge, null); @@ -887,22 +907,36 @@ void activeAndRetiringFederationOnly_activeFederationIsFromFederateMember_OK() t void activeAndRetiringFederationOnly_activeFederationIsNotFromFederateMember_retiringFederationIsNotNull_retiringFederationIsFromFederateMember_OK() throws Exception { // Given BridgeMethods.BridgeMethodExecutor decorate = mock( - BridgeMethods.BridgeMethodExecutor.class + BridgeMethods.BridgeMethodExecutor.class ); BridgeMethods.BridgeMethodExecutor executor = Bridge.activeAndRetiringFederationOnly( - decorate, - null + decorate, + null ); int senderPK = 405; // Sender PK belongs to retiring federation member PKs - Integer[] activeMemberPKs = new Integer[]{100, 200, 300, 400, 500, 600}; - Integer[] retiringMemberPKs = new Integer[]{101, 202, 303, 404, 505, 606}; + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Integer[] retiringMemberPKs = new Integer[]{ 101, 202, 303, 404, 505, 606 }; Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); Federation retiringFederation = FederationTestUtils.getFederation(retiringMemberPKs); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(activeFederation, retiringFederation, senderPK, bridgeSupportMock); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + doReturn(retiringFederation).when(bridgeSupportMock).getRetiringFederation(); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + Transaction rskTxMock = mock(Transaction.class); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + + ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); // When executor.execute(bridge, null); @@ -915,134 +949,114 @@ void activeAndRetiringFederationOnly_activeFederationIsNotFromFederateMember_ret @Test void getNextPegoutCreationBlockNumber_before_RSKIP271_activation() throws VMException { - doReturn(false).when(activationConfig).isActive(eq(RSKIP271), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] data = BridgeMethods.GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER.getFunction().encode(); - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void getNextPegoutCreationBlockNumber_after_RSKIP271_activation() throws VMException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP271), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.hop400(); + long nextPegoutCreationHeight = 1L; BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + when(bridgeSupportMock.getNextPegoutCreationBlockNumber()).thenReturn(nextPegoutCreationHeight); - when(bridgeSupportMock.getNextPegoutCreationBlockNumber()).thenReturn(1L); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); CallTransaction.Function function = BridgeMethods.GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER.getFunction(); byte[] data = function.encode(); byte[] result = bridge.execute(data); + BigInteger decodedResult = (BigInteger) function.decodeResult(result)[0]; + + assertEquals(nextPegoutCreationHeight, decodedResult.longValue()); - assertEquals(1L, ((BigInteger)function.decodeResult(result)[0]).longValue()); // Also test the method itself - assertEquals(1L, bridge.getNextPegoutCreationBlockNumber(new Object[]{ })); + long resultFromTheBridge = bridge.getNextPegoutCreationBlockNumber(new Object[]{}); + assertEquals(nextPegoutCreationHeight, resultFromTheBridge); } @Test void getQueuedPegoutsCount_before_RSKIP271_activation() throws VMException { - doReturn(false).when(activationConfig).isActive(eq(RSKIP271), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] data = BridgeMethods.GET_QUEUED_PEGOUTS_COUNT.getFunction().encode(); - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void getQueuedPegoutsCount_after_RSKIP271_activation() throws VMException, IOException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP271), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.hop400(); + int queuedPegoutsCount = 1; BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); - - when(bridgeSupportMock.getQueuedPegoutsCount()).thenReturn(1); + when(bridgeSupportMock.getQueuedPegoutsCount()).thenReturn(queuedPegoutsCount); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .build(); CallTransaction.Function function = BridgeMethods.GET_QUEUED_PEGOUTS_COUNT.getFunction(); byte[] data = function.encode(); byte[] result = bridge.execute(data); + BigInteger decodedResult = (BigInteger) function.decodeResult(result)[0]; + + assertEquals(queuedPegoutsCount, decodedResult.intValue()); - assertEquals(1, ((BigInteger)function.decodeResult(result)[0]).intValue()); // Also test the method itself - assertEquals(1, bridge.getQueuedPegoutsCount(new Object[]{ })); + int resultFromTheBridge = bridge.getQueuedPegoutsCount(new Object[]{}); + assertEquals(queuedPegoutsCount, resultFromTheBridge); } @Test void getEstimatedFeesForNextPegOutEvent_before_RSKIP271_activation() throws VMException { - doReturn(false).when(activationConfig).isActive(eq(RSKIP271), anyLong()); + ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .build(); byte[] data = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction().encode(); - assertNull(bridge.execute(data)); + assertThrows(VMException.class, () -> bridge.execute(data)); } @Test void getEstimatedFeesForNextPegOutEvent_after_RSKIP271_activation() throws VMException, IOException { - doReturn(true).when(activationConfig).isActive(eq(RSKIP271), anyLong()); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = getBridgeInstance(bridgeSupportMock); - - when(bridgeSupportMock.getEstimatedFeesForNextPegOutEvent()).thenReturn(Coin.SATOSHI); - - CallTransaction.Function function = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction(); - byte[] data = function.encode(); - byte[] result = bridge.execute(data); - - assertEquals(Coin.SATOSHI.value, ((BigInteger)function.decodeResult(result)[0]).intValue()); - // Also test the method itself - assertEquals(Coin.SATOSHI.value, bridge.getEstimatedFeesForNextPegOutEvent(new Object[]{ })); - } + ActivationConfig activationConfig = ActivationConfigsForTest.hop400(); - private Bridge getBridgeInstance(Federation activeFederation, Federation retiringFederation, int senderPK) { + Coin estimatedFeesForNextPegout = Coin.SATOSHI; BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); - doReturn(retiringFederation).when(bridgeSupportMock).getRetiringFederation(); + when(bridgeSupportMock.getEstimatedFeesForNextPegOutEvent()).thenReturn(estimatedFeesForNextPegout); - ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); - Transaction rskTxMock = mock(Transaction.class); - doReturn(new RskAddress(key.getAddress())).when(rskTxMock).getSender(any(SignatureCache.class)); - - ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); - - return bridgeBuilder - .transaction(rskTxMock) + Bridge bridge = bridgeBuilder .activationConfig(activationConfig) .bridgeSupport(bridgeSupportMock) .build(); - } - private Bridge getBridgeInstance(Federation activeFederation, Federation retiringFederation, int senderPK, BridgeSupport bridgeSupportMock) { - doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); - doReturn(retiringFederation).when(bridgeSupportMock).getRetiringFederation(); - - ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); - Transaction rskTxMock = mock(Transaction.class); - doReturn(new RskAddress(key.getAddress())).when(rskTxMock).getSender(any(SignatureCache.class)); - - ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); + CallTransaction.Function function = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction(); + byte[] data = function.encode(); + byte[] result = bridge.execute(data); + BigInteger decodedResult = (BigInteger) function.decodeResult(result)[0]; - return bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .build(); - } + assertEquals(estimatedFeesForNextPegout.getValue(), decodedResult.longValue()); - @Deprecated - private Bridge getBridgeInstance(BridgeSupport bridgeSupportInstance) { - return bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportInstance) - .build(); + // Also test the method itself + long resultFromTheBridge = bridge.getEstimatedFeesForNextPegOutEvent(new Object[]{}); + assertEquals(estimatedFeesForNextPegout.getValue(), resultFromTheBridge); } } From 4f83611dd7015a48b7919e6a0e17c0f47c9bb995 Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 16 Jan 2024 14:17:18 -0300 Subject: [PATCH 092/137] Use mainnet config by default to run Bridge tests --- .../src/test/java/co/rsk/peg/BridgeTest.java | 35 +++++++++++-------- .../co/rsk/test/builders/BridgeBuilder.java | 2 +- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index ee970a07e36..50d4741fd01 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -8,7 +8,9 @@ import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.store.BlockStoreException; +import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; +import co.rsk.config.BridgeTestNetConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.flyover.FlyoverTxResponseCodes; @@ -34,12 +36,12 @@ class BridgeTest { - private Constants constants; + private NetworkParameters networkParameters; private BridgeBuilder bridgeBuilder; @BeforeEach - void resetConfigToRegTest() { - constants = Constants.regtest(); + void resetConfigToMainnet() { + networkParameters = BridgeMainNetConstants.getInstance().getBtcParams(); bridgeBuilder = new BridgeBuilder(); } @@ -433,9 +435,9 @@ void registerFlyoverBtcTransaction_before_RSKIP176_activation() { } @Test - void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address_before_RSKIP284_activation_fails() + void registerFlyoverBtcTransaction_after_RSKIP176_activation_testnet_p2sh_refund_address_before_RSKIP284_activation_fails() throws VMException, IOException, BlockStoreException { - NetworkParameters networkParameters = constants.getBridgeConstants().getBtcParams(); + NetworkParameters testnetNetworkParameters = BridgeTestNetConstants.getInstance().getBtcParams(); ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); @@ -454,18 +456,22 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address Bridge bridge = bridgeBuilder .activationConfig(activationConfig) .bridgeSupport(bridgeSupportMock) + .constants(Constants.regtest()) .build(); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); - Address refundBtcAddress = Address.fromBase58(networkParameters, "2MyEXHyt2fXqdFm3r4xXEkTdbwdZm7qFiDP"); + Address refundBtcAddress = Address.fromBase58( + testnetNetworkParameters, + "2MyEXHyt2fXqdFm3r4xXEkTdbwdZm7qFiDP" + ); byte[] refundBtcAddressBytes = BridgeUtils.serializeBtcAddressWithVersion( activationConfig.forBlock(0), refundBtcAddress ); BtcECKey btcECKeyLp = new BtcECKey(); - Address lpBtcAddress = btcECKeyLp.toAddress(networkParameters); + Address lpBtcAddress = btcECKeyLp.toAddress(testnetNetworkParameters); byte[] lpBtcAddressBytes = BridgeUtils.serializeBtcAddressWithVersion( activationConfig.forBlock(0), lpBtcAddress @@ -504,9 +510,9 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address } @Test - void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address_after_RSKIP284_activation_ok() + void registerFlyoverBtcTransaction_after_RSKIP176_activation_testnet_p2sh_refund_address_after_RSKIP284_activation_ok() throws VMException, IOException, BlockStoreException { - NetworkParameters networkParameters = constants.getBridgeConstants().getBtcParams(); + NetworkParameters testnetNetworkParameters = BridgeTestNetConstants.getInstance().getBtcParams(); ActivationConfig activationConfig = ActivationConfigsForTest.hop400(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); @@ -525,18 +531,22 @@ void registerFlyoverBtcTransaction_after_RSKIP176_activation_p2sh_refund_address Bridge bridge = bridgeBuilder .activationConfig(activationConfig) .bridgeSupport(bridgeSupportMock) + .constants(Constants.regtest()) .build(); byte[] value = Sha256Hash.ZERO_HASH.getBytes(); - Address refundBtcAddress = Address.fromBase58(networkParameters, "2MyEXHyt2fXqdFm3r4xXEkTdbwdZm7qFiDP"); + Address refundBtcAddress = Address.fromBase58( + testnetNetworkParameters, + "2MyEXHyt2fXqdFm3r4xXEkTdbwdZm7qFiDP" + ); byte[] refundBtcAddressBytes = BridgeUtils.serializeBtcAddressWithVersion( activationConfig.forBlock(0), refundBtcAddress ); BtcECKey btcECKeyLp = new BtcECKey(); - Address lpBtcAddress = btcECKeyLp.toAddress(networkParameters); + Address lpBtcAddress = btcECKeyLp.toAddress(testnetNetworkParameters); byte[] lpBtcAddressBytes = BridgeUtils.serializeBtcAddressWithVersion( activationConfig.forBlock(0), lpBtcAddress @@ -643,7 +653,6 @@ void receiveHeader_before_RSKIP200() throws VMException { .activationConfig(activationConfig) .build(); - NetworkParameters networkParameters = constants.bridgeConstants.getBtcParams(); co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock( networkParameters, 1, @@ -685,7 +694,6 @@ void receiveHeader_after_RSKIP200_Ok() throws VMException { .activationConfig(activationConfig) .build(); - NetworkParameters networkParameters = constants.bridgeConstants.getBtcParams(); co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock( networkParameters, 1, @@ -716,7 +724,6 @@ void receiveHeader_bridgeSupport_Exception() throws IOException, BlockStoreExcep .bridgeSupport(bridgeSupportMock) .build(); - NetworkParameters networkParameters = constants.bridgeConstants.getBtcParams(); co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock( networkParameters, 1, diff --git a/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java index 0ac87c9f5ea..f9cd60ed0ca 100644 --- a/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java +++ b/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java @@ -39,7 +39,7 @@ public BridgeBuilder() { any()) ).thenReturn(mock(BridgeSupport.class)); - constants = Constants.regtest(); + constants = Constants.mainnet(); contractAddress = PrecompiledContracts.BRIDGE_ADDR; signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); From af64954a960503f72a33107305bd563adc04c152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mat=C3=ADas=20Marquez?= Date: Mon, 15 Jan 2024 15:03:04 -0300 Subject: [PATCH 093/137] adding test for limiting precompiled call types --- .../test/java/co/rsk/test/DslFilesTest.java | 31 +++++++++++++ .../test/resources/dsl/bridgeDelegateCall.txt | 43 +++++++++++++++++++ 2 files changed, 74 insertions(+) create mode 100644 rskj-core/src/test/resources/dsl/bridgeDelegateCall.txt diff --git a/rskj-core/src/test/java/co/rsk/test/DslFilesTest.java b/rskj-core/src/test/java/co/rsk/test/DslFilesTest.java index 121f38fc4bb..cdac94ab829 100644 --- a/rskj-core/src/test/java/co/rsk/test/DslFilesTest.java +++ b/rskj-core/src/test/java/co/rsk/test/DslFilesTest.java @@ -89,6 +89,37 @@ void runCreate01Resource() throws FileNotFoundException, DslProcessorException { Assertions.assertEquals(BigIntegers.fromUnsignedByteArray(Hex.decode("fd59")), gasUsed); } + @Test + void runBridgeDelegateCallResource() throws FileNotFoundException, DslProcessorException { + DslParser parser = DslParser.fromResource("dsl/bridgeDelegateCall.txt"); + World world = new World(); + WorldDslProcessor processor = new WorldDslProcessor(world); + processor.processCommands(parser); + + /// In this test we call the bridge with different methods + /// CALL, DELEGATECALL, CALLCODE, STATICCALL + /// The only one having to produce a releaseBtc blog is the CALL opcode which is the first one + /// This test relies on the current bridge behavior of emitting logs + Transaction transaction = world.getTransactionByName("tx01"); + Assertions.assertNotNull(transaction); + TransactionInfo txinfo = world.getBlockChain().getTransactionInfo(transaction.getHash().getBytes()); + Assertions.assertEquals(1, txinfo.getReceipt().getLogInfoList().size()); + + transaction = world.getTransactionByName("tx02"); + Assertions.assertNotNull(transaction); + txinfo = world.getBlockChain().getTransactionInfo(transaction.getHash().getBytes()); + Assertions.assertEquals(0, txinfo.getReceipt().getLogInfoList().size()); + + transaction = world.getTransactionByName("tx03"); + Assertions.assertNotNull(transaction); + txinfo = world.getBlockChain().getTransactionInfo(transaction.getHash().getBytes()); + Assertions.assertEquals(0, txinfo.getReceipt().getLogInfoList().size()); + + transaction = world.getTransactionByName("tx04"); + Assertions.assertNotNull(transaction); + txinfo = world.getBlockChain().getTransactionInfo(transaction.getHash().getBytes()); + Assertions.assertEquals(0, txinfo.getReceipt().getLogInfoList().size()); + } @Test void runCreate02Resource() throws FileNotFoundException, DslProcessorException { //byte[] code2 =Hex.decode("608060405234801561001057600080fd5b504361001a61017b565b80828152602001915050604051809103906000f080158015610040573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f80ae3ec8027d0c5d1f3e47fb4bf1d9fc28225e7f4bcb1971b36efb81fe40574d6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663209652556040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b15801561012657600080fd5b505af115801561013a573d6000803e3d6000fd5b505050506040513d602081101561015057600080fd5b81019080805190602001909291905050506040518082815260200191505060405180910390a161018b565b6040516101e38061028283390190565b60e9806101996000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806361bc221a146044575b600080fd5b348015604f57600080fd5b5060566098565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815600a165627a7a7230582091284634a2c8e5cbd0e4153a1422a41670914d8ef8b4f7dc71bd54cf80baf8f50029608060405234801561001057600080fd5b506040516020806101e383398101806040528101908080519060200190929190505050806000819055507f06acbfb32bcf8383f3b0a768b70ac9ec234ea0f2d3b9c77fa6a2de69b919aad16000546040518082815260200191505060405180910390a150610160806100836000396000f30060806040526004361061004c576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680632096525514610051578063d09de08a1461007c575b600080fd5b34801561005d57600080fd5b50610066610093565b6040518082815260200191505060405180910390f35b34801561008857600080fd5b506100916100d6565b005b60007f1ee041944547858a75ebef916083b6d4f5ae04bea9cd809334469dd07dbf441b6000546040518082815260200191505060405180910390a1600054905090565b600080815460010191905081905550600160026000548115156100f557fe5b061415157f6e61ef44ac2747ff8b84d353a908eb8bd5c3fb118334d57698c5cfc7041196ad6000546040518082815260200191505060405180910390a25600a165627a7a7230582041617f72986040ac8590888e68e070d9d05aeb99361c0c77d1f67540db5ff6b10029"); diff --git a/rskj-core/src/test/resources/dsl/bridgeDelegateCall.txt b/rskj-core/src/test/resources/dsl/bridgeDelegateCall.txt new file mode 100644 index 00000000000..610b47b2ad1 --- /dev/null +++ b/rskj-core/src/test/resources/dsl/bridgeDelegateCall.txt @@ -0,0 +1,43 @@ +account_new acc1 10000000 + +transaction_build tx01 + sender acc1 + receiverAddress 00 + value 0 + data 5f600060006000600073000000000000000000000000000000000100000663005b8d80f1 + gas 1200000 + build + +transaction_build tx02 + sender acc1 + receiverAddress 00 + value 0 + data 5f600060006000600073000000000000000000000000000000000100000663005b8d80f4 + gas 1200000 + nonce 1 + build + +transaction_build tx03 + sender acc1 + receiverAddress 00 + value 0 + data 5f600060006000600073000000000000000000000000000000000100000663005b8d80f2 + gas 1200000 + nonce 2 + build + +transaction_build tx04 + sender acc1 + receiverAddress 00 + value 0 + data 5f600060006000600073000000000000000000000000000000000100000663005b8d80fa + gas 1200000 + nonce 3 + build + +block_build b01 + parent g00 + transactions tx01 tx02 tx03 tx04 + build + +block_connect b01 \ No newline at end of file From 4b7e4e279fc1294f1ba80321f54b301de1bce94d Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 17 Jan 2024 18:15:24 -0300 Subject: [PATCH 094/137] Add MsgType parameter to BridgeBuilder --- .../co/rsk/test/builders/BridgeBuilder.java | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java index f9cd60ed0ca..a11b6f05284 100644 --- a/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java +++ b/rskj-core/src/test/java/co/rsk/test/builders/BridgeBuilder.java @@ -16,6 +16,8 @@ import org.ethereum.core.ReceivedTxSignatureCache; import org.ethereum.core.SignatureCache; import org.ethereum.core.Transaction; +import org.ethereum.vm.MessageCall; +import org.ethereum.vm.MessageCall.MsgType; import org.ethereum.vm.PrecompiledContractArgs; import org.ethereum.vm.PrecompiledContractArgsBuilder; import org.ethereum.vm.PrecompiledContracts; @@ -24,27 +26,23 @@ public class BridgeBuilder { private RskAddress contractAddress; private Constants constants; private ActivationConfig activationConfig; - private BridgeSupportFactory bridgeSupportFactory; + private BridgeSupport bridgeSupport; private SignatureCache signatureCache; + // Precompiled contract args private Transaction transaction; private Block executionBlock; + private MessageCall.MsgType msgType; public BridgeBuilder() { - bridgeSupportFactory = mock(BridgeSupportFactory.class); - when(bridgeSupportFactory.newInstance( - any(), - any(), - any(), - any()) - ).thenReturn(mock(BridgeSupport.class)); - - constants = Constants.mainnet(); contractAddress = PrecompiledContracts.BRIDGE_ADDR; + constants = Constants.mainnet(); + bridgeSupport = new BridgeSupportBuilder().build(); signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); transaction = mock(Transaction.class); executionBlock = new BlockGenerator().getGenesisBlock(); + msgType = MsgType.CALL; } public BridgeBuilder contractAddress(RskAddress contractAddress) { @@ -68,7 +66,7 @@ public BridgeBuilder signatureCache(SignatureCache signatureCache) { } public BridgeBuilder bridgeSupport(BridgeSupport bridgeSupport) { - when(bridgeSupportFactory.newInstance(any(), any(), any(), any())).thenReturn(bridgeSupport); + this.bridgeSupport = bridgeSupport; return this; } @@ -82,7 +80,15 @@ public BridgeBuilder executionBlock(Block executionBlock) { return this; } + public BridgeBuilder msgType(MsgType msgType) { + this.msgType = msgType; + return this; + } + public Bridge build() { + BridgeSupportFactory bridgeSupportFactory = mock(BridgeSupportFactory.class); + when(bridgeSupportFactory.newInstance(any(), any(), any(), any())).thenReturn(bridgeSupport); + Bridge bridge = new Bridge( contractAddress, constants, @@ -94,6 +100,7 @@ public Bridge build() { PrecompiledContractArgs args = PrecompiledContractArgsBuilder.builder() .transaction(transaction) .executionBlock(executionBlock) + .msgType(msgType) .build(); bridge.init(args); From 58f1c617159398f1423081149b750d2a627d3e54 Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 17 Jan 2024 18:15:55 -0300 Subject: [PATCH 095/137] Add tests for addFederatorPublicKey Bridge method --- .../src/main/java/co/rsk/peg/Bridge.java | 4 +- .../src/test/java/co/rsk/peg/BridgeTest.java | 50 ++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 9bb0f75dc2b..82e19c0e4cd 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -897,8 +897,8 @@ public Integer addFederatorPublicKey(Object[] args) throws BridgeIllegalArgument } return bridgeSupport.voteFederationChange( - rskTx, - new ABICallSpec("add", new byte[][]{ publicKeyBytes }) + rskTx, + new ABICallSpec("add", new byte[][]{ publicKeyBytes }) ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 50d4741fd01..9c84b1ff1ea 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -24,9 +24,11 @@ import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; +import org.ethereum.vm.MessageCall.MsgType; import org.ethereum.vm.exception.VMException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -646,7 +648,7 @@ void registerFlyoverBtcTransaction_after_RSKIP176_null_parameter() throws VMExce } @Test - void receiveHeader_before_RSKIP200() throws VMException { + void receiveHeader_before_RSKIP200() { ActivationConfig activationConfig = ActivationConfigsForTest.papyrus200(); Bridge bridge = bridgeBuilder @@ -671,7 +673,7 @@ void receiveHeader_before_RSKIP200() throws VMException { } @Test - void receiveHeader_empty_parameter() throws VMException { + void receiveHeader_empty_parameter() { ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); @@ -1066,4 +1068,48 @@ void getEstimatedFeesForNextPegOutEvent_after_RSKIP271_activation() throws VMExc long resultFromTheBridge = bridge.getEstimatedFeesForNextPegOutEvent(new Object[]{}); assertEquals(estimatedFeesForNextPegout.getValue(), resultFromTheBridge); } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addFederatorPublicKey(MsgType msgType, ActivationConfig activationConfig) throws VMException { + String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_FEDERATOR_PUBLIC_KEY; + byte[] data = function.encode(Hex.decode(publicKey)); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); + } + } + + private static Stream msgTypesAndActivations() { + List argumentsList = new ArrayList<>(); + List activationConfigs = Arrays.asList( + ActivationConfigsForTest.orchid(), + ActivationConfigsForTest.wasabi100(), + ActivationConfigsForTest.papyrus200(), + ActivationConfigsForTest.iris300(), + ActivationConfigsForTest.hop400(), + ActivationConfigsForTest.fingerroot500(), + ActivationConfigsForTest.arrowhead600() + ); + + for(MsgType msgType : MsgType.values()) { + for(ActivationConfig activationConfig : activationConfigs) { + argumentsList.add(Arguments.of(msgType, activationConfig)); + } + } + + return argumentsList.stream(); + } } From 0bb602cb2309d83f9aef4b0f6ca3a9a848c5e576 Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 17 Jan 2024 18:51:21 -0300 Subject: [PATCH 096/137] Add tests for addFederatorPublicKeyMultikey Bridge method --- .../src/main/java/co/rsk/peg/Bridge.java | 7 +++-- .../main/java/co/rsk/peg/BridgeMethods.java | 6 ++-- .../src/test/java/co/rsk/peg/BridgeTest.java | 28 +++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 82e19c0e4cd..8ff0ca5974f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -910,8 +910,11 @@ public Integer addFederatorPublicKeyMultikey(Object[] args) throws BridgeIllegal byte[] mstPublicKeyBytes = (byte[]) args[2]; return bridgeSupport.voteFederationChange( - rskTx, - new ABICallSpec("add-multi", new byte[][]{ btcPublicKeyBytes, rskPublicKeyBytes, mstPublicKeyBytes }) + rskTx, + new ABICallSpec( + "add-multi", + new byte[][]{ btcPublicKeyBytes, rskPublicKeyBytes, mstPublicKeyBytes } + ) ); } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index d69de5810e1..d1934a99db0 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -47,9 +47,9 @@ public enum BridgeMethods { ), ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY( CallTransaction.Function.fromSignature( - "addFederatorPublicKeyMultikey", - new String[]{"bytes", "bytes", "bytes"}, - new String[]{"int256"} + "addFederatorPublicKeyMultikey", + new String[]{"bytes", "bytes", "bytes"}, + new String[]{"int256"} ), fixedCost(13000L), (BridgeMethodExecutorTyped) Bridge::addFederatorPublicKeyMultikey, diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 9c84b1ff1ea..7c82f549f21 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1092,6 +1092,34 @@ void addFederatorPublicKey(MsgType msgType, ActivationConfig activationConfig) t } } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addFederatorPublicKeyMultikey(MsgType msgType, ActivationConfig activationConfig) throws VMException { + String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY; + byte[] data = function.encode(Hex.decode(publicKey), Hex.decode(publicKey), Hex.decode(publicKey)); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + private static Stream msgTypesAndActivations() { List argumentsList = new ArrayList<>(); List activationConfigs = Arrays.asList( From c27c86aeae23af328914b768fb88e71f22a7e010 Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 17 Jan 2024 19:03:49 -0300 Subject: [PATCH 097/137] Add tests for addLockWhitelistAddress Bridge method --- .../main/java/co/rsk/peg/BridgeMethods.java | 18 +++++++------- .../src/test/java/co/rsk/peg/BridgeTest.java | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index d1934a99db0..fb499d54afe 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -57,15 +57,15 @@ public enum BridgeMethods { fixedPermission(false) ), ADD_LOCK_WHITELIST_ADDRESS( - CallTransaction.Function.fromSignature( - "addLockWhitelistAddress", - new String[]{"string", "int256"}, - new String[]{"int256"} - ), - fixedCost(25000L), - (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, - activations -> !activations.isActive(RSKIP87), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "addLockWhitelistAddress", + new String[]{"string", "int256"}, + new String[]{"int256"} + ), + fixedCost(25000L), + (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, + activations -> !activations.isActive(RSKIP87), + fixedPermission(false) ), ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 7c82f549f21..640ba8d691b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1120,6 +1120,30 @@ void addFederatorPublicKeyMultikey(MsgType msgType, ActivationConfig activationC } } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + long maxTransferValue = 100_000L; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_LOCK_WHITELIST_ADDRESS; + byte[] data = function.encode(addressBase58, maxTransferValue); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + // Post RSKIP87 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress(any(), any(), any()); + } + } + private static Stream msgTypesAndActivations() { List argumentsList = new ArrayList<>(); List activationConfigs = Arrays.asList( From 84c981412eb7345676cc80c112e12d23d5665e3a Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 17 Jan 2024 19:05:51 -0300 Subject: [PATCH 098/137] Add tests for addOneOffLockWhitelistAddress Bridge method --- .../main/java/co/rsk/peg/BridgeMethods.java | 18 ++++++------ .../src/test/java/co/rsk/peg/BridgeTest.java | 29 +++++++++++++++++++ 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index fb499d54afe..466ad0c73d2 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -68,15 +68,15 @@ public enum BridgeMethods { fixedPermission(false) ), ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS( - CallTransaction.Function.fromSignature( - "addOneOffLockWhitelistAddress", - new String[]{"string", "int256"}, - new String[]{"int256"} - ), - fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS - (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, - activations -> activations.isActive(RSKIP87), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "addOneOffLockWhitelistAddress", + new String[]{"string", "int256"}, + new String[]{"int256"} + ), + fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS + (BridgeMethodExecutorTyped) Bridge::addOneOffLockWhitelistAddress, + activations -> activations.isActive(RSKIP87), + fixedPermission(false) ), ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS( CallTransaction.Function.fromSignature( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 640ba8d691b..872c30b9949 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1144,6 +1144,35 @@ void addLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) } } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addOneOffLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + long maxTransferValue = 100_000L; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS; + byte[] data = function.encode(addressBase58, maxTransferValue); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress(any(), any(), any()); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + private static Stream msgTypesAndActivations() { List argumentsList = new ArrayList<>(); List activationConfigs = Arrays.asList( From 4ee6b00ae386aae2b53ce999fbdc4f55b0ebd685 Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 17 Jan 2024 19:08:55 -0300 Subject: [PATCH 099/137] Add tests for addUnlimitedLockWhitelistAddress Bridge method --- .../main/java/co/rsk/peg/BridgeMethods.java | 18 ++++---- .../src/test/java/co/rsk/peg/BridgeTest.java | 43 ++++++++++++++++++- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 466ad0c73d2..31cdbe7a0b9 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -79,15 +79,15 @@ public enum BridgeMethods { fixedPermission(false) ), ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS( - CallTransaction.Function.fromSignature( - "addUnlimitedLockWhitelistAddress", - new String[]{"string"}, - new String[]{"int256"} - ), - fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS - (BridgeMethodExecutorTyped) Bridge::addUnlimitedLockWhitelistAddress, - activations -> activations.isActive(RSKIP87), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "addUnlimitedLockWhitelistAddress", + new String[]{"string"}, + new String[]{"int256"} + ), + fixedCost(25000L), // using same gas estimation as ADD_LOCK_WHITELIST_ADDRESS + (BridgeMethodExecutorTyped) Bridge::addUnlimitedLockWhitelistAddress, + activations -> activations.isActive(RSKIP87), + fixedPermission(false) ), ADD_SIGNATURE( CallTransaction.Function.fromSignature( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 872c30b9949..a7f11a98165 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1140,7 +1140,11 @@ void addLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) assertThrows(VMException.class, () -> bridge.execute(data)); } else { bridge.execute(data); - verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress(any(), any(), any()); + verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( + any(), + any(), + any() + ); } } @@ -1165,7 +1169,42 @@ void addOneOffLockWhitelistAddress(MsgType msgType, ActivationConfig activationC assertThrows(VMException.class, () -> bridge.execute(data)); } else { bridge.execute(data); - verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress(any(), any(), any()); + verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( + any(), + any(), + any() + ); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addUnlimitedLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS; + byte[] data = function.encode(addressBase58); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addUnlimitedLockWhitelistAddress( + any(), + any() + ); } } else { // Pre RSKIP87 this method is not enabled, should fail for all message types From f4797e1df0f3ae55c720824262add141216ea7a7 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 18 Jan 2024 19:02:42 -0300 Subject: [PATCH 100/137] Add tests for addSignature Bridge method --- .../src/test/java/co/rsk/peg/BridgeTest.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index a7f11a98165..491ae3b060c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1,5 +1,6 @@ package co.rsk.peg; +import static co.rsk.peg.PegTestUtils.createHash3; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -1212,6 +1213,48 @@ void addUnlimitedLockWhitelistAddress(MsgType msgType, ActivationConfig activati } } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addSignatures(MsgType msgType, ActivationConfig activationConfig) throws Exception { + String pegnatoryPublicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + String signature = "3045022100a0963cea7551eb3174a3470c6ed25cda901c4b1093818d4d54792b87508820220220325f93b5aecc98385a664328e68d1cec7a2a2fe81810a7692358bd870aeecb74"; + List derEncodedSigs = Collections.singletonList(Hex.decode(signature)); + Keccak256 rskTxHash = createHash3(1); + + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + Transaction rskTxMock = mock(Transaction.class); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_SIGNATURE; + byte[] data = function.encode(Hex.decode(pegnatoryPublicKey), derEncodedSigs, rskTxHash.getBytes()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addSignature( + any(), + any(), + any() + ); + } + } + private static Stream msgTypesAndActivations() { List argumentsList = new ArrayList<>(); List activationConfigs = Arrays.asList( From 9b8c7b20f0c573c351fe6489397bac84700ad9f8 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 18 Jan 2024 19:09:46 -0300 Subject: [PATCH 101/137] Add tests for commitFederation Bridge method --- .../src/main/java/co/rsk/peg/Bridge.java | 4 +-- .../main/java/co/rsk/peg/BridgeMethods.java | 16 ++++++------ .../src/test/java/co/rsk/peg/BridgeTest.java | 26 +++++++++++++++++++ 3 files changed, 36 insertions(+), 10 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 8ff0ca5974f..e4f7771d040 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -930,8 +930,8 @@ public Integer commitFederation(Object[] args) throws BridgeIllegalArgumentExcep } return bridgeSupport.voteFederationChange( - rskTx, - new ABICallSpec("commit", new byte[][]{ hash }) + rskTx, + new ABICallSpec("commit", new byte[][]{ hash }) ); } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 31cdbe7a0b9..6f8f9649aa3 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -100,14 +100,14 @@ public enum BridgeMethods { fixedPermission(false) ), COMMIT_FEDERATION( - CallTransaction.Function.fromSignature( - "commitFederation", - new String[]{"bytes"}, - new String[]{"int256"} - ), - fixedCost(38000L), - (BridgeMethodExecutorTyped) Bridge::commitFederation, - fixedPermission(false) + CallTransaction.Function.fromSignature( + "commitFederation", + new String[]{"bytes"}, + new String[]{"int256"} + ), + fixedCost(38000L), + (BridgeMethodExecutorTyped) Bridge::commitFederation, + fixedPermission(false) ), CREATE_FEDERATION( CallTransaction.Function.fromSignature( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 491ae3b060c..3bc0989a5ae 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1255,6 +1255,32 @@ void addSignatures(MsgType msgType, ActivationConfig activationConfig) throws Ex } } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void commitFederation(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Keccak256 commitTransactionHash = createHash3(2); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.COMMIT_FEDERATION; + byte[] data = function.encode(commitTransactionHash.getBytes()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange( + any(), + any() + ); + } + } + private static Stream msgTypesAndActivations() { List argumentsList = new ArrayList<>(); List activationConfigs = Arrays.asList( From 851ba77ef9a3dcd82f9ebe5ea4f46b7e886ba520 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 18 Jan 2024 19:20:41 -0300 Subject: [PATCH 102/137] Add tests for getBtcBlockchainBestChainHeight Bridge method --- .../main/java/co/rsk/peg/BridgeMethods.java | 18 ++++++------ .../src/test/java/co/rsk/peg/BridgeTest.java | 28 +++++++++++++++++++ 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 6f8f9649aa3..c2dacc626e4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -120,15 +120,15 @@ public enum BridgeMethods { fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT( - CallTransaction.Function.fromSignature( - "getBtcBlockchainBestChainHeight", - new String[]{}, - new String[]{"int"} - ), - fixedCost(19000L), - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestChainHeight, - fromMethod(Bridge::getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcBlockchainBestChainHeight", + new String[]{}, + new String[]{"int"} + ), + fixedCost(19000L), + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestChainHeight, + fromMethod(Bridge::getBtcBlockchainBestChainHeightOnlyAllowsLocalCalls), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT( CallTransaction.Function.fromSignature( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 3bc0989a5ae..04fb6601c4e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1281,6 +1281,34 @@ void commitFederation(MsgType msgType, ActivationConfig activationConfig) throws } } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBestChainHeight(MsgType msgType, ActivationConfig activationConfig) + throws VMException, BlockStoreException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBestChainHeight(); + } + } + private static Stream msgTypesAndActivations() { List argumentsList = new ArrayList<>(); List activationConfigs = Arrays.asList( From 3e52710060509c34e0fe13311212e1da24e2f8b7 Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 23 Jan 2024 16:57:28 -0300 Subject: [PATCH 103/137] Add tests fro various gettter Bridge methods --- .../src/main/java/co/rsk/peg/Bridge.java | 6 +- .../main/java/co/rsk/peg/BridgeMethods.java | 372 +++++------ .../src/test/java/co/rsk/peg/BridgeTest.java | 604 +++++++++++++++++- 3 files changed, 792 insertions(+), 190 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index e4f7771d040..5028768f10b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -677,7 +677,7 @@ public byte[] getBtcBlockchainBlockHashAtDepth(Object[] args) throws VMException logger.trace("getBtcBlockchainBlockHashAtDepth"); int depth = ((BigInteger) args[0]).intValue(); - Sha256Hash blockHash = null; + Sha256Hash blockHash; try { blockHash = bridgeSupport.getBtcBlockchainBlockHashAtDepth(depth); } catch (Exception e) { @@ -880,8 +880,8 @@ public Integer createFederation(Object[] args) throws BridgeIllegalArgumentExcep logger.trace("createFederation"); return bridgeSupport.voteFederationChange( - rskTx, - new ABICallSpec("create", new byte[][]{}) + rskTx, + new ABICallSpec("create", new byte[][]{}) ); } diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index c2dacc626e4..333596cf07c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -110,14 +110,14 @@ public enum BridgeMethods { fixedPermission(false) ), CREATE_FEDERATION( - CallTransaction.Function.fromSignature( - "createFederation", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(11000L), - (BridgeMethodExecutorTyped) Bridge::createFederation, - fixedPermission(false) + CallTransaction.Function.fromSignature( + "createFederation", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(11000L), + (BridgeMethodExecutorTyped) Bridge::createFederation, + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT( CallTransaction.Function.fromSignature( @@ -131,220 +131,220 @@ public enum BridgeMethods { CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT( - CallTransaction.Function.fromSignature( - "getBtcBlockchainInitialBlockHeight", - new String[]{}, - new String[]{"int"} - ), - fixedCost(20000L), - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainInitialBlockHeight, - activations -> activations.isActive(RSKIP89), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcBlockchainInitialBlockHeight", + new String[]{}, + new String[]{"int"} + ), + fixedCost(20000L), + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainInitialBlockHeight, + activations -> activations.isActive(RSKIP89), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR( - CallTransaction.Function.fromSignature( - "getBtcBlockchainBlockLocator", - new String[]{}, - new String[]{"string[]"} - ), - fixedCost(76000L), - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockLocator, - activations -> !activations.isActive(RSKIP89), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcBlockchainBlockLocator", + new String[]{}, + new String[]{"string[]"} + ), + fixedCost(76000L), + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockLocator, + activations -> !activations.isActive(RSKIP89), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH( - CallTransaction.Function.fromSignature( - "getBtcBlockchainBlockHashAtDepth", - new String[]{"int256"}, - new String[]{"bytes"} - ), - fixedCost(20000L), - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHashAtDepth, - activations -> activations.isActive(RSKIP89), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcBlockchainBlockHashAtDepth", + new String[]{"int256"}, + new String[]{"bytes"} + ), + fixedCost(20000L), + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHashAtDepth, + activations -> activations.isActive(RSKIP89), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_TRANSACTION_CONFIRMATIONS( - CallTransaction.Function.fromSignature( - "getBtcTransactionConfirmations", - new String[]{"bytes32", "bytes32", "uint256", "bytes32[]"}, - new String[]{"int256"} - ), - fromMethod(Bridge::getBtcTransactionConfirmationsGetCost), - (BridgeMethodExecutorTyped) Bridge::getBtcTransactionConfirmations, - activations -> activations.isActive(RSKIP122), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcTransactionConfirmations", + new String[]{"bytes32", "bytes32", "uint256", "bytes32[]"}, + new String[]{"int256"} + ), + fromMethod(Bridge::getBtcTransactionConfirmationsGetCost), + (BridgeMethodExecutorTyped) Bridge::getBtcTransactionConfirmations, + activations -> activations.isActive(RSKIP122), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_TX_HASH_PROCESSED_HEIGHT( - CallTransaction.Function.fromSignature( - "getBtcTxHashProcessedHeight", - new String[]{"string"}, - new String[]{"int64"} - ), - fixedCost(22000L), - (BridgeMethodExecutorTyped) Bridge::getBtcTxHashProcessedHeight, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcTxHashProcessedHeight", + new String[]{"string"}, + new String[]{"int64"} + ), + fixedCost(22000L), + (BridgeMethodExecutorTyped) Bridge::getBtcTxHashProcessedHeight, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_ADDRESS( - CallTransaction.Function.fromSignature( - "getFederationAddress", - new String[]{}, - new String[]{"string"} - ), - fixedCost(11000L), - (BridgeMethodExecutorTyped) Bridge::getFederationAddress, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getFederationAddress", + new String[]{}, + new String[]{"string"} + ), + fixedCost(11000L), + (BridgeMethodExecutorTyped) Bridge::getFederationAddress, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_CREATION_BLOCK_NUMBER( - CallTransaction.Function.fromSignature( - "getFederationCreationBlockNumber", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(10000L), - (BridgeMethodExecutorTyped) Bridge::getFederationCreationBlockNumber, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getFederationCreationBlockNumber", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(10000L), + (BridgeMethodExecutorTyped) Bridge::getFederationCreationBlockNumber, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_CREATION_TIME( - CallTransaction.Function.fromSignature( - "getFederationCreationTime", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(10000L), - (BridgeMethodExecutorTyped) Bridge::getFederationCreationTime, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getFederationCreationTime", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(10000L), + (BridgeMethodExecutorTyped) Bridge::getFederationCreationTime, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_SIZE( - CallTransaction.Function.fromSignature( - "getFederationSize", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(10000L), - (BridgeMethodExecutorTyped) Bridge::getFederationSize, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getFederationSize", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(10000L), + (BridgeMethodExecutorTyped) Bridge::getFederationSize, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATION_THRESHOLD( - CallTransaction.Function.fromSignature( - "getFederationThreshold", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(11000L), - (BridgeMethodExecutorTyped) Bridge::getFederationThreshold, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getFederationThreshold", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(11000L), + (BridgeMethodExecutorTyped) Bridge::getFederationThreshold, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATOR_PUBLIC_KEY( - CallTransaction.Function.fromSignature( - "getFederatorPublicKey", - new String[]{"int256"}, - new String[]{"bytes"} - ), - fixedCost(10000L), - (BridgeMethodExecutorTyped) Bridge::getFederatorPublicKey, - activations -> !activations.isActive(RSKIP123), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getFederatorPublicKey", + new String[]{"int256"}, + new String[]{"bytes"} + ), + fixedCost(10000L), + (BridgeMethodExecutorTyped) Bridge::getFederatorPublicKey, + activations -> !activations.isActive(RSKIP123), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEDERATOR_PUBLIC_KEY_OF_TYPE( - CallTransaction.Function.fromSignature( - "getFederatorPublicKeyOfType", - new String[]{"int256", "string"}, - new String[]{"bytes"} - ), - fixedCost(10000L), - (BridgeMethodExecutorTyped) Bridge::getFederatorPublicKeyOfType, - activations -> activations.isActive(RSKIP123), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getFederatorPublicKeyOfType", + new String[]{"int256", "string"}, + new String[]{"bytes"} + ), + fixedCost(10000L), + (BridgeMethodExecutorTyped) Bridge::getFederatorPublicKeyOfType, + activations -> activations.isActive(RSKIP123), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_FEE_PER_KB( - CallTransaction.Function.fromSignature( - "getFeePerKb", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(2000L), - (BridgeMethodExecutorTyped) Bridge::getFeePerKb, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getFeePerKb", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(2000L), + (BridgeMethodExecutorTyped) Bridge::getFeePerKb, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_LOCK_WHITELIST_ADDRESS( - CallTransaction.Function.fromSignature( - "getLockWhitelistAddress", - new String[]{"int256"}, - new String[]{"string"} - ), - fixedCost(16000L), - (BridgeMethodExecutorTyped) Bridge::getLockWhitelistAddress, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getLockWhitelistAddress", + new String[]{"int256"}, + new String[]{"string"} + ), + fixedCost(16000L), + (BridgeMethodExecutorTyped) Bridge::getLockWhitelistAddress, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_LOCK_WHITELIST_ENTRY_BY_ADDRESS( - CallTransaction.Function.fromSignature( - "getLockWhitelistEntryByAddress", - new String[]{"string"}, - new String[]{"int256"} - ), - fixedCost(16000L), - (BridgeMethodExecutorTyped) Bridge::getLockWhitelistEntryByAddress, - activations -> activations.isActive(RSKIP87), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getLockWhitelistEntryByAddress", + new String[]{"string"}, + new String[]{"int256"} + ), + fixedCost(16000L), + (BridgeMethodExecutorTyped) Bridge::getLockWhitelistEntryByAddress, + activations -> activations.isActive(RSKIP87), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_LOCK_WHITELIST_SIZE( - CallTransaction.Function.fromSignature( - "getLockWhitelistSize", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(16000L), - (BridgeMethodExecutorTyped) Bridge::getLockWhitelistSize, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getLockWhitelistSize", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(16000L), + (BridgeMethodExecutorTyped) Bridge::getLockWhitelistSize, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_MINIMUM_LOCK_TX_VALUE( - CallTransaction.Function.fromSignature( - "getMinimumLockTxValue", - new String[]{}, - new String[]{"int"} - ), - fixedCost(2000L), - (BridgeMethodExecutorTyped) Bridge::getMinimumLockTxValue, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getMinimumLockTxValue", + new String[]{}, + new String[]{"int"} + ), + fixedCost(2000L), + (BridgeMethodExecutorTyped) Bridge::getMinimumLockTxValue, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATION_HASH( - CallTransaction.Function.fromSignature( - "getPendingFederationHash", - new String[]{}, - new String[]{"bytes"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getPendingFederationHash, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getPendingFederationHash", + new String[]{}, + new String[]{"bytes"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getPendingFederationHash, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATION_SIZE( - CallTransaction.Function.fromSignature( - "getPendingFederationSize", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getPendingFederationSize, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getPendingFederationSize", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getPendingFederationSize, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATOR_PUBLIC_KEY( CallTransaction.Function.fromSignature( diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 04fb6601c4e..dca9d2f9a24 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -9,11 +9,14 @@ import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.store.BlockStoreException; +import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; +import co.rsk.peg.FederationMember.KeyType; +import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.test.builders.BridgeBuilder; import java.io.IOException; @@ -1281,6 +1284,31 @@ void commitFederation(MsgType msgType, ActivationConfig activationConfig) throws } } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void createFederation(MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.CREATE_FEDERATION; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange( + any(), + any() + ); + } + } + @ParameterizedTest() @MethodSource("msgTypesAndActivations") void getBtcBlockchainBestChainHeight(MsgType msgType, ActivationConfig activationConfig) @@ -1309,6 +1337,580 @@ void getBtcBlockchainBestChainHeight(MsgType msgType, ActivationConfig activatio } } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainInitialBlockHeight(MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainInitialBlockHeight(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockLocator(MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { + // Post RSKIP89 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockLocator(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockHashAtDepth(MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int depth = 1000; + Sha256Hash blockHashAtDepth = BitcoinTestUtils.createHash(1); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getBtcBlockchainBlockHashAtDepth(depth)).thenReturn(blockHashAtDepth); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH; + byte[] data = function.encode(depth); + + if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHashAtDepth(depth); + } + } else { + // Pre RSKIP89 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcTransactionConfirmations(MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + + Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); + Sha256Hash btcBlockHash = BitcoinTestUtils.createHash(2); + int merkleBranchPath = 1; + List merkleBranchHashes = Arrays.asList( + BitcoinTestUtils.createHash(10), + BitcoinTestUtils.createHash(11), + BitcoinTestUtils.createHash(12) + ); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_TRANSACTION_CONFIRMATIONS; + byte[] data = function.encode( + btcTxHash.getBytes(), + btcBlockHash.getBytes(), + merkleBranchPath, + merkleBranchHashes.stream().map(Sha256Hash::getBytes).toArray() + ); + + if (activationConfig.isActive(ConsensusRule.RSKIP122, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcTransactionConfirmations( + any(), + any(), + any() + ); + } + } else { + // Pre RSKIP122 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcTxHashProcessedHeight(MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_TX_HASH_PROCESSED_HEIGHT; + byte[] data = function.encode(btcTxHash.toString()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcTxHashProcessedHeight(btcTxHash); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Address federationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFederationAddress()).thenReturn(federationAddress); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_ADDRESS; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationAddress(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationCreationBlockNumber(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_CREATION_BLOCK_NUMBER; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationCreationBlockNumber(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationCreationTime(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFederationCreationTime()).thenReturn(Instant.ofEpochSecond(100_000L)); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_CREATION_TIME; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationCreationTime(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationSize(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_SIZE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationThreshold(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_THRESHOLD; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationThreshold(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederatorPublicKey(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int federatorIndex = 1; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATOR_PUBLIC_KEY; + byte[] data = function.encode(federatorIndex); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederatorPublicKey(federatorIndex); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederatorPublicKeyOfType(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int federatorIndex = 1; + KeyType keyType = KeyType.BTC; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATOR_PUBLIC_KEY_OF_TYPE; + byte[] data = function.encode(federatorIndex, keyType.getValue()); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederatorPublicKeyOfType( + federatorIndex, + keyType + ); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFeePerKb(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Coin feePerKb = Coin.COIN; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFeePerKb()).thenReturn(feePerKb); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEE_PER_KB; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFeePerKb(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int index = 1; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_ADDRESS; + byte[] data = function.encode(index); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByIndex(index); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistEntryByAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_ENTRY_BY_ADDRESS; + byte[] data = function.encode(addressBase58); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByAddress(addressBase58); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistSize(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_SIZE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getMinimumLockTxValue(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Coin minimumPeginTxValue = Coin.COIN; + BridgeConstants bridgeConstants = mock(BridgeConstants.class); + when(bridgeConstants.getMinimumPeginTxValue(any())).thenReturn(minimumPeginTxValue); + Constants constants = mock(Constants.class); + when(constants.getBridgeConstants()).thenReturn(bridgeConstants); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .constants(constants) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_MINIMUM_LOCK_TX_VALUE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeConstants, times(1)).getMinimumPeginTxValue(any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederationHash(MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_PENDING_FEDERATION_HASH; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederationHash(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederationSize(MsgType msgType, ActivationConfig activationConfig) throws VMException + { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_PENDING_FEDERATION_SIZE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederationSize(); + } + } + private static Stream msgTypesAndActivations() { List argumentsList = new ArrayList<>(); List activationConfigs = Arrays.asList( @@ -1321,7 +1923,7 @@ private static Stream msgTypesAndActivations() { ActivationConfigsForTest.arrowhead600() ); - for(MsgType msgType : MsgType.values()) { + for (MsgType msgType : MsgType.values()) { for(ActivationConfig activationConfig : activationConfigs) { argumentsList.add(Arguments.of(msgType, activationConfig)); } From da60d8198c747393ffb794d9739b4bbf57ea0236 Mon Sep 17 00:00:00 2001 From: julia zack Date: Wed, 24 Jan 2024 17:51:50 -0300 Subject: [PATCH 104/137] Finish creating unit tests for bridge methods. Move all those tests to BridgeMethodsTest new file. --- .../main/java/co/rsk/peg/BridgeMethods.java | 638 +++--- .../java/co/rsk/peg/BridgeMethodsTest.java | 1979 +++++++++++++++++ .../src/test/java/co/rsk/peg/BridgeTest.java | 867 +------- 3 files changed, 2299 insertions(+), 1185 deletions(-) create mode 100644 rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 333596cf07c..1c24092eaaa 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -347,344 +347,344 @@ public enum BridgeMethods { CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATOR_PUBLIC_KEY( - CallTransaction.Function.fromSignature( - "getPendingFederatorPublicKey", - new String[]{"int256"}, - new String[]{"bytes"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getPendingFederatorPublicKey, - activations -> !activations.isActive(RSKIP123), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getPendingFederatorPublicKey", + new String[]{"int256"}, + new String[]{"bytes"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getPendingFederatorPublicKey, + activations -> !activations.isActive(RSKIP123), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_PENDING_FEDERATOR_PUBLIC_KEY_OF_TYPE( - CallTransaction.Function.fromSignature( - "getPendingFederatorPublicKeyOfType", - new String[]{"int256", "string"}, - new String[]{"bytes"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getPendingFederatorPublicKeyOfType, - activations -> activations.isActive(RSKIP123), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getPendingFederatorPublicKeyOfType", + new String[]{"int256", "string"}, + new String[]{"bytes"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getPendingFederatorPublicKeyOfType, + activations -> activations.isActive(RSKIP123), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_ADDRESS( - CallTransaction.Function.fromSignature( - "getRetiringFederationAddress", - new String[]{}, - new String[]{"string"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getRetiringFederationAddress, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getRetiringFederationAddress", + new String[]{}, + new String[]{"string"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getRetiringFederationAddress, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_CREATION_BLOCK_NUMBER( - CallTransaction.Function.fromSignature( - "getRetiringFederationCreationBlockNumber", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getRetiringFederationCreationBlockNumber, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getRetiringFederationCreationBlockNumber", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getRetiringFederationCreationBlockNumber, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_CREATION_TIME( - CallTransaction.Function.fromSignature( - "getRetiringFederationCreationTime", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getRetiringFederationCreationTime, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getRetiringFederationCreationTime", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getRetiringFederationCreationTime, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_SIZE( - CallTransaction.Function.fromSignature( - "getRetiringFederationSize", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getRetiringFederationSize, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getRetiringFederationSize", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getRetiringFederationSize, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATION_THRESHOLD( - CallTransaction.Function.fromSignature( - "getRetiringFederationThreshold", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getRetiringFederationThreshold, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getRetiringFederationThreshold", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getRetiringFederationThreshold, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATOR_PUBLIC_KEY( - CallTransaction.Function.fromSignature( - "getRetiringFederatorPublicKey", - new String[]{"int256"}, - new String[]{"bytes"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getRetiringFederatorPublicKey, - activations -> !activations.isActive(RSKIP123), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getRetiringFederatorPublicKey", + new String[]{"int256"}, + new String[]{"bytes"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getRetiringFederatorPublicKey, + activations -> !activations.isActive(RSKIP123), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_RETIRING_FEDERATOR_PUBLIC_KEY_OF_TYPE( - CallTransaction.Function.fromSignature( - "getRetiringFederatorPublicKeyOfType", - new String[]{"int256", "string"}, - new String[]{"bytes"} - ), - fixedCost(3000L), - (BridgeMethodExecutorTyped) Bridge::getRetiringFederatorPublicKeyOfType, - activations -> activations.isActive(RSKIP123), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getRetiringFederatorPublicKeyOfType", + new String[]{"int256", "string"}, + new String[]{"bytes"} + ), + fixedCost(3000L), + (BridgeMethodExecutorTyped) Bridge::getRetiringFederatorPublicKeyOfType, + activations -> activations.isActive(RSKIP123), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_STATE_FOR_BTC_RELEASE_CLIENT( - CallTransaction.Function.fromSignature( - "getStateForBtcReleaseClient", - new String[]{}, - new String[]{"bytes"} - ), - fixedCost(4000L), - (BridgeMethodExecutorTyped) Bridge::getStateForBtcReleaseClient, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getStateForBtcReleaseClient", + new String[]{}, + new String[]{"bytes"} + ), + fixedCost(4000L), + (BridgeMethodExecutorTyped) Bridge::getStateForBtcReleaseClient, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_STATE_FOR_DEBUGGING( - CallTransaction.Function.fromSignature( - "getStateForDebugging", - new String[]{}, - new String[]{"bytes"} - ), - fixedCost(3_000_000L), - (BridgeMethodExecutorTyped) Bridge::getStateForDebugging, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getStateForDebugging", + new String[]{}, + new String[]{"bytes"} + ), + fixedCost(3_000_000L), + (BridgeMethodExecutorTyped) Bridge::getStateForDebugging, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_LOCKING_CAP( - CallTransaction.Function.fromSignature( - "getLockingCap", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(3_000L), - (BridgeMethodExecutorTyped) Bridge::getLockingCap, - activations -> activations.isActive(RSKIP134), - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getLockingCap", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(3_000L), + (BridgeMethodExecutorTyped) Bridge::getLockingCap, + activations -> activations.isActive(RSKIP134), + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_ACTIVE_POWPEG_REDEEM_SCRIPT( - CallTransaction.Function.fromSignature( - "getActivePowpegRedeemScript", - new String[]{}, - new String[]{"bytes"} - ), - fixedCost(30_000L), - (BridgeMethodExecutorTyped) Bridge::getActivePowpegRedeemScript, - activations -> activations.isActive(RSKIP293), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getActivePowpegRedeemScript", + new String[]{}, + new String[]{"bytes"} + ), + fixedCost(30_000L), + (BridgeMethodExecutorTyped) Bridge::getActivePowpegRedeemScript, + activations -> activations.isActive(RSKIP293), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT( - CallTransaction.Function.fromSignature( - "getActiveFederationCreationBlockHeight", - new String[]{}, - new String[]{"uint256"} - ), - fixedCost(3_000L), - (BridgeMethodExecutorTyped) Bridge::getActiveFederationCreationBlockHeight, - activations -> activations.isActive(RSKIP186), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getActiveFederationCreationBlockHeight", + new String[]{}, + new String[]{"uint256"} + ), + fixedCost(3_000L), + (BridgeMethodExecutorTyped) Bridge::getActiveFederationCreationBlockHeight, + activations -> activations.isActive(RSKIP186), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), INCREASE_LOCKING_CAP( - CallTransaction.Function.fromSignature( - "increaseLockingCap", - new String[]{"int256"}, - new String[]{"bool"} - ), - fixedCost(8_000L), - (BridgeMethodExecutorTyped) Bridge::increaseLockingCap, - activations -> activations.isActive(RSKIP134), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "increaseLockingCap", + new String[]{"int256"}, + new String[]{"bool"} + ), + fixedCost(8_000L), + (BridgeMethodExecutorTyped) Bridge::increaseLockingCap, + activations -> activations.isActive(RSKIP134), + fixedPermission(false) ), IS_BTC_TX_HASH_ALREADY_PROCESSED( - CallTransaction.Function.fromSignature( - "isBtcTxHashAlreadyProcessed", - new String[]{"string"}, - new String[]{"bool"} - ), - fixedCost(23000L), - (BridgeMethodExecutorTyped) Bridge::isBtcTxHashAlreadyProcessed, - fixedPermission(true), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "isBtcTxHashAlreadyProcessed", + new String[]{"string"}, + new String[]{"bool"} + ), + fixedCost(23000L), + (BridgeMethodExecutorTyped) Bridge::isBtcTxHashAlreadyProcessed, + fixedPermission(true), + CallTypeHelper.ALLOW_STATIC_CALL ), RECEIVE_HEADERS( - CallTransaction.Function.fromSignature( - "receiveHeaders", - new String[]{"bytes[]"}, - new String[]{} - ), - fromMethod(Bridge::receiveHeadersGetCost), - Bridge.executeIfElse( - Bridge::receiveHeadersIsPublic, - (BridgeMethodExecutorVoid) Bridge::receiveHeaders, - Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::receiveHeaders, "receiveHeaders") - ), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "receiveHeaders", + new String[]{"bytes[]"}, + new String[]{} + ), + fromMethod(Bridge::receiveHeadersGetCost), + Bridge.executeIfElse( + Bridge::receiveHeadersIsPublic, + (BridgeMethodExecutorVoid) Bridge::receiveHeaders, + Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::receiveHeaders, "receiveHeaders") + ), + fixedPermission(false) ), RECEIVE_HEADER( CallTransaction.Function.fromSignature( - "receiveHeader", - new String[]{"bytes"}, - new String[]{"int256"} - ), - fixedCost(10_600L), - (BridgeMethodExecutorTyped) Bridge::receiveHeader, - activations -> activations.isActive(RSKIP200), - fixedPermission(false) + "receiveHeader", + new String[]{"bytes"}, + new String[]{"int256"} + ), + fixedCost(10_600L), + (BridgeMethodExecutorTyped) Bridge::receiveHeader, + activations -> activations.isActive(RSKIP200), + fixedPermission(false) ), REGISTER_BTC_TRANSACTION( - CallTransaction.Function.fromSignature( - "registerBtcTransaction", - new String[]{"bytes", "int", "bytes"}, - new String[]{} - ), - fixedCost(22000L), - Bridge.executeIfElse( - Bridge::registerBtcTransactionIsPublic, - (BridgeMethodExecutorVoid) Bridge::registerBtcTransaction, - Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::registerBtcTransaction, "registerBtcTransaction") - ), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "registerBtcTransaction", + new String[]{"bytes", "int", "bytes"}, + new String[]{} + ), + fixedCost(22000L), + Bridge.executeIfElse( + Bridge::registerBtcTransactionIsPublic, + (BridgeMethodExecutorVoid) Bridge::registerBtcTransaction, + Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::registerBtcTransaction, "registerBtcTransaction") + ), + fixedPermission(false) ), RELEASE_BTC( - CallTransaction.Function.fromSignature( - "releaseBtc", - new String[]{}, - new String[]{} - ), - fixedCost(23000L), - (BridgeMethodExecutorVoid) Bridge::releaseBtc, - fixedPermission(false) + CallTransaction.Function.fromSignature( + "releaseBtc", + new String[]{}, + new String[]{} + ), + fixedCost(23000L), + (BridgeMethodExecutorVoid) Bridge::releaseBtc, + fixedPermission(false) ), REMOVE_LOCK_WHITELIST_ADDRESS( - CallTransaction.Function.fromSignature( - "removeLockWhitelistAddress", - new String[]{"string"}, - new String[]{"int256"} - ), - fixedCost(24000L), - (BridgeMethodExecutorTyped) Bridge::removeLockWhitelistAddress, - fixedPermission(false) + CallTransaction.Function.fromSignature( + "removeLockWhitelistAddress", + new String[]{"string"}, + new String[]{"int256"} + ), + fixedCost(24000L), + (BridgeMethodExecutorTyped) Bridge::removeLockWhitelistAddress, + fixedPermission(false) ), ROLLBACK_FEDERATION( - CallTransaction.Function.fromSignature( - "rollbackFederation", - new String[]{}, - new String[]{"int256"} - ), - fixedCost(12000L), - (BridgeMethodExecutorTyped) Bridge::rollbackFederation, - fixedPermission(false) + CallTransaction.Function.fromSignature( + "rollbackFederation", + new String[]{}, + new String[]{"int256"} + ), + fixedCost(12000L), + (BridgeMethodExecutorTyped) Bridge::rollbackFederation, + fixedPermission(false) ), SET_LOCK_WHITELIST_DISABLE_BLOCK_DELAY( - CallTransaction.Function.fromSignature( - "setLockWhitelistDisableBlockDelay", - new String[]{"int256"}, - new String[]{"int256"} - ), - fixedCost(24000L), - (BridgeMethodExecutorTyped) Bridge::setLockWhitelistDisableBlockDelay, - fixedPermission(false) + CallTransaction.Function.fromSignature( + "setLockWhitelistDisableBlockDelay", + new String[]{"int256"}, + new String[]{"int256"} + ), + fixedCost(24000L), + (BridgeMethodExecutorTyped) Bridge::setLockWhitelistDisableBlockDelay, + fixedPermission(false) ), UPDATE_COLLECTIONS( - CallTransaction.Function.fromSignature( - "updateCollections", - new String[]{}, - new String[]{} - ), - fixedCost(48000L), - Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::updateCollections, "updateCollections"), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "updateCollections", + new String[]{}, + new String[]{} + ), + fixedCost(48000L), + Bridge.activeAndRetiringFederationOnly((BridgeMethodExecutorVoid) Bridge::updateCollections, "updateCollections"), + fixedPermission(false) ), VOTE_FEE_PER_KB( - CallTransaction.Function.fromSignature( - "voteFeePerKbChange", - new String[]{"int256"}, - new String[]{"int256"} - ), - fixedCost(10000L), - (BridgeMethodExecutorTyped) Bridge::voteFeePerKbChange, - fixedPermission(false) + CallTransaction.Function.fromSignature( + "voteFeePerKbChange", + new String[]{"int256"}, + new String[]{"int256"} + ), + fixedCost(10000L), + (BridgeMethodExecutorTyped) Bridge::voteFeePerKbChange, + fixedPermission(false) ), REGISTER_BTC_COINBASE_TRANSACTION( - CallTransaction.Function.fromSignature( - "registerBtcCoinbaseTransaction", - new String[]{"bytes", "bytes32", "bytes", "bytes32", "bytes32"}, - new String[]{} - ), - fixedCost(10000L), - (BridgeMethodExecutorVoid) Bridge::registerBtcCoinbaseTransaction, - activations -> activations.isActive(RSKIP143), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "registerBtcCoinbaseTransaction", + new String[]{"bytes", "bytes32", "bytes", "bytes32", "bytes32"}, + new String[]{} + ), + fixedCost(10000L), + (BridgeMethodExecutorVoid) Bridge::registerBtcCoinbaseTransaction, + activations -> activations.isActive(RSKIP143), + fixedPermission(false) ), HAS_BTC_BLOCK_COINBASE_TRANSACTION_INFORMATION( - CallTransaction.Function.fromSignature( - "hasBtcBlockCoinbaseTransactionInformation", - new String[]{"bytes32"}, - new String[]{"bool"} - ), - fixedCost(5000L), - (BridgeMethodExecutorTyped) Bridge::hasBtcBlockCoinbaseTransactionInformation, - activations -> activations.isActive(RSKIP143), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "hasBtcBlockCoinbaseTransactionInformation", + new String[]{"bytes32"}, + new String[]{"bool"} + ), + fixedCost(5000L), + (BridgeMethodExecutorTyped) Bridge::hasBtcBlockCoinbaseTransactionInformation, + activations -> activations.isActive(RSKIP143), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), REGISTER_FAST_BRIDGE_BTC_TRANSACTION( - CallTransaction.Function.fromSignature( - "registerFastBridgeBtcTransaction", - new String[]{"bytes", "uint256", "bytes", "bytes32", "bytes", "address", "bytes", "bool"}, - new String[]{"int256"} - ), - fixedCost(25_000L), - (BridgeMethodExecutorTyped) Bridge::registerFlyoverBtcTransaction, - activations -> activations.isActive(RSKIP176), - fixedPermission(false) + CallTransaction.Function.fromSignature( + "registerFastBridgeBtcTransaction", + new String[]{"bytes", "uint256", "bytes", "bytes32", "bytes", "address", "bytes", "bool"}, + new String[]{"int256"} + ), + fixedCost(25_000L), + (BridgeMethodExecutorTyped) Bridge::registerFlyoverBtcTransaction, + activations -> activations.isActive(RSKIP176), + fixedPermission(false) ), GET_BTC_BLOCKCHAIN_BEST_BLOCK_HEADER( - CallTransaction.Function.fromSignature( - "getBtcBlockchainBestBlockHeader", - new String[0], - new String[]{"bytes"} - ), - fixedCost(3_800L), - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestBlockHeader, - activations -> activations.isActive(RSKIP220), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcBlockchainBestBlockHeader", + new String[0], + new String[]{"bytes"} + ), + fixedCost(3_800L), + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBestBlockHeader, + activations -> activations.isActive(RSKIP220), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HASH( - CallTransaction.Function.fromSignature( - "getBtcBlockchainBlockHeaderByHash", - new String[]{"bytes32"}, - new String[]{"bytes"} - ), - fixedCost(4_600L), - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHash, - activations -> activations.isActive(RSKIP220), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcBlockchainBlockHeaderByHash", + new String[]{"bytes32"}, + new String[]{"bytes"} + ), + fixedCost(4_600L), + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainBlockHeaderByHash, + activations -> activations.isActive(RSKIP220), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HEIGHT( CallTransaction.Function.fromSignature( @@ -699,52 +699,52 @@ public enum BridgeMethods { CallTypeHelper.ALLOW_STATIC_CALL ), GET_BTC_BLOCKCHAIN_PARENT_BLOCK_HEADER_BY_HASH( - CallTransaction.Function.fromSignature( - "getBtcBlockchainParentBlockHeaderByHash", - new String[]{"bytes32"}, - new String[]{"bytes"} - ), - fixedCost(4_900L), - (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainParentBlockHeaderByHash, - activations -> activations.isActive(RSKIP220), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getBtcBlockchainParentBlockHeaderByHash", + new String[]{"bytes32"}, + new String[]{"bytes"} + ), + fixedCost(4_900L), + (BridgeMethodExecutorTyped) Bridge::getBtcBlockchainParentBlockHeaderByHash, + activations -> activations.isActive(RSKIP220), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER( - CallTransaction.Function.fromSignature( - "getNextPegoutCreationBlockNumber", - new String[]{}, - new String[]{"uint256"} - ), - fixedCost(3_000L), - (BridgeMethodExecutorTyped) Bridge::getNextPegoutCreationBlockNumber, - activations -> activations.isActive(RSKIP271), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getNextPegoutCreationBlockNumber", + new String[]{}, + new String[]{"uint256"} + ), + fixedCost(3_000L), + (BridgeMethodExecutorTyped) Bridge::getNextPegoutCreationBlockNumber, + activations -> activations.isActive(RSKIP271), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_QUEUED_PEGOUTS_COUNT( - CallTransaction.Function.fromSignature( - "getQueuedPegoutsCount", - new String[]{}, - new String[]{"uint256"} - ), - fixedCost(3_000L), - (BridgeMethodExecutorTyped) Bridge::getQueuedPegoutsCount, - activations -> activations.isActive(RSKIP271), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getQueuedPegoutsCount", + new String[]{}, + new String[]{"uint256"} + ), + fixedCost(3_000L), + (BridgeMethodExecutorTyped) Bridge::getQueuedPegoutsCount, + activations -> activations.isActive(RSKIP271), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ), GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT( - CallTransaction.Function.fromSignature( - "getEstimatedFeesForNextPegOutEvent", - new String[]{}, - new String[]{"uint256"} - ), - fixedCost(10_000L), - (BridgeMethodExecutorTyped) Bridge::getEstimatedFeesForNextPegOutEvent, - activations -> activations.isActive(RSKIP271), - fixedPermission(false), - CallTypeHelper.ALLOW_STATIC_CALL + CallTransaction.Function.fromSignature( + "getEstimatedFeesForNextPegOutEvent", + new String[]{}, + new String[]{"uint256"} + ), + fixedCost(10_000L), + (BridgeMethodExecutorTyped) Bridge::getEstimatedFeesForNextPegOutEvent, + activations -> activations.isActive(RSKIP271), + fixedPermission(false), + CallTypeHelper.ALLOW_STATIC_CALL ); private static class CallTypeHelper { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java new file mode 100644 index 00000000000..435ab95608e --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java @@ -0,0 +1,1979 @@ +package co.rsk.peg; + +import co.rsk.bitcoinj.core.*; +import co.rsk.bitcoinj.script.Script; +import co.rsk.bitcoinj.store.BlockStoreException; +import co.rsk.config.BridgeConstants; +import co.rsk.config.BridgeMainNetConstants; +import co.rsk.config.BridgeRegTestConstants; +import co.rsk.core.RskAddress; +import co.rsk.crypto.Keccak256; +import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.test.builders.BridgeBuilder; +import org.bouncycastle.util.encoders.Hex; +import org.ethereum.config.Constants; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; +import org.ethereum.core.CallTransaction; +import org.ethereum.core.SignatureCache; +import org.ethereum.core.Transaction; +import org.ethereum.crypto.ECKey; +import org.ethereum.vm.MessageCall; +import org.ethereum.vm.exception.VMException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.IOException; +import java.math.BigInteger; +import java.time.Instant; +import java.util.*; +import java.util.stream.Stream; + +import static co.rsk.peg.PegTestUtils.createHash3; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.*; + +class BridgeMethodsTest { + + private NetworkParameters networkParameters; + private BridgeBuilder bridgeBuilder; + + @BeforeEach + void resetConfigToMainnet() { + networkParameters = BridgeMainNetConstants.getInstance().getBtcParams(); + bridgeBuilder = new BridgeBuilder(); + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_FEDERATOR_PUBLIC_KEY; + byte[] data = function.encode(Hex.decode(publicKey)); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addFederatorPublicKeyMultikey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY; + byte[] data = function.encode(Hex.decode(publicKey), Hex.decode(publicKey), Hex.decode(publicKey)); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + long maxTransferValue = 100_000L; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_LOCK_WHITELIST_ADDRESS; + byte[] data = function.encode(addressBase58, maxTransferValue); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + // Post RSKIP87 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( + any(), + any(), + any() + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addOneOffLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + long maxTransferValue = 100_000L; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS; + byte[] data = function.encode(addressBase58, maxTransferValue); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( + any(), + any(), + any() + ); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addUnlimitedLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS; + byte[] data = function.encode(addressBase58); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addUnlimitedLockWhitelistAddress( + any(), + any() + ); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addSignatures(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws Exception { + String pegnatoryPublicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + String signature = "3045022100a0963cea7551eb3174a3470c6ed25cda901c4b1093818d4d54792b87508820220220325f93b5aecc98385a664328e68d1cec7a2a2fe81810a7692358bd870aeecb74"; + List derEncodedSigs = Collections.singletonList(Hex.decode(signature)); + Keccak256 rskTxHash = createHash3(1); + + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + Transaction rskTxMock = mock(Transaction.class); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ADD_SIGNATURE; + byte[] data = function.encode(Hex.decode(pegnatoryPublicKey), derEncodedSigs, rskTxHash.getBytes()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addSignature( + any(), + any(), + any() + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void commitFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Keccak256 commitTransactionHash = createHash3(2); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.COMMIT_FEDERATION; + byte[] data = function.encode(commitTransactionHash.getBytes()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange( + any(), + any() + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void createFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.CREATE_FEDERATION; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange( + any(), + any() + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBestChainHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, BlockStoreException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBestChainHeight(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainInitialBlockHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainInitialBlockHeight(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockLocator(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { + // Post RSKIP89 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockLocator(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockHashAtDepth(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int depth = 1000; + Sha256Hash blockHashAtDepth = BitcoinTestUtils.createHash(1); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getBtcBlockchainBlockHashAtDepth(depth)).thenReturn(blockHashAtDepth); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH; + byte[] data = function.encode(depth); + + if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHashAtDepth(depth); + } + } else { + // Pre RSKIP89 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcTransactionConfirmations(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + + Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); + Sha256Hash btcBlockHash = BitcoinTestUtils.createHash(2); + int merkleBranchPath = 1; + List merkleBranchHashes = Arrays.asList( + BitcoinTestUtils.createHash(10), + BitcoinTestUtils.createHash(11), + BitcoinTestUtils.createHash(12) + ); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_TRANSACTION_CONFIRMATIONS; + byte[] data = function.encode( + btcTxHash.getBytes(), + btcBlockHash.getBytes(), + merkleBranchPath, + merkleBranchHashes.stream().map(Sha256Hash::getBytes).toArray() + ); + + if (activationConfig.isActive(ConsensusRule.RSKIP122, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcTransactionConfirmations( + any(), + any(), + any() + ); + } + } else { + // Pre RSKIP122 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcTxHashProcessedHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_TX_HASH_PROCESSED_HEIGHT; + byte[] data = function.encode(btcTxHash.toString()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcTxHashProcessedHeight(btcTxHash); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Address federationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFederationAddress()).thenReturn(federationAddress); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_ADDRESS; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationAddress(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_CREATION_BLOCK_NUMBER; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationCreationBlockNumber(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationCreationTime(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFederationCreationTime()).thenReturn(Instant.ofEpochSecond(100_000L)); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_CREATION_TIME; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationCreationTime(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_SIZE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationThreshold(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_THRESHOLD; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationThreshold(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int federatorIndex = 1; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATOR_PUBLIC_KEY; + byte[] data = function.encode(federatorIndex); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederatorPublicKey(federatorIndex); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int federatorIndex = 1; + FederationMember.KeyType keyType = FederationMember.KeyType.BTC; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATOR_PUBLIC_KEY_OF_TYPE; + byte[] data = function.encode(federatorIndex, keyType.getValue()); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederatorPublicKeyOfType( + federatorIndex, + keyType + ); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Coin feePerKb = Coin.COIN; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFeePerKb()).thenReturn(feePerKb); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEE_PER_KB; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFeePerKb(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int index = 1; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_ADDRESS; + byte[] data = function.encode(index); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByIndex(index); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistEntryByAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_ENTRY_BY_ADDRESS; + byte[] data = function.encode(addressBase58); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByAddress(addressBase58); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_SIZE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getMinimumLockTxValue(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Coin minimumPeginTxValue = Coin.COIN; + BridgeConstants bridgeConstants = mock(BridgeConstants.class); + when(bridgeConstants.getMinimumPeginTxValue(any())).thenReturn(minimumPeginTxValue); + Constants constants = mock(Constants.class); + when(constants.getBridgeConstants()).thenReturn(bridgeConstants); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .constants(constants) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_MINIMUM_LOCK_TX_VALUE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeConstants, times(1)).getMinimumPeginTxValue(any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederationHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_PENDING_FEDERATION_HASH; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederationHash(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException + { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_PENDING_FEDERATION_SIZE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederationSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY; + + int federatorIndex = 1; + byte[] data = function.encode(federatorIndex); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederatorPublicKey(federatorIndex); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY_OF_TYPE; + + int federatorIndex = 1; + FederationMember.KeyType keyType = FederationMember.KeyType.BTC; + byte[] data = function.encode(federatorIndex, keyType.getValue()); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederatorPublicKeyOfType( + federatorIndex, + keyType + ); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Address federationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); + when(bridgeSupportMock.getFederationAddress()).thenReturn(federationAddress); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_FEDERATION_ADDRESS; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationAddress(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_CREATION_BLOCK_NUMBER; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationCreationBlockNumber(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationCreationTime(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFederationCreationTime()).thenReturn(Instant.ofEpochSecond(100_000L)); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_CREATION_TIME; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationCreationTime(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_SIZE; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationThreshold(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_THRESHOLD; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationThreshold(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int federatorIndex = 1; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY; + byte[] data = function.encode(federatorIndex); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederatorPublicKey(federatorIndex); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY_OF_TYPE; + + int federatorIndex = 1; + FederationMember.KeyType keyType = FederationMember.KeyType.BTC; + byte[] data = function.encode(federatorIndex, keyType.getValue()); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederatorPublicKeyOfType( + federatorIndex, + keyType + ); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getStateForBtcReleaseClient(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_STATE_FOR_BTC_RELEASE_CLIENT; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getStateForBtcReleaseClient(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getStateForDebugging(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_STATE_FOR_DEBUGGING; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getStateForDebugging(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockingCap(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Coin lockingCap = Coin.COIN; + when(bridgeSupportMock.getLockingCap()).thenReturn(lockingCap); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_LOCKING_CAP; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockingCap(); + } + } else { + // Pre RSKIP134 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getActivePowpegRedeemScript(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + Script activePowpegRedeemScript = activeFederation.getRedeemScript(); + when(bridgeSupportMock.getActivePowpegRedeemScript()).thenReturn(Optional.of(activePowpegRedeemScript)); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_ACTIVE_POWPEG_REDEEM_SCRIPT; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP293, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getActivePowpegRedeemScript(); + } + } + else { + // Pre RSKIP293 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getActiveFederationCreationBlockHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP186, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getActiveFederationCreationBlockHeight(); + } + } + else { + // Pre RSKIP186 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void increaseLockingCap(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.increaseLockingCap(any(), any())).thenReturn(true); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.INCREASE_LOCKING_CAP; + + long newLockingCap = 1; + byte[] data = function.encode(newLockingCap); + + if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).increaseLockingCap(any(), any()); + } + } + else { + // Pre RSKIP134 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void isBtcTxHashAlreadyProcessed(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Sha256Hash btcTxHash = Sha256Hash.of("btcTxHash".getBytes()); + when(bridgeSupportMock.isBtcTxHashAlreadyProcessed(btcTxHash)).thenReturn(true); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.IS_BTC_TX_HASH_ALREADY_PROCESSED; + byte[] data = function.encode(btcTxHash.toString()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).isBtcTxHashAlreadyProcessed(btcTxHash); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void receiveHeaders(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + boolean receiveHeadersIsPublic = + activationConfig.isActive(ConsensusRule.RSKIP124, 0) + && !activationConfig.isActive(ConsensusRule.RSKIP200, 0); + + // Pre RSKIP124 and post RSKIP200 receiveHeaders is callable only from active or retiring federation fed members + if (!receiveHeadersIsPublic) { + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + } + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.RECEIVE_HEADERS; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).receiveHeaders(new BtcBlock[]{}); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void receiveHeader(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.RECEIVE_HEADER; + + BtcBlock btcBlock = new BtcBlock( + networkParameters, + 1, + PegTestUtils.createHash(1), + PegTestUtils.createHash(1), + 1, + Utils.encodeCompactBits(networkParameters.getMaxTarget()), + 1, + new ArrayList<>() + ).cloneAsHeader(); + Object[] btcBlockBytes = new Object[]{btcBlock.bitcoinSerialize()}; + byte[] data = function.encode(btcBlockBytes); + + if (activationConfig.isActive(ConsensusRule.RSKIP200, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).receiveHeader(any()); + } + } else { + // Pre RSKIP200 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void registerBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + boolean registerBtcTransactionIsPublic = activationConfig.isActive(ConsensusRule.RSKIP199, 0); + // Before RSKIP199 registerBtcTransaction was callable only from active or retiring federation fed members + if (!registerBtcTransactionIsPublic) { + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + } + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.REGISTER_BTC_TRANSACTION; + + byte[] value = Sha256Hash.ZERO_HASH.getBytes(); + int zero = 0; + byte[] data = function.encode(value, zero, value); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).registerBtcTransaction( + any(Transaction.class), any(byte[].class), anyInt(), any(byte[].class)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void releaseBtc(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.RELEASE_BTC; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).releaseBtc(any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void removeLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.REMOVE_LOCK_WHITELIST_ADDRESS; + + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + byte[] data = function.encode(addressBase58); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).removeLockWhitelistAddress(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void rollbackFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.ROLLBACK_FEDERATION; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void setLockWhiteListDisableBlockDelay(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.SET_LOCK_WHITELIST_DISABLE_BLOCK_DELAY; + + BigInteger disableBlockDelayBI = BigInteger.valueOf(100); + byte[] data = function.encode(disableBlockDelayBI); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).setLockWhitelistDisableBlockDelay(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void updateCollections(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + // updateCollections is only callable from active or retiring federation + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.UPDATE_COLLECTIONS; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).updateCollections(rskTxMock); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.VOTE_FEE_PER_KB; + + long feePerKB = 10_000; + byte[] data = function.encode(feePerKB); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFeePerKbChange(any(), any()); + } + } + + // TODO: check data + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.REGISTER_BTC_COINBASE_TRANSACTION; + + byte[] value = new byte[32]; + byte[] data = function.encode(value, value, value, value, value); + + if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).registerBtcCoinbaseTransaction( + value, Sha256Hash.wrap(value), value, Sha256Hash.wrap(value), value); + } + } else { + // Pre RSKIP143 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void hasBtcBlockCoinbaseTransactionInformation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.HAS_BTC_BLOCK_COINBASE_TRANSACTION_INFORMATION; + + byte[] value = Sha256Hash.ZERO_HASH.getBytes(); + byte[] data = function.encode(value); + + if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATICCALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).hasBtcBlockCoinbaseTransactionInformation(any()); + } + } else { + // Pre RSKIP143 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void registerFastBridgeBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION; + + byte[] value = Sha256Hash.ZERO_HASH.getBytes(); + byte[] hashBytes = new byte[32]; + byte[] addressBytes = new byte[21]; + int zero = 0; + RskAddress rskAddress = new RskAddress((new ECKey()).getAddress()); + byte[] data = function + .encode(value, zero, value, hashBytes, addressBytes, rskAddress.toHexString(), addressBytes, true); + + if (activationConfig.isActive(ConsensusRule.RSKIP176, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).registerFlyoverBtcTransaction( + any(Transaction.class), any(byte[].class), anyInt(), any(byte[].class), + any(Keccak256.class), any(Address.class), any(RskAddress.class), any(Address.class), + any(boolean.class)); + } + } + else { + // Pre RSKIP176 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBestBlockHeader(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BEST_BLOCK_HEADER; + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBestBlockHeader(); + } + } else { + // Pre RSKIP220 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockHeaderByHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HASH; + + byte[] hashBytes = new byte[32]; + byte[] data = function.encode(hashBytes); + + if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHeaderByHash(Sha256Hash.wrap(hashBytes)); + } + } else { + // Pre RSKIP220 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockHeaderByHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HEIGHT; + + int value = 20; + byte[] data = function.encode(value); + + if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHeaderByHeight(value); + } + } else { + // Pre RSKIP220 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainParentBlockHeaderByHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_PARENT_BLOCK_HEADER_BY_HASH; + + byte[] hashBytes = new byte[32]; + byte[] data = function.encode(hashBytes); + + if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainParentBlockHeaderByHash(any()); + } + } else { + // Pre RSKIP220 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getNextPegoutCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getNextPegoutCreationBlockNumber(); + } + } else { + // Pre RSKIP271 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getQueuedPegoutsCount(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_QUEUED_PEGOUTS_COUNT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getQueuedPegoutsCount(); + } + } else { + // Pre RSKIP271 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getEstimatedFeesForNextPegoutEvent(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Coin estimatedFeesForNextPegout = Coin.SATOSHI; + when(bridgeSupportMock.getEstimatedFeesForNextPegOutEvent()).thenReturn(estimatedFeesForNextPegout); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getEstimatedFeesForNextPegOutEvent(); + } + } else { + // Pre RSKIP271 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + private static Stream msgTypesAndActivations() { + List argumentsList = new ArrayList<>(); + List activationConfigs = Arrays.asList( + ActivationConfigsForTest.orchid(), + ActivationConfigsForTest.wasabi100(), + ActivationConfigsForTest.papyrus200(), + ActivationConfigsForTest.iris300(), + ActivationConfigsForTest.hop400(), + ActivationConfigsForTest.fingerroot500(), + ActivationConfigsForTest.arrowhead600() + ); + + for (MessageCall.MsgType msgType : MessageCall.MsgType.values()) { + for(ActivationConfig activationConfig : activationConfigs) { + argumentsList.add(Arguments.of(msgType, activationConfig)); + } + } + + return argumentsList.stream(); + } +} diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index dca9d2f9a24..2c34b88d4d5 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1,6 +1,5 @@ package co.rsk.peg; -import static co.rsk.peg.PegTestUtils.createHash3; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -9,14 +8,11 @@ import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.store.BlockStoreException; -import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; -import co.rsk.peg.FederationMember.KeyType; -import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.test.builders.BridgeBuilder; import java.io.IOException; @@ -28,11 +24,9 @@ import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; -import org.ethereum.vm.MessageCall.MsgType; import org.ethereum.vm.exception.VMException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -171,7 +165,7 @@ void increaseLockingCap_after_RSKIP134_activation(long newLockingCapValue) throw private static Stream lockingCapValues() { return Stream.of( Arguments.of(1), - Arguments.of(21_000_0000) + Arguments.of(21_000_0000) // TODO y este nro? ); } @@ -1072,863 +1066,4 @@ void getEstimatedFeesForNextPegOutEvent_after_RSKIP271_activation() throws VMExc long resultFromTheBridge = bridge.getEstimatedFeesForNextPegOutEvent(new Object[]{}); assertEquals(estimatedFeesForNextPegout.getValue(), resultFromTheBridge); } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addFederatorPublicKey(MsgType msgType, ActivationConfig activationConfig) throws VMException { - String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_FEDERATOR_PUBLIC_KEY; - byte[] data = function.encode(Hex.decode(publicKey)); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - // Post RSKIP123 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addFederatorPublicKeyMultikey(MsgType msgType, ActivationConfig activationConfig) throws VMException { - String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY; - byte[] data = function.encode(Hex.decode(publicKey), Hex.decode(publicKey), Hex.decode(publicKey)); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); - } - } else { - // Pre RSKIP123 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - long maxTransferValue = 100_000L; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_LOCK_WHITELIST_ADDRESS; - byte[] data = function.encode(addressBase58, maxTransferValue); - - if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - // Post RSKIP87 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( - any(), - any(), - any() - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addOneOffLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - long maxTransferValue = 100_000L; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS; - byte[] data = function.encode(addressBase58, maxTransferValue); - - if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( - any(), - any(), - any() - ); - } - } else { - // Pre RSKIP87 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addUnlimitedLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS; - byte[] data = function.encode(addressBase58); - - if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).addUnlimitedLockWhitelistAddress( - any(), - any() - ); - } - } else { - // Pre RSKIP87 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addSignatures(MsgType msgType, ActivationConfig activationConfig) throws Exception { - String pegnatoryPublicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; - String signature = "3045022100a0963cea7551eb3174a3470c6ed25cda901c4b1093818d4d54792b87508820220220325f93b5aecc98385a664328e68d1cec7a2a2fe81810a7692358bd870aeecb74"; - List derEncodedSigs = Collections.singletonList(Hex.decode(signature)); - Keccak256 rskTxHash = createHash3(1); - - int senderPK = 101; // Sender PK belongs to active federation member PKs - Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; - Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); - - ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); - RskAddress txSender = new RskAddress(key.getAddress()); - Transaction rskTxMock = mock(Transaction.class); - doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_SIGNATURE; - byte[] data = function.encode(Hex.decode(pegnatoryPublicKey), derEncodedSigs, rskTxHash.getBytes()); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).addSignature( - any(), - any(), - any() - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void commitFederation(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Keccak256 commitTransactionHash = createHash3(2); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.COMMIT_FEDERATION; - byte[] data = function.encode(commitTransactionHash.getBytes()); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange( - any(), - any() - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void createFederation(MsgType msgType, ActivationConfig activationConfig) throws VMException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.CREATE_FEDERATION; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange( - any(), - any() - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBestChainHeight(MsgType msgType, ActivationConfig activationConfig) - throws VMException, BlockStoreException, IOException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBestChainHeight(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainInitialBlockHeight(MsgType msgType, ActivationConfig activationConfig) - throws VMException, IOException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainInitialBlockHeight(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBlockLocator(MsgType msgType, ActivationConfig activationConfig) - throws VMException, IOException, BlockStoreException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { - // Post RSKIP89 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockLocator(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBlockHashAtDepth(MsgType msgType, ActivationConfig activationConfig) - throws VMException, IOException, BlockStoreException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int depth = 1000; - Sha256Hash blockHashAtDepth = BitcoinTestUtils.createHash(1); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getBtcBlockchainBlockHashAtDepth(depth)).thenReturn(blockHashAtDepth); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH; - byte[] data = function.encode(depth); - - if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHashAtDepth(depth); - } - } else { - // Pre RSKIP89 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcTransactionConfirmations(MsgType msgType, ActivationConfig activationConfig) - throws VMException, IOException, BlockStoreException { - - Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); - Sha256Hash btcBlockHash = BitcoinTestUtils.createHash(2); - int merkleBranchPath = 1; - List merkleBranchHashes = Arrays.asList( - BitcoinTestUtils.createHash(10), - BitcoinTestUtils.createHash(11), - BitcoinTestUtils.createHash(12) - ); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_TRANSACTION_CONFIRMATIONS; - byte[] data = function.encode( - btcTxHash.getBytes(), - btcBlockHash.getBytes(), - merkleBranchPath, - merkleBranchHashes.stream().map(Sha256Hash::getBytes).toArray() - ); - - if (activationConfig.isActive(ConsensusRule.RSKIP122, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcTransactionConfirmations( - any(), - any(), - any() - ); - } - } else { - // Pre RSKIP122 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcTxHashProcessedHeight(MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_TX_HASH_PROCESSED_HEIGHT; - byte[] data = function.encode(btcTxHash.toString()); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcTxHashProcessedHeight(btcTxHash); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - Address federationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getFederationAddress()).thenReturn(federationAddress); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_ADDRESS; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationAddress(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationCreationBlockNumber(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_CREATION_BLOCK_NUMBER; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationCreationBlockNumber(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationCreationTime(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getFederationCreationTime()).thenReturn(Instant.ofEpochSecond(100_000L)); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_CREATION_TIME; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationCreationTime(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationSize(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_SIZE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationSize(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationThreshold(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_THRESHOLD; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationThreshold(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederatorPublicKey(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int federatorIndex = 1; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATOR_PUBLIC_KEY; - byte[] data = function.encode(federatorIndex); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - // Post RSKIP123 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederatorPublicKey(federatorIndex); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederatorPublicKeyOfType(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int federatorIndex = 1; - KeyType keyType = KeyType.BTC; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATOR_PUBLIC_KEY_OF_TYPE; - byte[] data = function.encode(federatorIndex, keyType.getValue()); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederatorPublicKeyOfType( - federatorIndex, - keyType - ); - } - } else { - // Pre RSKIP123 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFeePerKb(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - Coin feePerKb = Coin.COIN; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getFeePerKb()).thenReturn(feePerKb); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEE_PER_KB; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFeePerKb(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getLockWhitelistAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int index = 1; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_ADDRESS; - byte[] data = function.encode(index); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByIndex(index); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getLockWhitelistEntryByAddress(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_ENTRY_BY_ADDRESS; - byte[] data = function.encode(addressBase58); - - if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByAddress(addressBase58); - } - } else { - // Pre RSKIP87 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getLockWhitelistSize(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_SIZE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getLockWhitelistSize(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getMinimumLockTxValue(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - Coin minimumPeginTxValue = Coin.COIN; - BridgeConstants bridgeConstants = mock(BridgeConstants.class); - when(bridgeConstants.getMinimumPeginTxValue(any())).thenReturn(minimumPeginTxValue); - Constants constants = mock(Constants.class); - when(constants.getBridgeConstants()).thenReturn(bridgeConstants); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .constants(constants) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_MINIMUM_LOCK_TX_VALUE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeConstants, times(1)).getMinimumPeginTxValue(any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getPendingFederationHash(MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_PENDING_FEDERATION_HASH; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getPendingFederationHash(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getPendingFederationSize(MsgType msgType, ActivationConfig activationConfig) throws VMException - { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_PENDING_FEDERATION_SIZE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MsgType.CALL) || msgType.equals(MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getPendingFederationSize(); - } - } - - private static Stream msgTypesAndActivations() { - List argumentsList = new ArrayList<>(); - List activationConfigs = Arrays.asList( - ActivationConfigsForTest.orchid(), - ActivationConfigsForTest.wasabi100(), - ActivationConfigsForTest.papyrus200(), - ActivationConfigsForTest.iris300(), - ActivationConfigsForTest.hop400(), - ActivationConfigsForTest.fingerroot500(), - ActivationConfigsForTest.arrowhead600() - ); - - for (MsgType msgType : MsgType.values()) { - for(ActivationConfig activationConfig : activationConfigs) { - argumentsList.add(Arguments.of(msgType, activationConfig)); - } - } - - return argumentsList.stream(); - } } From eb7cea17e232b78bfac49c059a39c798b2506688 Mon Sep 17 00:00:00 2001 From: julia zack Date: Wed, 24 Jan 2024 17:52:54 -0300 Subject: [PATCH 105/137] Remove unnecessary comments --- rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java | 1 - rskj-core/src/test/java/co/rsk/peg/BridgeTest.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java index 435ab95608e..3bb9fd96d86 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java @@ -1648,7 +1648,6 @@ void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig } } - // TODO: check data @ParameterizedTest() @MethodSource("msgTypesAndActivations") void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 2c34b88d4d5..e54210fd9bf 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -165,7 +165,7 @@ void increaseLockingCap_after_RSKIP134_activation(long newLockingCapValue) throw private static Stream lockingCapValues() { return Stream.of( Arguments.of(1), - Arguments.of(21_000_0000) // TODO y este nro? + Arguments.of(21_000_0000) ); } From d3f6c706b5268766840d4ed96630dce8a877ed9d Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 25 Jan 2024 15:25:40 -0300 Subject: [PATCH 106/137] Adjust Bridge tests --- .../main/java/co/rsk/peg/BridgeMethods.java | 2 +- .../java/co/rsk/peg/BridgeMethodsTest.java | 120 +++++++++++------- 2 files changed, 74 insertions(+), 48 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java index 1c24092eaaa..ca08460e20c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeMethods.java @@ -544,7 +544,7 @@ public enum BridgeMethods { fixedPermission(false) ), RECEIVE_HEADER( - CallTransaction.Function.fromSignature( + CallTransaction.Function.fromSignature( "receiveHeader", new String[]{"bytes"}, new String[]{"int256"} diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java index 3bb9fd96d86..aa7d85bc13f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java @@ -5,7 +5,6 @@ import co.rsk.bitcoinj.store.BlockStoreException; import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; -import co.rsk.config.BridgeRegTestConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.bitcoin.BitcoinTestUtils; @@ -960,8 +959,8 @@ void getRetiringFederationAddress(MessageCall.MsgType msgType, ActivationConfig doReturn(true).when(rskTxMock).isLocalCallTransaction(); BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Address federationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); - when(bridgeSupportMock.getFederationAddress()).thenReturn(federationAddress); + Address retiringFederationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); + when(bridgeSupportMock.getRetiringFederationAddress()).thenReturn(retiringFederationAddress); Bridge bridge = bridgeBuilder .transaction(rskTxMock) @@ -970,7 +969,7 @@ void getRetiringFederationAddress(MessageCall.MsgType msgType, ActivationConfig .msgType(msgType) .build(); - CallTransaction.Function function = Bridge.GET_FEDERATION_ADDRESS; + CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_ADDRESS; byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && @@ -979,7 +978,7 @@ void getRetiringFederationAddress(MessageCall.MsgType msgType, ActivationConfig assertThrows(VMException.class, () -> bridge.execute(data)); } else { bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationAddress(); + verify(bridgeSupportMock, times(1)).getRetiringFederationAddress(); } } @@ -1274,8 +1273,7 @@ void getActivePowpegRedeemScript(MessageCall.MsgType msgType, ActivationConfig a bridge.execute(data); verify(bridgeSupportMock, times(1)).getActivePowpegRedeemScript(); } - } - else { + } else { // Pre RSKIP293 this method is not enabled, should fail for all message types assertThrows(VMException.class, () -> bridge.execute(data)); } @@ -1431,15 +1429,16 @@ void receiveHeader(MessageCall.MsgType msgType, ActivationConfig activationConfi BtcBlock btcBlock = new BtcBlock( networkParameters, 1, - PegTestUtils.createHash(1), - PegTestUtils.createHash(1), + BitcoinTestUtils.createHash(1), + BitcoinTestUtils.createHash(1), 1, - Utils.encodeCompactBits(networkParameters.getMaxTarget()), + 100L, 1, new ArrayList<>() ).cloneAsHeader(); - Object[] btcBlockBytes = new Object[]{btcBlock.bitcoinSerialize()}; - byte[] data = function.encode(btcBlockBytes); + + byte[] serializedBlockHeader = btcBlock.bitcoinSerialize(); + byte[] data = function.encode(serializedBlockHeader); if (activationConfig.isActive(ConsensusRule.RSKIP200, 0)) { if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { @@ -1483,17 +1482,20 @@ void registerBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activa CallTransaction.Function function = Bridge.REGISTER_BTC_TRANSACTION; - byte[] value = Sha256Hash.ZERO_HASH.getBytes(); - int zero = 0; - byte[] data = function.encode(value, zero, value); + byte[] btcTxSerialized = new byte[]{1}; + int height = 0; + byte[] pmtSerialized = new byte[]{2}; + byte[] data = function.encode(btcTxSerialized, height, pmtSerialized); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { bridge.execute(data); verify(bridgeSupportMock, times(1)).registerBtcTransaction( - any(Transaction.class), any(byte[].class), anyInt(), any(byte[].class)); + any(Transaction.class), any(byte[].class), anyInt(), any(byte[].class) + ); } } @@ -1510,7 +1512,8 @@ void releaseBtc(MessageCall.MsgType msgType, ActivationConfig activationConfig) CallTransaction.Function function = Bridge.RELEASE_BTC; byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1521,7 +1524,7 @@ void releaseBtc(MessageCall.MsgType msgType, ActivationConfig activationConfig) @ParameterizedTest() @MethodSource("msgTypesAndActivations") - void removeLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + void removeLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = bridgeBuilder .activationConfig(activationConfig) @@ -1534,7 +1537,8 @@ void removeLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig ac String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; byte[] data = function.encode(addressBase58); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1577,10 +1581,11 @@ void setLockWhiteListDisableBlockDelay(MessageCall.MsgType msgType, ActivationCo CallTransaction.Function function = Bridge.SET_LOCK_WHITELIST_DISABLE_BLOCK_DELAY; - BigInteger disableBlockDelayBI = BigInteger.valueOf(100); - byte[] data = function.encode(disableBlockDelayBI); + BigInteger disableBlockDelay = BigInteger.valueOf(100); + byte[] data = function.encode(disableBlockDelay); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1615,7 +1620,8 @@ void updateCollections(MessageCall.MsgType msgType, ActivationConfig activationC CallTransaction.Function function = Bridge.UPDATE_COLLECTIONS; byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1626,7 +1632,7 @@ void updateCollections(MessageCall.MsgType msgType, ActivationConfig activationC @ParameterizedTest() @MethodSource("msgTypesAndActivations") - void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = bridgeBuilder .activationConfig(activationConfig) @@ -1639,7 +1645,8 @@ void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig long feePerKB = 10_000; byte[] data = function.encode(feePerKB); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1650,7 +1657,7 @@ void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig @ParameterizedTest() @MethodSource("msgTypesAndActivations") - void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = bridgeBuilder .activationConfig(activationConfig) @@ -1680,7 +1687,7 @@ void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfi @ParameterizedTest() @MethodSource("msgTypesAndActivations") - void hasBtcBlockCoinbaseTransactionInformation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + void hasBtcBlockCoinbaseTransactionInformation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = bridgeBuilder .activationConfig(activationConfig) @@ -1690,8 +1697,8 @@ void hasBtcBlockCoinbaseTransactionInformation(MessageCall.MsgType msgType, Acti CallTransaction.Function function = Bridge.HAS_BTC_BLOCK_COINBASE_TRANSACTION_INFORMATION; - byte[] value = Sha256Hash.ZERO_HASH.getBytes(); - byte[] data = function.encode(value); + Sha256Hash blockHash = BitcoinTestUtils.createHash(2); + byte[] data = function.encode(blockHash.getBytes()); if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && @@ -1720,13 +1727,24 @@ void registerFastBridgeBtcTransaction(MessageCall.MsgType msgType, ActivationCon CallTransaction.Function function = Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION; - byte[] value = Sha256Hash.ZERO_HASH.getBytes(); - byte[] hashBytes = new byte[32]; - byte[] addressBytes = new byte[21]; - int zero = 0; - RskAddress rskAddress = new RskAddress((new ECKey()).getAddress()); - byte[] data = function - .encode(value, zero, value, hashBytes, addressBytes, rskAddress.toHexString(), addressBytes, true); + byte[] btcTxSerialized = new byte[]{1}; + int height = 1; + byte[] pmtSerialized = new byte[]{2}; + Keccak256 derivationArgumentsHash = PegTestUtils.createHash3(2); + byte[] refundAddressSerialized = new byte[21]; + RskAddress lbcAddress = new RskAddress("0xFcE93641243D1EFB6131277cCD1c0a60460d5610"); + byte[] lpAddressSerialized = new byte[21]; + boolean shouldTransferToContract = true; + byte[] data = function.encode( + btcTxSerialized, + height, + pmtSerialized, + derivationArgumentsHash.getBytes(), + refundAddressSerialized, + lbcAddress.toHexString(), + lpAddressSerialized, + shouldTransferToContract + ); if (activationConfig.isActive(ConsensusRule.RSKIP176, 0)) { if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { @@ -1735,16 +1753,23 @@ void registerFastBridgeBtcTransaction(MessageCall.MsgType msgType, ActivationCon } else { bridge.execute(data); verify(bridgeSupportMock, times(1)).registerFlyoverBtcTransaction( - any(Transaction.class), any(byte[].class), anyInt(), any(byte[].class), - any(Keccak256.class), any(Address.class), any(RskAddress.class), any(Address.class), - any(boolean.class)); + any(Transaction.class), + any(byte[].class), + anyInt(), + any(byte[].class), + any(Keccak256.class), + any(Address.class), + any(RskAddress.class), + any(Address.class), + any(boolean.class) + ); } - } - else { + } else { // Pre RSKIP176 this method is not enabled, should fail for all message types assertThrows(VMException.class, () -> bridge.execute(data)); } } + @ParameterizedTest() @MethodSource("msgTypesAndActivations") void getBtcBlockchainBestBlockHeader(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { @@ -1773,6 +1798,7 @@ void getBtcBlockchainBestBlockHeader(MessageCall.MsgType msgType, ActivationConf assertThrows(VMException.class, () -> bridge.execute(data)); } } + @ParameterizedTest() @MethodSource("msgTypesAndActivations") void getBtcBlockchainBlockHeaderByHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { @@ -1817,8 +1843,8 @@ void getBtcBlockchainBlockHeaderByHeight(MessageCall.MsgType msgType, Activation CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HEIGHT; - int value = 20; - byte[] data = function.encode(value); + int height = 20; + byte[] data = function.encode(height); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && @@ -1827,7 +1853,7 @@ void getBtcBlockchainBlockHeaderByHeight(MessageCall.MsgType msgType, Activation assertThrows(VMException.class, () -> bridge.execute(data)); } else { bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHeaderByHeight(value); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHeaderByHeight(height); } } else { // Pre RSKIP220 this method is not enabled, should fail for all message types @@ -1897,7 +1923,7 @@ void getNextPegoutCreationBlockNumber(MessageCall.MsgType msgType, ActivationCon @ParameterizedTest() @MethodSource("msgTypesAndActivations") - void getQueuedPegoutsCount(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + void getQueuedPegoutsCount(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = bridgeBuilder @@ -1926,7 +1952,7 @@ void getQueuedPegoutsCount(MessageCall.MsgType msgType, ActivationConfig activat @ParameterizedTest() @MethodSource("msgTypesAndActivations") - void getEstimatedFeesForNextPegoutEvent(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + void getEstimatedFeesForNextPegoutEvent(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Coin estimatedFeesForNextPegout = Coin.SATOSHI; when(bridgeSupportMock.getEstimatedFeesForNextPegOutEvent()).thenReturn(estimatedFeesForNextPegout); From 52fdbecf1c0d5d5191b58250d57da783013d1c23 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 25 Jan 2024 15:38:47 -0300 Subject: [PATCH 107/137] Move tests to BridgeTests class --- .../java/co/rsk/peg/BridgeMethodsTest.java | 2004 ----------------- .../src/test/java/co/rsk/peg/BridgeTest.java | 1957 ++++++++++++++++ 2 files changed, 1957 insertions(+), 2004 deletions(-) delete mode 100644 rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java deleted file mode 100644 index aa7d85bc13f..00000000000 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeMethodsTest.java +++ /dev/null @@ -1,2004 +0,0 @@ -package co.rsk.peg; - -import co.rsk.bitcoinj.core.*; -import co.rsk.bitcoinj.script.Script; -import co.rsk.bitcoinj.store.BlockStoreException; -import co.rsk.config.BridgeConstants; -import co.rsk.config.BridgeMainNetConstants; -import co.rsk.core.RskAddress; -import co.rsk.crypto.Keccak256; -import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.test.builders.BridgeBuilder; -import org.bouncycastle.util.encoders.Hex; -import org.ethereum.config.Constants; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; -import org.ethereum.core.CallTransaction; -import org.ethereum.core.SignatureCache; -import org.ethereum.core.Transaction; -import org.ethereum.crypto.ECKey; -import org.ethereum.vm.MessageCall; -import org.ethereum.vm.exception.VMException; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.io.IOException; -import java.math.BigInteger; -import java.time.Instant; -import java.util.*; -import java.util.stream.Stream; - -import static co.rsk.peg.PegTestUtils.createHash3; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.Mockito.*; - -class BridgeMethodsTest { - - private NetworkParameters networkParameters; - private BridgeBuilder bridgeBuilder; - - @BeforeEach - void resetConfigToMainnet() { - networkParameters = BridgeMainNetConstants.getInstance().getBtcParams(); - bridgeBuilder = new BridgeBuilder(); - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_FEDERATOR_PUBLIC_KEY; - byte[] data = function.encode(Hex.decode(publicKey)); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - // Post RSKIP123 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addFederatorPublicKeyMultikey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY; - byte[] data = function.encode(Hex.decode(publicKey), Hex.decode(publicKey), Hex.decode(publicKey)); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); - } - } else { - // Pre RSKIP123 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - long maxTransferValue = 100_000L; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_LOCK_WHITELIST_ADDRESS; - byte[] data = function.encode(addressBase58, maxTransferValue); - - if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - // Post RSKIP87 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( - any(), - any(), - any() - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addOneOffLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - long maxTransferValue = 100_000L; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS; - byte[] data = function.encode(addressBase58, maxTransferValue); - - if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( - any(), - any(), - any() - ); - } - } else { - // Pre RSKIP87 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addUnlimitedLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS; - byte[] data = function.encode(addressBase58); - - if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).addUnlimitedLockWhitelistAddress( - any(), - any() - ); - } - } else { - // Pre RSKIP87 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void addSignatures(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws Exception { - String pegnatoryPublicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; - String signature = "3045022100a0963cea7551eb3174a3470c6ed25cda901c4b1093818d4d54792b87508820220220325f93b5aecc98385a664328e68d1cec7a2a2fe81810a7692358bd870aeecb74"; - List derEncodedSigs = Collections.singletonList(Hex.decode(signature)); - Keccak256 rskTxHash = createHash3(1); - - int senderPK = 101; // Sender PK belongs to active federation member PKs - Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; - Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); - - ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); - RskAddress txSender = new RskAddress(key.getAddress()); - Transaction rskTxMock = mock(Transaction.class); - doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ADD_SIGNATURE; - byte[] data = function.encode(Hex.decode(pegnatoryPublicKey), derEncodedSigs, rskTxHash.getBytes()); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).addSignature( - any(), - any(), - any() - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void commitFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Keccak256 commitTransactionHash = createHash3(2); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.COMMIT_FEDERATION; - byte[] data = function.encode(commitTransactionHash.getBytes()); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange( - any(), - any() - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void createFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.CREATE_FEDERATION; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange( - any(), - any() - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBestChainHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) - throws VMException, BlockStoreException, IOException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBestChainHeight(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainInitialBlockHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) - throws VMException, IOException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainInitialBlockHeight(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBlockLocator(MessageCall.MsgType msgType, ActivationConfig activationConfig) - throws VMException, IOException, BlockStoreException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { - // Post RSKIP89 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockLocator(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBlockHashAtDepth(MessageCall.MsgType msgType, ActivationConfig activationConfig) - throws VMException, IOException, BlockStoreException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int depth = 1000; - Sha256Hash blockHashAtDepth = BitcoinTestUtils.createHash(1); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getBtcBlockchainBlockHashAtDepth(depth)).thenReturn(blockHashAtDepth); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH; - byte[] data = function.encode(depth); - - if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHashAtDepth(depth); - } - } else { - // Pre RSKIP89 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcTransactionConfirmations(MessageCall.MsgType msgType, ActivationConfig activationConfig) - throws VMException, IOException, BlockStoreException { - - Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); - Sha256Hash btcBlockHash = BitcoinTestUtils.createHash(2); - int merkleBranchPath = 1; - List merkleBranchHashes = Arrays.asList( - BitcoinTestUtils.createHash(10), - BitcoinTestUtils.createHash(11), - BitcoinTestUtils.createHash(12) - ); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_TRANSACTION_CONFIRMATIONS; - byte[] data = function.encode( - btcTxHash.getBytes(), - btcBlockHash.getBytes(), - merkleBranchPath, - merkleBranchHashes.stream().map(Sha256Hash::getBytes).toArray() - ); - - if (activationConfig.isActive(ConsensusRule.RSKIP122, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcTransactionConfirmations( - any(), - any(), - any() - ); - } - } else { - // Pre RSKIP122 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcTxHashProcessedHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_TX_HASH_PROCESSED_HEIGHT; - byte[] data = function.encode(btcTxHash.toString()); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcTxHashProcessedHeight(btcTxHash); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - Address federationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getFederationAddress()).thenReturn(federationAddress); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_ADDRESS; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationAddress(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_CREATION_BLOCK_NUMBER; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationCreationBlockNumber(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationCreationTime(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getFederationCreationTime()).thenReturn(Instant.ofEpochSecond(100_000L)); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_CREATION_TIME; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationCreationTime(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_SIZE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationSize(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederationThreshold(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATION_THRESHOLD; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederationThreshold(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int federatorIndex = 1; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATOR_PUBLIC_KEY; - byte[] data = function.encode(federatorIndex); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - // Post RSKIP123 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederatorPublicKey(federatorIndex); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int federatorIndex = 1; - FederationMember.KeyType keyType = FederationMember.KeyType.BTC; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEDERATOR_PUBLIC_KEY_OF_TYPE; - byte[] data = function.encode(federatorIndex, keyType.getValue()); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFederatorPublicKeyOfType( - federatorIndex, - keyType - ); - } - } else { - // Pre RSKIP123 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - Coin feePerKb = Coin.COIN; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getFeePerKb()).thenReturn(feePerKb); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_FEE_PER_KB; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getFeePerKb(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int index = 1; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_ADDRESS; - byte[] data = function.encode(index); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByIndex(index); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getLockWhitelistEntryByAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_ENTRY_BY_ADDRESS; - byte[] data = function.encode(addressBase58); - - if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByAddress(addressBase58); - } - } else { - // Pre RSKIP87 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getLockWhitelistSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_LOCK_WHITELIST_SIZE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getLockWhitelistSize(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getMinimumLockTxValue(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - Coin minimumPeginTxValue = Coin.COIN; - BridgeConstants bridgeConstants = mock(BridgeConstants.class); - when(bridgeConstants.getMinimumPeginTxValue(any())).thenReturn(minimumPeginTxValue); - Constants constants = mock(Constants.class); - when(constants.getBridgeConstants()).thenReturn(bridgeConstants); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .constants(constants) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_MINIMUM_LOCK_TX_VALUE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeConstants, times(1)).getMinimumPeginTxValue(any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getPendingFederationHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_PENDING_FEDERATION_HASH; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getPendingFederationHash(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getPendingFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException - { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_PENDING_FEDERATION_SIZE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getPendingFederationSize(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getPendingFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY; - - int federatorIndex = 1; - byte[] data = function.encode(federatorIndex); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - // Post RSKIP123 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getPendingFederatorPublicKey(federatorIndex); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getPendingFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_PENDING_FEDERATOR_PUBLIC_KEY_OF_TYPE; - - int federatorIndex = 1; - FederationMember.KeyType keyType = FederationMember.KeyType.BTC; - byte[] data = function.encode(federatorIndex, keyType.getValue()); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getPendingFederatorPublicKeyOfType( - federatorIndex, - keyType - ); - } - } else { - // Pre RSKIP123 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getRetiringFederationAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Address retiringFederationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); - when(bridgeSupportMock.getRetiringFederationAddress()).thenReturn(retiringFederationAddress); - - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_ADDRESS; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getRetiringFederationAddress(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getRetiringFederationCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_CREATION_BLOCK_NUMBER; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getRetiringFederationCreationBlockNumber(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getRetiringFederationCreationTime(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.getFederationCreationTime()).thenReturn(Instant.ofEpochSecond(100_000L)); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_CREATION_TIME; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getRetiringFederationCreationTime(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getRetiringFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_SIZE; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getRetiringFederationSize(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getRetiringFederationThreshold(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATION_THRESHOLD; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getRetiringFederationThreshold(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getRetiringFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - int federatorIndex = 1; - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY; - byte[] data = function.encode(federatorIndex); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - // Post RSKIP123 this method is no longer enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getRetiringFederatorPublicKey(federatorIndex); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getRetiringFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_RETIRING_FEDERATOR_PUBLIC_KEY_OF_TYPE; - - int federatorIndex = 1; - FederationMember.KeyType keyType = FederationMember.KeyType.BTC; - byte[] data = function.encode(federatorIndex, keyType.getValue()); - - if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getRetiringFederatorPublicKeyOfType( - federatorIndex, - keyType - ); - } - } else { - // Pre RSKIP123 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getStateForBtcReleaseClient(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_STATE_FOR_BTC_RELEASE_CLIENT; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getStateForBtcReleaseClient(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getStateForDebugging(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_STATE_FOR_DEBUGGING; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getStateForDebugging(); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getLockingCap(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Coin lockingCap = Coin.COIN; - when(bridgeSupportMock.getLockingCap()).thenReturn(lockingCap); - - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_LOCKING_CAP; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getLockingCap(); - } - } else { - // Pre RSKIP134 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getActivePowpegRedeemScript(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; - Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); - Script activePowpegRedeemScript = activeFederation.getRedeemScript(); - when(bridgeSupportMock.getActivePowpegRedeemScript()).thenReturn(Optional.of(activePowpegRedeemScript)); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_ACTIVE_POWPEG_REDEEM_SCRIPT; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP293, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getActivePowpegRedeemScript(); - } - } else { - // Pre RSKIP293 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getActiveFederationCreationBlockHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT.getFunction(); - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP186, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getActiveFederationCreationBlockHeight(); - } - } - else { - // Pre RSKIP186 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void increaseLockingCap(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - when(bridgeSupportMock.increaseLockingCap(any(), any())).thenReturn(true); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.INCREASE_LOCKING_CAP; - - long newLockingCap = 1; - byte[] data = function.encode(newLockingCap); - - if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).increaseLockingCap(any(), any()); - } - } - else { - // Pre RSKIP134 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void isBtcTxHashAlreadyProcessed(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { - Transaction rskTxMock = mock(Transaction.class); - doReturn(true).when(rskTxMock).isLocalCallTransaction(); - - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Sha256Hash btcTxHash = Sha256Hash.of("btcTxHash".getBytes()); - when(bridgeSupportMock.isBtcTxHashAlreadyProcessed(btcTxHash)).thenReturn(true); - - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.IS_BTC_TX_HASH_ALREADY_PROCESSED; - byte[] data = function.encode(btcTxHash.toString()); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).isBtcTxHashAlreadyProcessed(btcTxHash); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void receiveHeaders(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - Transaction rskTxMock = mock(Transaction.class); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - boolean receiveHeadersIsPublic = - activationConfig.isActive(ConsensusRule.RSKIP124, 0) - && !activationConfig.isActive(ConsensusRule.RSKIP200, 0); - - // Pre RSKIP124 and post RSKIP200 receiveHeaders is callable only from active or retiring federation fed members - if (!receiveHeadersIsPublic) { - int senderPK = 101; // Sender PK belongs to active federation member PKs - Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; - Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); - - ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); - RskAddress txSender = new RskAddress(key.getAddress()); - doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); - doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); - } - - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.RECEIVE_HEADERS; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).receiveHeaders(new BtcBlock[]{}); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void receiveHeader(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.RECEIVE_HEADER; - - BtcBlock btcBlock = new BtcBlock( - networkParameters, - 1, - BitcoinTestUtils.createHash(1), - BitcoinTestUtils.createHash(1), - 1, - 100L, - 1, - new ArrayList<>() - ).cloneAsHeader(); - - byte[] serializedBlockHeader = btcBlock.bitcoinSerialize(); - byte[] data = function.encode(serializedBlockHeader); - - if (activationConfig.isActive(ConsensusRule.RSKIP200, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).receiveHeader(any()); - } - } else { - // Pre RSKIP200 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void registerBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - Transaction rskTxMock = mock(Transaction.class); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - boolean registerBtcTransactionIsPublic = activationConfig.isActive(ConsensusRule.RSKIP199, 0); - // Before RSKIP199 registerBtcTransaction was callable only from active or retiring federation fed members - if (!registerBtcTransactionIsPublic) { - int senderPK = 101; // Sender PK belongs to active federation member PKs - Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; - Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); - - ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); - RskAddress txSender = new RskAddress(key.getAddress()); - doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); - doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); - } - - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.REGISTER_BTC_TRANSACTION; - - byte[] btcTxSerialized = new byte[]{1}; - int height = 0; - byte[] pmtSerialized = new byte[]{2}; - byte[] data = function.encode(btcTxSerialized, height, pmtSerialized); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).registerBtcTransaction( - any(Transaction.class), any(byte[].class), anyInt(), any(byte[].class) - ); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void releaseBtc(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.RELEASE_BTC; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).releaseBtc(any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void removeLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.REMOVE_LOCK_WHITELIST_ADDRESS; - - String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; - byte[] data = function.encode(addressBase58); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).removeLockWhitelistAddress(any(), any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void rollbackFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.ROLLBACK_FEDERATION; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void setLockWhiteListDisableBlockDelay(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.SET_LOCK_WHITELIST_DISABLE_BLOCK_DELAY; - - BigInteger disableBlockDelay = BigInteger.valueOf(100); - byte[] data = function.encode(disableBlockDelay); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).setLockWhitelistDisableBlockDelay(any(), any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void updateCollections(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - Transaction rskTxMock = mock(Transaction.class); - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - // updateCollections is only callable from active or retiring federation - int senderPK = 101; // Sender PK belongs to active federation member PKs - Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; - Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); - - ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); - RskAddress txSender = new RskAddress(key.getAddress()); - doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); - doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); - - Bridge bridge = bridgeBuilder - .transaction(rskTxMock) - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.UPDATE_COLLECTIONS; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).updateCollections(rskTxMock); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.VOTE_FEE_PER_KB; - - long feePerKB = 10_000; - byte[] data = function.encode(feePerKB); - - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).voteFeePerKbChange(any(), any()); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.REGISTER_BTC_COINBASE_TRANSACTION; - - byte[] value = new byte[32]; - byte[] data = function.encode(value, value, value, value, value); - - if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).registerBtcCoinbaseTransaction( - value, Sha256Hash.wrap(value), value, Sha256Hash.wrap(value), value); - } - } else { - // Pre RSKIP143 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void hasBtcBlockCoinbaseTransactionInformation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.HAS_BTC_BLOCK_COINBASE_TRANSACTION_INFORMATION; - - Sha256Hash blockHash = BitcoinTestUtils.createHash(2); - byte[] data = function.encode(blockHash.getBytes()); - - if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATICCALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).hasBtcBlockCoinbaseTransactionInformation(any()); - } - } else { - // Pre RSKIP143 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void registerFastBridgeBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.REGISTER_FAST_BRIDGE_BTC_TRANSACTION; - - byte[] btcTxSerialized = new byte[]{1}; - int height = 1; - byte[] pmtSerialized = new byte[]{2}; - Keccak256 derivationArgumentsHash = PegTestUtils.createHash3(2); - byte[] refundAddressSerialized = new byte[21]; - RskAddress lbcAddress = new RskAddress("0xFcE93641243D1EFB6131277cCD1c0a60460d5610"); - byte[] lpAddressSerialized = new byte[21]; - boolean shouldTransferToContract = true; - byte[] data = function.encode( - btcTxSerialized, - height, - pmtSerialized, - derivationArgumentsHash.getBytes(), - refundAddressSerialized, - lbcAddress.toHexString(), - lpAddressSerialized, - shouldTransferToContract - ); - - if (activationConfig.isActive(ConsensusRule.RSKIP176, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { - // Post arrowhead should fail for any msg type != CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).registerFlyoverBtcTransaction( - any(Transaction.class), - any(byte[].class), - anyInt(), - any(byte[].class), - any(Keccak256.class), - any(Address.class), - any(RskAddress.class), - any(Address.class), - any(boolean.class) - ); - } - } else { - // Pre RSKIP176 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBestBlockHeader(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BEST_BLOCK_HEADER; - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBestBlockHeader(); - } - } else { - // Pre RSKIP220 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBlockHeaderByHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HASH; - - byte[] hashBytes = new byte[32]; - byte[] data = function.encode(hashBytes); - - if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHeaderByHash(Sha256Hash.wrap(hashBytes)); - } - } else { - // Pre RSKIP220 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainBlockHeaderByHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HEIGHT; - - int height = 20; - byte[] data = function.encode(height); - - if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHeaderByHeight(height); - } - } else { - // Pre RSKIP220 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getBtcBlockchainParentBlockHeaderByHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = Bridge.GET_BTC_BLOCKCHAIN_PARENT_BLOCK_HEADER_BY_HASH; - - byte[] hashBytes = new byte[32]; - byte[] data = function.encode(hashBytes); - - if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getBtcBlockchainParentBlockHeaderByHash(any()); - } - } else { - // Pre RSKIP220 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getNextPegoutCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = BridgeMethods.GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER.getFunction(); - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getNextPegoutCreationBlockNumber(); - } - } else { - // Pre RSKIP271 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getQueuedPegoutsCount(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = BridgeMethods.GET_QUEUED_PEGOUTS_COUNT.getFunction(); - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getQueuedPegoutsCount(); - } - } else { - // Pre RSKIP271 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - @ParameterizedTest() - @MethodSource("msgTypesAndActivations") - void getEstimatedFeesForNextPegoutEvent(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { - BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); - Coin estimatedFeesForNextPegout = Coin.SATOSHI; - when(bridgeSupportMock.getEstimatedFeesForNextPegOutEvent()).thenReturn(estimatedFeesForNextPegout); - - Bridge bridge = bridgeBuilder - .activationConfig(activationConfig) - .bridgeSupport(bridgeSupportMock) - .msgType(msgType) - .build(); - - CallTransaction.Function function = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction(); - byte[] data = function.encode(); - - if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && - !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { - // Post arrowhead should fail for any msg type != CALL or STATIC CALL - assertThrows(VMException.class, () -> bridge.execute(data)); - } else { - bridge.execute(data); - verify(bridgeSupportMock, times(1)).getEstimatedFeesForNextPegOutEvent(); - } - } else { - // Pre RSKIP271 this method is not enabled, should fail for all message types - assertThrows(VMException.class, () -> bridge.execute(data)); - } - } - - private static Stream msgTypesAndActivations() { - List argumentsList = new ArrayList<>(); - List activationConfigs = Arrays.asList( - ActivationConfigsForTest.orchid(), - ActivationConfigsForTest.wasabi100(), - ActivationConfigsForTest.papyrus200(), - ActivationConfigsForTest.iris300(), - ActivationConfigsForTest.hop400(), - ActivationConfigsForTest.fingerroot500(), - ActivationConfigsForTest.arrowhead600() - ); - - for (MessageCall.MsgType msgType : MessageCall.MsgType.values()) { - for(ActivationConfig activationConfig : activationConfigs) { - argumentsList.add(Arguments.of(msgType, activationConfig)); - } - } - - return argumentsList.stream(); - } -} diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index e54210fd9bf..a766b437483 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1,5 +1,6 @@ package co.rsk.peg; +import static co.rsk.peg.PegTestUtils.createHash3; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; @@ -8,11 +9,13 @@ import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; import co.rsk.bitcoinj.store.BlockStoreException; +import co.rsk.config.BridgeConstants; import co.rsk.config.BridgeMainNetConstants; import co.rsk.config.BridgeRegTestConstants; import co.rsk.config.BridgeTestNetConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; +import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.test.builders.BridgeBuilder; import java.io.IOException; @@ -24,9 +27,11 @@ import org.ethereum.config.Constants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; +import org.ethereum.vm.MessageCall; import org.ethereum.vm.exception.VMException; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -1066,4 +1071,1956 @@ void getEstimatedFeesForNextPegOutEvent_after_RSKIP271_activation() throws VMExc long resultFromTheBridge = bridge.getEstimatedFeesForNextPegOutEvent(new Object[]{}); assertEquals(estimatedFeesForNextPegout.getValue(), resultFromTheBridge); } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.ADD_FEDERATOR_PUBLIC_KEY.getFunction(); + byte[] data = function.encode(Hex.decode(publicKey)); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addFederatorPublicKeyMultikey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String publicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.ADD_FEDERATOR_PUBLIC_KEY_MULTIKEY.getFunction(); + byte[] data = function.encode(Hex.decode(publicKey), Hex.decode(publicKey), Hex.decode(publicKey)); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + long maxTransferValue = 100_000L; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.ADD_LOCK_WHITELIST_ADDRESS.getFunction(); + byte[] data = function.encode(addressBase58, maxTransferValue); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + // Post RSKIP87 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( + any(), + any(), + any() + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addOneOffLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + long maxTransferValue = 100_000L; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.ADD_ONE_OFF_LOCK_WHITELIST_ADDRESS.getFunction(); + byte[] data = function.encode(addressBase58, maxTransferValue); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addOneOffLockWhitelistAddress( + any(), + any(), + any() + ); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addUnlimitedLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.ADD_UNLIMITED_LOCK_WHITELIST_ADDRESS.getFunction(); + byte[] data = function.encode(addressBase58); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addUnlimitedLockWhitelistAddress( + any(), + any() + ); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void addSignatures(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws Exception { + String pegnatoryPublicKey = "039a060badbeb24bee49eb2063f616c0f0f0765d4ca646b20a88ce828f259fcdb9"; + String signature = "3045022100a0963cea7551eb3174a3470c6ed25cda901c4b1093818d4d54792b87508820220220325f93b5aecc98385a664328e68d1cec7a2a2fe81810a7692358bd870aeecb74"; + List derEncodedSigs = Collections.singletonList(Hex.decode(signature)); + Keccak256 rskTxHash = createHash3(1); + + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + Transaction rskTxMock = mock(Transaction.class); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.ADD_SIGNATURE.getFunction(); + byte[] data = function.encode(Hex.decode(pegnatoryPublicKey), derEncodedSigs, rskTxHash.getBytes()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).addSignature( + any(), + any(), + any() + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void commitFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Keccak256 commitTransactionHash = createHash3(2); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.COMMIT_FEDERATION.getFunction(); + byte[] data = function.encode(commitTransactionHash.getBytes()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange( + any(), + any() + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void createFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.CREATE_FEDERATION.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange( + any(), + any() + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBestChainHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, BlockStoreException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBestChainHeight(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainInitialBlockHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainInitialBlockHeight(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockLocator(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_BLOCK_LOCATOR.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { + // Post RSKIP89 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockLocator(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockHashAtDepth(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int depth = 1000; + Sha256Hash blockHashAtDepth = BitcoinTestUtils.createHash(1); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getBtcBlockchainBlockHashAtDepth(depth)).thenReturn(blockHashAtDepth); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_BLOCK_HASH_AT_DEPTH.getFunction(); + byte[] data = function.encode(depth); + + if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHashAtDepth(depth); + } + } else { + // Pre RSKIP89 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcTransactionConfirmations(MessageCall.MsgType msgType, ActivationConfig activationConfig) + throws VMException, IOException, BlockStoreException { + + Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); + Sha256Hash btcBlockHash = BitcoinTestUtils.createHash(2); + int merkleBranchPath = 1; + List merkleBranchHashes = Arrays.asList( + BitcoinTestUtils.createHash(10), + BitcoinTestUtils.createHash(11), + BitcoinTestUtils.createHash(12) + ); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_TRANSACTION_CONFIRMATIONS.getFunction(); + byte[] data = function.encode( + btcTxHash.getBytes(), + btcBlockHash.getBytes(), + merkleBranchPath, + merkleBranchHashes.stream().map(Sha256Hash::getBytes).toArray() + ); + + if (activationConfig.isActive(ConsensusRule.RSKIP122, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcTransactionConfirmations( + any(), + any(), + any() + ); + } + } else { + // Pre RSKIP122 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcTxHashProcessedHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Sha256Hash btcTxHash = BitcoinTestUtils.createHash(1); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_TX_HASH_PROCESSED_HEIGHT.getFunction(); + byte[] data = function.encode(btcTxHash.toString()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcTxHashProcessedHeight(btcTxHash); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Address federationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFederationAddress()).thenReturn(federationAddress); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_FEDERATION_ADDRESS.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationAddress(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_FEDERATION_CREATION_BLOCK_NUMBER.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationCreationBlockNumber(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationCreationTime(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFederationCreationTime()).thenReturn(Instant.ofEpochSecond(100_000L)); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_FEDERATION_CREATION_TIME.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationCreationTime(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_FEDERATION_SIZE.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederationThreshold(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_FEDERATION_THRESHOLD.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederationThreshold(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int federatorIndex = 1; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_FEDERATOR_PUBLIC_KEY.getFunction(); + byte[] data = function.encode(federatorIndex); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederatorPublicKey(federatorIndex); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int federatorIndex = 1; + FederationMember.KeyType keyType = FederationMember.KeyType.BTC; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_FEDERATOR_PUBLIC_KEY_OF_TYPE.getFunction(); + byte[] data = function.encode(federatorIndex, keyType.getValue()); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFederatorPublicKeyOfType( + federatorIndex, + keyType + ); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Coin feePerKb = Coin.COIN; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFeePerKb()).thenReturn(feePerKb); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_FEE_PER_KB.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getFeePerKb(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int index = 1; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_LOCK_WHITELIST_ADDRESS.getFunction(); + byte[] data = function.encode(index); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByIndex(index); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistEntryByAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_LOCK_WHITELIST_ENTRY_BY_ADDRESS.getFunction(); + byte[] data = function.encode(addressBase58); + + if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistEntryByAddress(addressBase58); + } + } else { + // Pre RSKIP87 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockWhitelistSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_LOCK_WHITELIST_SIZE.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockWhitelistSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getMinimumLockTxValue(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + Coin minimumPeginTxValue = Coin.COIN; + BridgeConstants bridgeConstants = mock(BridgeConstants.class); + when(bridgeConstants.getMinimumPeginTxValue(any())).thenReturn(minimumPeginTxValue); + Constants constants = mock(Constants.class); + when(constants.getBridgeConstants()).thenReturn(bridgeConstants); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .constants(constants) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_MINIMUM_LOCK_TX_VALUE.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeConstants, times(1)).getMinimumPeginTxValue(any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederationHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_PENDING_FEDERATION_HASH.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederationHash(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException + { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_PENDING_FEDERATION_SIZE.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederationSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_PENDING_FEDERATOR_PUBLIC_KEY.getFunction(); + + int federatorIndex = 1; + byte[] data = function.encode(federatorIndex); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederatorPublicKey(federatorIndex); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getPendingFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_PENDING_FEDERATOR_PUBLIC_KEY_OF_TYPE.getFunction(); + + int federatorIndex = 1; + FederationMember.KeyType keyType = FederationMember.KeyType.BTC; + byte[] data = function.encode(federatorIndex, keyType.getValue()); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getPendingFederatorPublicKeyOfType( + federatorIndex, + keyType + ); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Address retiringFederationAddress = Address.fromBase58(networkParameters, "32Bhwee9FzQbuaG29RcXpdrvYnvZeMk11M"); + when(bridgeSupportMock.getRetiringFederationAddress()).thenReturn(retiringFederationAddress); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_ADDRESS.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationAddress(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_CREATION_BLOCK_NUMBER.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationCreationBlockNumber(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationCreationTime(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.getFederationCreationTime()).thenReturn(Instant.ofEpochSecond(100_000L)); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_CREATION_TIME.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationCreationTime(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationSize(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_SIZE.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationSize(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederationThreshold(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_THRESHOLD.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederationThreshold(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederatorPublicKey(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + int federatorIndex = 1; + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATOR_PUBLIC_KEY.getFunction(); + byte[] data = function.encode(federatorIndex); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + // Post RSKIP123 this method is no longer enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederatorPublicKey(federatorIndex); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getRetiringFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATOR_PUBLIC_KEY_OF_TYPE.getFunction(); + + int federatorIndex = 1; + FederationMember.KeyType keyType = FederationMember.KeyType.BTC; + byte[] data = function.encode(federatorIndex, keyType.getValue()); + + if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getRetiringFederatorPublicKeyOfType( + federatorIndex, + keyType + ); + } + } else { + // Pre RSKIP123 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getStateForBtcReleaseClient(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_STATE_FOR_BTC_RELEASE_CLIENT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getStateForBtcReleaseClient(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getStateForDebugging(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_STATE_FOR_DEBUGGING.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getStateForDebugging(); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getLockingCap(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Coin lockingCap = Coin.COIN; + when(bridgeSupportMock.getLockingCap()).thenReturn(lockingCap); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_LOCKING_CAP.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getLockingCap(); + } + } else { + // Pre RSKIP134 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getActivePowpegRedeemScript(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + Script activePowpegRedeemScript = activeFederation.getRedeemScript(); + when(bridgeSupportMock.getActivePowpegRedeemScript()).thenReturn(Optional.of(activePowpegRedeemScript)); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_ACTIVE_POWPEG_REDEEM_SCRIPT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP293, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getActivePowpegRedeemScript(); + } + } else { + // Pre RSKIP293 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getActiveFederationCreationBlockHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_ACTIVE_FEDERATION_CREATION_BLOCK_HEIGHT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP186, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getActiveFederationCreationBlockHeight(); + } + } + else { + // Pre RSKIP186 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void increaseLockingCap(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + when(bridgeSupportMock.increaseLockingCap(any(), any())).thenReturn(true); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.INCREASE_LOCKING_CAP.getFunction(); + + long newLockingCap = 1; + byte[] data = function.encode(newLockingCap); + + if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).increaseLockingCap(any(), any()); + } + } + else { + // Pre RSKIP134 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void isBtcTxHashAlreadyProcessed(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + Transaction rskTxMock = mock(Transaction.class); + doReturn(true).when(rskTxMock).isLocalCallTransaction(); + + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Sha256Hash btcTxHash = Sha256Hash.of("btcTxHash".getBytes()); + when(bridgeSupportMock.isBtcTxHashAlreadyProcessed(btcTxHash)).thenReturn(true); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.IS_BTC_TX_HASH_ALREADY_PROCESSED.getFunction(); + byte[] data = function.encode(btcTxHash.toString()); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).isBtcTxHashAlreadyProcessed(btcTxHash); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void receiveHeaders(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + boolean receiveHeadersIsPublic = + activationConfig.isActive(ConsensusRule.RSKIP124, 0) + && !activationConfig.isActive(ConsensusRule.RSKIP200, 0); + + // Pre RSKIP124 and post RSKIP200 receiveHeaders is callable only from active or retiring federation fed members + if (!receiveHeadersIsPublic) { + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + } + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.RECEIVE_HEADERS.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).receiveHeaders(new BtcBlock[]{}); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void receiveHeader(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.RECEIVE_HEADER.getFunction(); + + BtcBlock btcBlock = new BtcBlock( + networkParameters, + 1, + BitcoinTestUtils.createHash(1), + BitcoinTestUtils.createHash(1), + 1, + 100L, + 1, + new ArrayList<>() + ).cloneAsHeader(); + + byte[] serializedBlockHeader = btcBlock.bitcoinSerialize(); + byte[] data = function.encode(serializedBlockHeader); + + if (activationConfig.isActive(ConsensusRule.RSKIP200, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).receiveHeader(any()); + } + } else { + // Pre RSKIP200 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void registerBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + boolean registerBtcTransactionIsPublic = activationConfig.isActive(ConsensusRule.RSKIP199, 0); + // Before RSKIP199 registerBtcTransaction was callable only from active or retiring federation fed members + if (!registerBtcTransactionIsPublic) { + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + } + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.REGISTER_BTC_TRANSACTION.getFunction(); + + byte[] btcTxSerialized = new byte[]{1}; + int height = 0; + byte[] pmtSerialized = new byte[]{2}; + byte[] data = function.encode(btcTxSerialized, height, pmtSerialized); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).registerBtcTransaction( + any(Transaction.class), any(byte[].class), anyInt(), any(byte[].class) + ); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void releaseBtc(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.RELEASE_BTC.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).releaseBtc(any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void removeLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.REMOVE_LOCK_WHITELIST_ADDRESS.getFunction(); + + String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; + byte[] data = function.encode(addressBase58); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).removeLockWhitelistAddress(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void rollbackFederation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.ROLLBACK_FEDERATION.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFederationChange(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void setLockWhiteListDisableBlockDelay(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.SET_LOCK_WHITELIST_DISABLE_BLOCK_DELAY.getFunction(); + + BigInteger disableBlockDelay = BigInteger.valueOf(100); + byte[] data = function.encode(disableBlockDelay); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).setLockWhitelistDisableBlockDelay(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void updateCollections(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + Transaction rskTxMock = mock(Transaction.class); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + // updateCollections is only callable from active or retiring federation + int senderPK = 101; // Sender PK belongs to active federation member PKs + Integer[] activeMemberPKs = new Integer[]{ 100, 200, 300, 400, 500, 600 }; + Federation activeFederation = FederationTestUtils.getFederation(activeMemberPKs); + + ECKey key = ECKey.fromPrivate(BigInteger.valueOf(senderPK)); + RskAddress txSender = new RskAddress(key.getAddress()); + doReturn(txSender).when(rskTxMock).getSender(any(SignatureCache.class)); + doReturn(activeFederation).when(bridgeSupportMock).getActiveFederation(); + + Bridge bridge = bridgeBuilder + .transaction(rskTxMock) + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.UPDATE_COLLECTIONS.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).updateCollections(rskTxMock); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.VOTE_FEE_PER_KB.getFunction(); + + long feePerKB = 10_000; + byte[] data = function.encode(feePerKB); + + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).voteFeePerKbChange(any(), any()); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.REGISTER_BTC_COINBASE_TRANSACTION.getFunction(); + + byte[] value = new byte[32]; + byte[] data = function.encode(value, value, value, value, value); + + if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).registerBtcCoinbaseTransaction( + value, Sha256Hash.wrap(value), value, Sha256Hash.wrap(value), value); + } + } else { + // Pre RSKIP143 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void hasBtcBlockCoinbaseTransactionInformation(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.HAS_BTC_BLOCK_COINBASE_TRANSACTION_INFORMATION.getFunction(); + + Sha256Hash blockHash = BitcoinTestUtils.createHash(2); + byte[] data = function.encode(blockHash.getBytes()); + + if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATICCALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).hasBtcBlockCoinbaseTransactionInformation(any()); + } + } else { + // Pre RSKIP143 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void registerFastBridgeBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.REGISTER_FAST_BRIDGE_BTC_TRANSACTION.getFunction(); + + byte[] btcTxSerialized = new byte[]{1}; + int height = 1; + byte[] pmtSerialized = new byte[]{2}; + Keccak256 derivationArgumentsHash = PegTestUtils.createHash3(2); + byte[] refundAddressSerialized = new byte[21]; + RskAddress lbcAddress = new RskAddress("0xFcE93641243D1EFB6131277cCD1c0a60460d5610"); + byte[] lpAddressSerialized = new byte[21]; + boolean shouldTransferToContract = true; + byte[] data = function.encode( + btcTxSerialized, + height, + pmtSerialized, + derivationArgumentsHash.getBytes(), + refundAddressSerialized, + lbcAddress.toHexString(), + lpAddressSerialized, + shouldTransferToContract + ); + + if (activationConfig.isActive(ConsensusRule.RSKIP176, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + // Post arrowhead should fail for any msg type != CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).registerFlyoverBtcTransaction( + any(Transaction.class), + any(byte[].class), + anyInt(), + any(byte[].class), + any(Keccak256.class), + any(Address.class), + any(RskAddress.class), + any(Address.class), + any(boolean.class) + ); + } + } else { + // Pre RSKIP176 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBestBlockHeader(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_BLOCK_HEADER.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBestBlockHeader(); + } + } else { + // Pre RSKIP220 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockHeaderByHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HASH.getFunction(); + + byte[] hashBytes = new byte[32]; + byte[] data = function.encode(hashBytes); + + if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHeaderByHash(Sha256Hash.wrap(hashBytes)); + } + } else { + // Pre RSKIP220 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainBlockHeaderByHeight(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_BLOCK_HEADER_BY_HEIGHT.getFunction(); + + int height = 20; + byte[] data = function.encode(height); + + if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainBlockHeaderByHeight(height); + } + } else { + // Pre RSKIP220 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getBtcBlockchainParentBlockHeaderByHash(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_PARENT_BLOCK_HEADER_BY_HASH.getFunction(); + + byte[] hashBytes = new byte[32]; + byte[] data = function.encode(hashBytes); + + if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getBtcBlockchainParentBlockHeaderByHash(any()); + } + } else { + // Pre RSKIP220 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getNextPegoutCreationBlockNumber(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException, BlockStoreException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_NEXT_PEGOUT_CREATION_BLOCK_NUMBER.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getNextPegoutCreationBlockNumber(); + } + } else { + // Pre RSKIP271 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getQueuedPegoutsCount(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_QUEUED_PEGOUTS_COUNT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getQueuedPegoutsCount(); + } + } else { + // Pre RSKIP271 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + @ParameterizedTest() + @MethodSource("msgTypesAndActivations") + void getEstimatedFeesForNextPegoutEvent(MessageCall.MsgType msgType, ActivationConfig activationConfig) throws VMException, IOException { + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); + Coin estimatedFeesForNextPegout = Coin.SATOSHI; + when(bridgeSupportMock.getEstimatedFeesForNextPegOutEvent()).thenReturn(estimatedFeesForNextPegout); + + Bridge bridge = bridgeBuilder + .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) + .msgType(msgType) + .build(); + + CallTransaction.Function function = BridgeMethods.GET_ESTIMATED_FEES_FOR_NEXT_PEGOUT_EVENT.getFunction(); + byte[] data = function.encode(); + + if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { + // Post arrowhead should fail for any msg type != CALL or STATIC CALL + assertThrows(VMException.class, () -> bridge.execute(data)); + } else { + bridge.execute(data); + verify(bridgeSupportMock, times(1)).getEstimatedFeesForNextPegOutEvent(); + } + } else { + // Pre RSKIP271 this method is not enabled, should fail for all message types + assertThrows(VMException.class, () -> bridge.execute(data)); + } + } + + private static Stream msgTypesAndActivations() { + List argumentsList = new ArrayList<>(); + List activationConfigs = Arrays.asList( + ActivationConfigsForTest.orchid(), + ActivationConfigsForTest.wasabi100(), + ActivationConfigsForTest.papyrus200(), + ActivationConfigsForTest.iris300(), + ActivationConfigsForTest.hop400(), + ActivationConfigsForTest.fingerroot500(), + ActivationConfigsForTest.arrowhead600() + ); + + for (MessageCall.MsgType msgType : MessageCall.MsgType.values()) { + for(ActivationConfig activationConfig : activationConfigs) { + argumentsList.add(Arguments.of(msgType, activationConfig)); + } + } + + return argumentsList.stream(); + } } From 5fc00996892cac2b01d76a279c4a2ef60f387c41 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 26 Jan 2024 16:40:25 -0300 Subject: [PATCH 108/137] Refactor Bridge execute method to have the current behaviour as the default one --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 5028768f10b..ebb872f1f76 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -367,11 +367,11 @@ public byte[] execute(byte[] data) throws VMException { if (bridgeParsedData == null) { String errorMessage = String.format("Invalid data given: %s.", ByteUtil.toHexString(data)); logger.info("[execute] {}", errorMessage); - if (activations.isActive(ConsensusRule.RSKIP88)) { - throw new BridgeIllegalArgumentException(errorMessage); + if (!activations.isActive(ConsensusRule.RSKIP88)) { + return null; } - return null; + throw new BridgeIllegalArgumentException(errorMessage); } validateCall(bridgeParsedData); @@ -384,16 +384,16 @@ public byte[] execute(byte[] data) throws VMException { } catch (BridgeIllegalArgumentException ex) { String errorMessage = String.format("Error executing: %s", bridgeParsedData.bridgeMethod); logger.warn(errorMessage, ex); - if (activations.isActive(ConsensusRule.RSKIP88)) { - throw new BridgeIllegalArgumentException(errorMessage); + if (!activations.isActive(ConsensusRule.RSKIP88)) { + return null; } - return null; + throw new BridgeIllegalArgumentException(errorMessage); } teardown(); - return result.map(bridgeParsedData.bridgeMethod.getFunction()::encodeOutputs).orElse(null); + return result.map(bridgeParsedData.bridgeMethod.getFunction()::encodeOutputs).orElse(new byte[]{}); } catch (Exception ex) { logger.error(ex.getMessage(), ex); panicProcessor.panic("bridgeexecute", ex.getMessage()); From 46c4e4de87b3ac362557c1862036b2ef19fa9a4b Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 26 Jan 2024 17:04:32 -0300 Subject: [PATCH 109/137] Return empty array for void Bridge methods executions --- .../src/main/java/co/rsk/peg/Bridge.java | 42 +++++++++++-------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index ebb872f1f76..9e62b51e0a0 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -26,6 +26,7 @@ import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.panic.PanicProcessor; +import co.rsk.peg.BridgeMethods.BridgeMethodExecutor; import co.rsk.peg.bitcoin.MerkleBranch; import co.rsk.peg.flyover.FlyoverTxResponseCodes; import co.rsk.peg.utils.BtcTransactionFormatUtils; @@ -375,25 +376,15 @@ public byte[] execute(byte[] data) throws VMException { } validateCall(bridgeParsedData); + Optional result = executeBridgeMethod(bridgeParsedData); + teardown(); - Optional result; - try { - // bridgeParsedData.function should be one of the CallTransaction.Function declared above. - // If the user tries to call an non-existent function, parseData() will return null. - result = bridgeParsedData.bridgeMethod.getExecutor().execute(this, bridgeParsedData.args); - } catch (BridgeIllegalArgumentException ex) { - String errorMessage = String.format("Error executing: %s", bridgeParsedData.bridgeMethod); - logger.warn(errorMessage, ex); - if (!activations.isActive(ConsensusRule.RSKIP88)) { - return null; - } - - throw new BridgeIllegalArgumentException(errorMessage); + byte[] voidReturnValue = new byte[]{}; + if (!activations.isActive(RSKIP_ARROWHEAD)) { + voidReturnValue = null; } - teardown(); - - return result.map(bridgeParsedData.bridgeMethod.getFunction()::encodeOutputs).orElse(new byte[]{}); + return result.map(bridgeParsedData.bridgeMethod.getFunction()::encodeOutputs).orElse(voidReturnValue); } catch (Exception ex) { logger.error(ex.getMessage(), ex); panicProcessor.panic("bridgeexecute", ex.getMessage()); @@ -430,7 +421,24 @@ private void validateCallMessageType(BridgeParsedData bridgeParsedData) throws B bridgeParsedData.bridgeMethod.getFunction().name ); logger.info("[validateCallMessageType] {}", errorMessage); - // TODO: determine which type of exception makes sense for this case + + throw new BridgeIllegalArgumentException(errorMessage); + } + } + + private Optional executeBridgeMethod(BridgeParsedData bridgeParsedData) throws Exception { + try { + // bridgeParsedData.function should be one of the CallTransaction.Function declared above. + // If the user tries to call an non-existent function, parseData() will return null. + BridgeMethodExecutor executor = bridgeParsedData.bridgeMethod.getExecutor(); + return executor.execute(this, bridgeParsedData.args); + } catch (BridgeIllegalArgumentException ex) { + String errorMessage = String.format("Error executing: %s", bridgeParsedData.bridgeMethod); + logger.warn(errorMessage, ex); + if (!activations.isActive(ConsensusRule.RSKIP88)) { + return null; + } + throw new BridgeIllegalArgumentException(errorMessage); } } From bfb0e3183ca1c31db1dda8508508754d1ab6d070 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 26 Jan 2024 17:09:49 -0300 Subject: [PATCH 110/137] Rename RSKIP_ARROWHEAD to RSKIP414 --- .../src/main/java/co/rsk/peg/Bridge.java | 6 +- .../blockchain/upgrades/ConsensusRule.java | 2 +- rskj-core/src/main/resources/reference.conf | 2 +- .../src/test/java/co/rsk/peg/BridgeTest.java | 114 +++++++++--------- .../upgrades/ActivationConfigsForTest.java | 4 +- 5 files changed, 64 insertions(+), 64 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 9e62b51e0a0..5349b435850 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -17,7 +17,7 @@ */ package co.rsk.peg; -import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP_ARROWHEAD; +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP414; import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; @@ -380,7 +380,7 @@ public byte[] execute(byte[] data) throws VMException { teardown(); byte[] voidReturnValue = new byte[]{}; - if (!activations.isActive(RSKIP_ARROWHEAD)) { + if (!activations.isActive(RSKIP414)) { voidReturnValue = null; } @@ -413,7 +413,7 @@ private void validateLocalCall(BridgeParsedData bridgeParsedData) throws BridgeI } private void validateCallMessageType(BridgeParsedData bridgeParsedData) throws BridgeIllegalArgumentException { - if (activations.isActive(RSKIP_ARROWHEAD) && + if (activations.isActive(RSKIP414) && !bridgeParsedData.bridgeMethod.acceptsThisTypeOfCall(this.msgType)) { String errorMessage = String.format( "Call type (%s) not accepted by %s. Returning without execution.", diff --git a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java index 9b7b37315d0..cef4b0bbcd2 100644 --- a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java +++ b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java @@ -91,8 +91,8 @@ public enum ConsensusRule { RSKIP398("rskip398"), RSKIP400("rskip400"), // From EIP-2028 calldata gas cost reduction RSKIP412("rskip412"), // From EIP-3198 BASEFEE opcode + RSKIP414("rskip414"), RSKIP415("rskip415"), - RSKIP_ARROWHEAD("RSKIP_ARROWHEAD"), // TODO: define what activation we will be using for the bridge patch ; private String configKey; diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 34b7e01bfae..55257c50fee 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -77,8 +77,8 @@ blockchain = { rskip398 = arrowhead600 rskip400 = arrowhead600 rskip412 = arrowhead600 + rskip414 = arrowhead600 rskip415 = arrowhead600 - rskipArrowhead = arrowhead600 } } gc = { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index a766b437483..d4b513fc70d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1110,7 +1110,7 @@ void addFederatorPublicKeyMultikey(MessageCall.MsgType msgType, ActivationConfig byte[] data = function.encode(Hex.decode(publicKey), Hex.decode(publicKey), Hex.decode(publicKey)); if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1167,7 +1167,7 @@ void addOneOffLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig byte[] data = function.encode(addressBase58, maxTransferValue); if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1199,7 +1199,7 @@ void addUnlimitedLockWhitelistAddress(MessageCall.MsgType msgType, ActivationCon byte[] data = function.encode(addressBase58); if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1244,7 +1244,7 @@ void addSignatures(MessageCall.MsgType msgType, ActivationConfig activationConfi CallTransaction.Function function = BridgeMethods.ADD_SIGNATURE.getFunction(); byte[] data = function.encode(Hex.decode(pegnatoryPublicKey), derEncodedSigs, rskTxHash.getBytes()); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1271,7 +1271,7 @@ void commitFederation(MessageCall.MsgType msgType, ActivationConfig activationCo CallTransaction.Function function = BridgeMethods.COMMIT_FEDERATION.getFunction(); byte[] data = function.encode(commitTransactionHash.getBytes()); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1296,7 +1296,7 @@ void createFederation(MessageCall.MsgType msgType, ActivationConfig activationCo CallTransaction.Function function = BridgeMethods.CREATE_FEDERATION.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1326,7 +1326,7 @@ void getBtcBlockchainBestChainHeight(MessageCall.MsgType msgType, ActivationConf CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1354,7 +1354,7 @@ void getBtcBlockchainInitialBlockHeight(MessageCall.MsgType msgType, ActivationC CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1413,7 +1413,7 @@ void getBtcBlockchainBlockHashAtDepth(MessageCall.MsgType msgType, ActivationCon byte[] data = function.encode(depth); if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1456,7 +1456,7 @@ void getBtcTransactionConfirmations(MessageCall.MsgType msgType, ActivationConfi ); if (activationConfig.isActive(ConsensusRule.RSKIP122, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1492,7 +1492,7 @@ void getBtcTxHashProcessedHeight(MessageCall.MsgType msgType, ActivationConfig a CallTransaction.Function function = BridgeMethods.GET_BTC_TX_HASH_PROCESSED_HEIGHT.getFunction(); byte[] data = function.encode(btcTxHash.toString()); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1521,7 +1521,7 @@ void getFederationAddress(MessageCall.MsgType msgType, ActivationConfig activati CallTransaction.Function function = BridgeMethods.GET_FEDERATION_ADDRESS.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1548,7 +1548,7 @@ void getFederationCreationBlockNumber(MessageCall.MsgType msgType, ActivationCon CallTransaction.Function function = BridgeMethods.GET_FEDERATION_CREATION_BLOCK_NUMBER.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1576,7 +1576,7 @@ void getFederationCreationTime(MessageCall.MsgType msgType, ActivationConfig act CallTransaction.Function function = BridgeMethods.GET_FEDERATION_CREATION_TIME.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1603,7 +1603,7 @@ void getFederationSize(MessageCall.MsgType msgType, ActivationConfig activationC CallTransaction.Function function = BridgeMethods.GET_FEDERATION_SIZE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1630,7 +1630,7 @@ void getFederationThreshold(MessageCall.MsgType msgType, ActivationConfig activa CallTransaction.Function function = BridgeMethods.GET_FEDERATION_THRESHOLD.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1687,7 +1687,7 @@ void getFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig a byte[] data = function.encode(federatorIndex, keyType.getValue()); if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1723,7 +1723,7 @@ void getFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) CallTransaction.Function function = BridgeMethods.GET_FEE_PER_KB.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1751,7 +1751,7 @@ void getLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activ CallTransaction.Function function = BridgeMethods.GET_LOCK_WHITELIST_ADDRESS.getFunction(); byte[] data = function.encode(index); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1780,7 +1780,7 @@ void getLockWhitelistEntryByAddress(MessageCall.MsgType msgType, ActivationConfi byte[] data = function.encode(addressBase58); if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1811,7 +1811,7 @@ void getLockWhitelistSize(MessageCall.MsgType msgType, ActivationConfig activati CallTransaction.Function function = BridgeMethods.GET_LOCK_WHITELIST_SIZE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1845,7 +1845,7 @@ void getMinimumLockTxValue(MessageCall.MsgType msgType, ActivationConfig activat CallTransaction.Function function = BridgeMethods.GET_MINIMUM_LOCK_TX_VALUE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1872,7 +1872,7 @@ void getPendingFederationHash(MessageCall.MsgType msgType, ActivationConfig acti CallTransaction.Function function = BridgeMethods.GET_PENDING_FEDERATION_HASH.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1900,7 +1900,7 @@ void getPendingFederationSize(MessageCall.MsgType msgType, ActivationConfig acti CallTransaction.Function function = BridgeMethods.GET_PENDING_FEDERATION_SIZE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1959,7 +1959,7 @@ void getPendingFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationC byte[] data = function.encode(federatorIndex, keyType.getValue()); if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1996,7 +1996,7 @@ void getRetiringFederationAddress(MessageCall.MsgType msgType, ActivationConfig CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_ADDRESS.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2023,7 +2023,7 @@ void getRetiringFederationCreationBlockNumber(MessageCall.MsgType msgType, Activ CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_CREATION_BLOCK_NUMBER.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2051,7 +2051,7 @@ void getRetiringFederationCreationTime(MessageCall.MsgType msgType, ActivationCo CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_CREATION_TIME.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2078,7 +2078,7 @@ void getRetiringFederationSize(MessageCall.MsgType msgType, ActivationConfig act CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_SIZE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2105,7 +2105,7 @@ void getRetiringFederationThreshold(MessageCall.MsgType msgType, ActivationConfi CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_THRESHOLD.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2163,7 +2163,7 @@ void getRetiringFederatorPublicKeyOfType(MessageCall.MsgType msgType, Activation byte[] data = function.encode(federatorIndex, keyType.getValue()); if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2197,7 +2197,7 @@ void getStateForBtcReleaseClient(MessageCall.MsgType msgType, ActivationConfig a CallTransaction.Function function = BridgeMethods.GET_STATE_FOR_BTC_RELEASE_CLIENT.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2224,7 +2224,7 @@ void getStateForDebugging(MessageCall.MsgType msgType, ActivationConfig activati CallTransaction.Function function = BridgeMethods.GET_STATE_FOR_DEBUGGING.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2255,7 +2255,7 @@ void getLockingCap(MessageCall.MsgType msgType, ActivationConfig activationConfi byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2288,7 +2288,7 @@ void getActivePowpegRedeemScript(MessageCall.MsgType msgType, ActivationConfig a byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP293, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2316,7 +2316,7 @@ void getActiveFederationCreationBlockHeight(MessageCall.MsgType msgType, Activat byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP186, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2349,7 +2349,7 @@ void increaseLockingCap(MessageCall.MsgType msgType, ActivationConfig activation byte[] data = function.encode(newLockingCap); if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2383,7 +2383,7 @@ void isBtcTxHashAlreadyProcessed(MessageCall.MsgType msgType, ActivationConfig a CallTransaction.Function function = BridgeMethods.IS_BTC_TX_HASH_ALREADY_PROCESSED.getFunction(); byte[] data = function.encode(btcTxHash.toString()); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2425,7 +2425,7 @@ void receiveHeaders(MessageCall.MsgType msgType, ActivationConfig activationConf CallTransaction.Function function = BridgeMethods.RECEIVE_HEADERS.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2463,7 +2463,7 @@ void receiveHeader(MessageCall.MsgType msgType, ActivationConfig activationConfi byte[] data = function.encode(serializedBlockHeader); if (activationConfig.isActive(ConsensusRule.RSKIP200, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2509,7 +2509,7 @@ void registerBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activa byte[] pmtSerialized = new byte[]{2}; byte[] data = function.encode(btcTxSerialized, height, pmtSerialized); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2534,7 +2534,7 @@ void releaseBtc(MessageCall.MsgType msgType, ActivationConfig activationConfig) CallTransaction.Function function = BridgeMethods.RELEASE_BTC.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2559,7 +2559,7 @@ void removeLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig ac String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; byte[] data = function.encode(addressBase58); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2582,7 +2582,7 @@ void rollbackFederation(MessageCall.MsgType msgType, ActivationConfig activation CallTransaction.Function function = BridgeMethods.ROLLBACK_FEDERATION.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2606,7 +2606,7 @@ void setLockWhiteListDisableBlockDelay(MessageCall.MsgType msgType, ActivationCo BigInteger disableBlockDelay = BigInteger.valueOf(100); byte[] data = function.encode(disableBlockDelay); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2642,7 +2642,7 @@ void updateCollections(MessageCall.MsgType msgType, ActivationConfig activationC CallTransaction.Function function = BridgeMethods.UPDATE_COLLECTIONS.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2667,7 +2667,7 @@ void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig long feePerKB = 10_000; byte[] data = function.encode(feePerKB); - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2693,7 +2693,7 @@ void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfi byte[] data = function.encode(value, value, value, value, value); if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2723,7 +2723,7 @@ void hasBtcBlockCoinbaseTransactionInformation(MessageCall.MsgType msgType, Acti byte[] data = function.encode(blockHash.getBytes()); if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATICCALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2769,7 +2769,7 @@ void registerFastBridgeBtcTransaction(MessageCall.MsgType msgType, ActivationCon ); if (activationConfig.isActive(ConsensusRule.RSKIP176, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2807,7 +2807,7 @@ void getBtcBlockchainBestBlockHeader(MessageCall.MsgType msgType, ActivationConf byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2838,7 +2838,7 @@ void getBtcBlockchainBlockHeaderByHash(MessageCall.MsgType msgType, ActivationCo byte[] data = function.encode(hashBytes); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2869,7 +2869,7 @@ void getBtcBlockchainBlockHeaderByHeight(MessageCall.MsgType msgType, Activation byte[] data = function.encode(height); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2900,7 +2900,7 @@ void getBtcBlockchainParentBlockHeaderByHash(MessageCall.MsgType msgType, Activa byte[] data = function.encode(hashBytes); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2929,7 +2929,7 @@ void getNextPegoutCreationBlockNumber(MessageCall.MsgType msgType, ActivationCon byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2958,7 +2958,7 @@ void getQueuedPegoutsCount(MessageCall.MsgType msgType, ActivationConfig activat byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2989,7 +2989,7 @@ void getEstimatedFeesForNextPegoutEvent(MessageCall.MsgType msgType, ActivationC byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP_ARROWHEAD, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java index afb38d7564e..882ae05b71a 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java @@ -184,8 +184,8 @@ private static List getArrowhead600Rskips() { ConsensusRule.RSKIP379, ConsensusRule.RSKIP398, ConsensusRule.RSKIP400, - ConsensusRule.RSKIP415, - ConsensusRule.RSKIP_ARROWHEAD + ConsensusRule.RSKIP414, + ConsensusRule.RSKIP415 )); return rskips; From a6857219fb946749abd9743b26fdbdcb04ace5d4 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 26 Jan 2024 17:48:50 -0300 Subject: [PATCH 111/137] Assert correct response value of void Bridge methods --- .../src/main/java/co/rsk/peg/Bridge.java | 9 ++- .../src/test/java/co/rsk/peg/BridgeTest.java | 74 ++++++++++++++----- 2 files changed, 63 insertions(+), 20 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 5349b435850..a34cc844038 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -1160,7 +1160,14 @@ public void registerBtcCoinbaseTransaction(Object[] args) throws VMException { byte[] pmtSerialized = (byte[]) args[2]; Sha256Hash witnessMerkleRoot = Sha256Hash.wrap((byte[]) args[3]); byte[] witnessReservedValue = (byte[]) args[4]; - bridgeSupport.registerBtcCoinbaseTransaction(btcTxSerialized, blockHash, pmtSerialized, witnessMerkleRoot, witnessReservedValue); + + bridgeSupport.registerBtcCoinbaseTransaction( + btcTxSerialized, + blockHash, + pmtSerialized, + witnessMerkleRoot, + witnessReservedValue + ); } public boolean hasBtcBlockCoinbaseTransactionInformation(Object[] args) { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index d4b513fc70d..3b22d4801b7 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -40,6 +40,7 @@ import org.junit.jupiter.params.provider.MethodSource; class BridgeTest { + private static final byte[] EMPTY_BYTE_ARRAY = new byte[]{}; private NetworkParameters networkParameters; private BridgeBuilder bridgeBuilder; @@ -694,26 +695,29 @@ void receiveHeader_empty_parameter() { @Test void receiveHeader_after_RSKIP200_Ok() throws VMException { ActivationConfig activationConfig = ActivationConfigsForTest.iris300(); + BridgeSupport bridgeSupportMock = mock(BridgeSupport.class); Bridge bridge = bridgeBuilder .activationConfig(activationConfig) + .bridgeSupport(bridgeSupportMock) .build(); co.rsk.bitcoinj.core.BtcBlock block = new co.rsk.bitcoinj.core.BtcBlock( networkParameters, 1, - PegTestUtils.createHash(1), - PegTestUtils.createHash(1), - 1, - Utils.encodeCompactBits(networkParameters.getMaxTarget()), - 1, + BitcoinTestUtils.createHash(1), + BitcoinTestUtils.createHash(2), + 1L, + 100L, + 1L, new ArrayList<>() ).cloneAsHeader(); - Object[] parameters = new Object[]{block.bitcoinSerialize()}; - byte[] data = Bridge.RECEIVE_HEADER.encode(parameters); + CallTransaction.Function function = BridgeMethods.RECEIVE_HEADER.getFunction(); + + byte[] data = function.encode(block.bitcoinSerialize()); byte[] result = bridge.execute(data); - BigInteger decodedResult = (BigInteger) Bridge.RECEIVE_HEADER.decodeResult(result)[0]; + BigInteger decodedResult = (BigInteger) function.decodeResult(result)[0]; assertEquals(BigInteger.valueOf(0), decodedResult); } @@ -1248,7 +1252,8 @@ void addSignatures(MessageCall.MsgType msgType, ActivationConfig activationConfi // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { - bridge.execute(data); + byte[] result = bridge.execute(data); + assertVoidMethodResult(activationConfig, result); verify(bridgeSupportMock, times(1)).addSignature( any(), any(), @@ -2430,7 +2435,8 @@ void receiveHeaders(MessageCall.MsgType msgType, ActivationConfig activationConf // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { - bridge.execute(data); + byte[] result = bridge.execute(data); + assertVoidMethodResult(activationConfig, result); verify(bridgeSupportMock, times(1)).receiveHeaders(new BtcBlock[]{}); } } @@ -2452,7 +2458,7 @@ void receiveHeader(MessageCall.MsgType msgType, ActivationConfig activationConfi networkParameters, 1, BitcoinTestUtils.createHash(1), - BitcoinTestUtils.createHash(1), + BitcoinTestUtils.createHash(2), 1, 100L, 1, @@ -2514,9 +2520,13 @@ void registerBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activa // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { - bridge.execute(data); + byte[] result = bridge.execute(data); + assertVoidMethodResult(activationConfig, result); verify(bridgeSupportMock, times(1)).registerBtcTransaction( - any(Transaction.class), any(byte[].class), anyInt(), any(byte[].class) + any(Transaction.class), + any(byte[].class), + anyInt(), + any(byte[].class) ); } } @@ -2539,7 +2549,8 @@ void releaseBtc(MessageCall.MsgType msgType, ActivationConfig activationConfig) // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { - bridge.execute(data); + byte[] result = bridge.execute(data); + assertVoidMethodResult(activationConfig, result); verify(bridgeSupportMock, times(1)).releaseBtc(any()); } } @@ -2647,7 +2658,8 @@ void updateCollections(MessageCall.MsgType msgType, ActivationConfig activationC // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { - bridge.execute(data); + byte[] result = bridge.execute(data); + assertVoidMethodResult(activationConfig, result); verify(bridgeSupportMock, times(1)).updateCollections(rskTxMock); } } @@ -2689,17 +2701,33 @@ void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfi CallTransaction.Function function = BridgeMethods.REGISTER_BTC_COINBASE_TRANSACTION.getFunction(); - byte[] value = new byte[32]; - byte[] data = function.encode(value, value, value, value, value); + byte[] btcTxSerialized = EMPTY_BYTE_ARRAY; + Sha256Hash blockHash = BitcoinTestUtils.createHash(1); + byte[] pmtSerialized = EMPTY_BYTE_ARRAY; + Sha256Hash witnessMerkleRoot = BitcoinTestUtils.createHash(2); + byte[] witnessReservedValue = new byte[32]; + byte[] data = function.encode( + btcTxSerialized, + blockHash.getBytes(), + pmtSerialized, + witnessMerkleRoot.getBytes(), + witnessReservedValue + ); if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { - bridge.execute(data); + byte[] result = bridge.execute(data); + assertVoidMethodResult(activationConfig, result); verify(bridgeSupportMock, times(1)).registerBtcCoinbaseTransaction( - value, Sha256Hash.wrap(value), value, Sha256Hash.wrap(value), value); + btcTxSerialized, + blockHash, + pmtSerialized, + witnessMerkleRoot, + witnessReservedValue + ); } } else { // Pre RSKIP143 this method is not enabled, should fail for all message types @@ -3023,4 +3051,12 @@ private static Stream msgTypesAndActivations() { return argumentsList.stream(); } + + private void assertVoidMethodResult(ActivationConfig activationConfig, byte[] result) { + if (activationConfig.isActive(ConsensusRule.RSKIP414, 0)) { + assertArrayEquals(EMPTY_BYTE_ARRAY, result); + } else { + assertNull(result); + } + } } From 5ac7267c1a75c96d04c3d5218ec1a1d70ef365be Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 29 Jan 2024 16:27:31 -0300 Subject: [PATCH 112/137] Add new log messages to BridgeSupport::releaseBtc --- .../main/java/co/rsk/peg/BridgeSupport.java | 49 +++++++++++++------ 1 file changed, 33 insertions(+), 16 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 fc9e8f0c332..36f6c6e1ac5 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -833,39 +833,56 @@ private void saveNewUTXOs(BtcTransaction btcTx) throws IOException { * @throws IOException */ public void releaseBtc(Transaction rskTx) throws IOException { - Coin value = rskTx.getValue().toBitcoin(); + Coin pegoutValue = rskTx.getValue().toBitcoin(); final RskAddress senderAddress = rskTx.getSender(signatureCache); - //as we can't send btc from contracts we want to send them back to the senderAddressStr + logger.debug( + "[releaseBtc] Releasing {} RBTC from RSK address {} in tx {}", + pegoutValue, + senderAddress, + rskTx.getHash() + ); + + // Peg-out from a smart contract not allowed since it's not possible to derive a BTC address from it if (BridgeUtils.isContractTx(rskTx)) { - logger.trace("Contract {} tried to release funds. Release is just allowed from standard accounts.", rskTx); + logger.trace( + "[releaseBtc] Contract {} tried to release funds. Release is just allowed from EOA", + senderAddress + ); if (activations.isActive(ConsensusRule.RSKIP185)) { - emitRejectEvent(value, senderAddress.toHexString(), RejectedPegoutReason.CALLER_CONTRACT); + emitRejectEvent(pegoutValue, senderAddress, RejectedPegoutReason.CALLER_CONTRACT); return; } else { - throw new Program.OutOfGasException("Contract calling releaseBTC"); + String message = "Contract calling releaseBTC"; + logger.debug("[releaseBtc] {}", message); + throw new Program.OutOfGasException(message); } } Context.propagate(btcContext); NetworkParameters btcParams = bridgeConstants.getBtcParams(); Address btcDestinationAddress = BridgeUtils.recoverBtcAddressFromEthTransaction(rskTx, btcParams); + logger.debug("[releaseBtc] BTC destination address: {}", btcDestinationAddress); - requestRelease(btcDestinationAddress, value, rskTx); + requestRelease(btcDestinationAddress, pegoutValue, rskTx); } private void refundAndEmitRejectEvent(Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { - String senderAddressStr = senderAddress.toHexString(); - logger.trace("Executing a refund of {} to {}. Reason: {}", value, senderAddressStr, reason); + logger.trace( + "[refundAndEmitRejectEvent] Executing a refund of {} to {}. Reason: {}", + value, + senderAddress, + reason + ); rskRepository.transfer( - PrecompiledContracts.BRIDGE_ADDR, - senderAddress, - co.rsk.core.Coin.fromBitcoin(value) + PrecompiledContracts.BRIDGE_ADDR, + senderAddress, + co.rsk.core.Coin.fromBitcoin(value) ); - emitRejectEvent(value, senderAddressStr, reason); + emitRejectEvent(value, senderAddress, reason); } - private void emitRejectEvent(Coin value, String senderAddressStr, RejectedPegoutReason reason) { - eventLogger.logReleaseBtcRequestRejected(senderAddressStr, value, reason); + private void emitRejectEvent(Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { + eventLogger.logReleaseBtcRequestRejected(senderAddress.toHexString(), value, reason); } /** @@ -915,7 +932,7 @@ private void requestRelease(Address destinationAddress, Coin value, Transaction if (optionalRejectedPegoutReason.isPresent()) { logger.warn( - "releaseBtc ignored. To {}. Tx {}. Value {}. Reason: {}", + "[requestRelease] releaseBtc ignored. To {}. Tx {}. Value {}. Reason: {}", destinationAddress, rskTx, value, @@ -938,7 +955,7 @@ private void requestRelease(Address destinationAddress, Coin value, Transaction if (activations.isActive(ConsensusRule.RSKIP185)) { eventLogger.logReleaseBtcRequestReceived(rskTx.getSender(signatureCache).toHexString(), destinationAddress, value); } - logger.info("releaseBtc successful to {}. Tx {}. Value {}.", destinationAddress, rskTx, value); + logger.info("[requestRelease] releaseBtc successful to {}. Tx {}. Value {}.", destinationAddress, rskTx, value); } } From c5b7946649944c45b9d734c47b0fe2dca638da04 Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 31 Jan 2024 09:28:12 -0300 Subject: [PATCH 113/137] Update comment in BridgeUtils::isContractTx --- rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 99bcbcdaa68..e916f10933d 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeUtils.java @@ -421,7 +421,7 @@ public static boolean isFreeBridgeTx(Transaction rskTx, Constants constants, Act * @return */ public static boolean isContractTx(Transaction rskTx) { - // TODO: this should be refactored to provide a more robust way of checking the transaction origin + // Calls between contracts are done through internal transactions return rskTx.getClass() == org.ethereum.vm.program.InternalTransaction.class; } From da2864d7a381add9d397a59cdbbbc2d8b827ed31 Mon Sep 17 00:00:00 2001 From: fmacleal Date: Tue, 30 Jan 2024 00:08:53 +0100 Subject: [PATCH 114/137] Fix the Web3InformationRetriever With the current logic implementation, the hash is working to retrieve the block. We are verifying if the identifier and if it's a valid hash, we get the block by hash, otherwise we get trying by the blockNumber. --- .../co/rsk/rpc/Web3InformationRetriever.java | 36 ++++++++++++++----- .../rsk/rpc/Web3InformationRetrieverTest.java | 13 +++++++ .../java/org/ethereum/rpc/Web3ImplTest.java | 34 ++++++++++++++++-- 3 files changed, 72 insertions(+), 11 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/Web3InformationRetriever.java b/rskj-core/src/main/java/co/rsk/rpc/Web3InformationRetriever.java index e77f97f1591..328b8be17c1 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/Web3InformationRetriever.java +++ b/rskj-core/src/main/java/co/rsk/rpc/Web3InformationRetriever.java @@ -21,6 +21,7 @@ import co.rsk.core.bc.AccountInformationProvider; import co.rsk.db.RepositoryLocator; import co.rsk.util.HexUtils; +import org.bouncycastle.util.encoders.DecoderException; import org.ethereum.core.Block; import org.ethereum.core.Blockchain; import org.ethereum.core.Transaction; @@ -30,6 +31,7 @@ import java.util.List; import java.util.Optional; +import static co.rsk.crypto.Keccak256.HASH_LEN; import static org.ethereum.rpc.exception.RskJsonRpcRequestException.blockNotFound; import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError; @@ -70,14 +72,22 @@ public Web3InformationRetriever(TransactionPool transactionPool, */ public Optional getBlock(String identifier) { Block block; - if (PENDING.equals(identifier)) { - block = executionBlockRetriever.retrieveExecutionBlock(identifier).getBlock(); - } else if (LATEST.equals(identifier)) { - block = blockchain.getBestBlock(); - } else if (EARLIEST.equals(identifier)) { - block = blockchain.getBlockByNumber(0); - } else { - block = this.blockchain.getBlockByNumber(getBlockNumber(identifier)); + + switch (identifier) { + case PENDING: + block = executionBlockRetriever.retrieveExecutionBlock(identifier).getBlock(); + break; + case LATEST: + block = blockchain.getBestBlock(); + break; + case EARLIEST: + block = blockchain.getBlockByNumber(0); + break; + default: + byte[] hash = getBlockHash(identifier); + block = hash.length == HASH_LEN ? + blockchain.getBlockByHash(hash) + : blockchain.getBlockByNumber(getBlockNumber(identifier)); } return Optional.ofNullable(block); @@ -134,4 +144,14 @@ private long getBlockNumber(String identifier) { } return blockNumber; } + + private byte[] getBlockHash(String identifier) { + byte[] blockHash; + try { + blockHash = HexUtils.stringHexToByteArray(identifier); + } catch (DecoderException e) { + throw invalidParamError(String.format("invalid blockhash %s", identifier)); + } + return blockHash; + } } diff --git a/rskj-core/src/test/java/co/rsk/rpc/Web3InformationRetrieverTest.java b/rskj-core/src/test/java/co/rsk/rpc/Web3InformationRetrieverTest.java index af1df1192ca..b4ac8badf70 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/Web3InformationRetrieverTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/Web3InformationRetrieverTest.java @@ -6,6 +6,7 @@ import co.rsk.crypto.Keccak256; import co.rsk.db.RepositoryLocator; import co.rsk.db.RepositorySnapshot; +import co.rsk.util.HexUtils; import org.ethereum.TestUtils; import org.ethereum.core.*; import org.ethereum.rpc.exception.RskJsonRpcRequestException; @@ -90,6 +91,18 @@ void getBlock_number() { assertEquals(secondBlock, result.get()); } + @Test + void getBlock_hash() { + String hash = "0x0000000000000000000000000000000000000000000000000000000000000002"; + byte[] bytesHash = HexUtils.stringHexToByteArray(hash); + Block secondBlock = mock(Block.class); + when(blockchain.getBlockByHash(bytesHash)).thenReturn(secondBlock); + Optional result = target.getBlock(hash); + + assertTrue(result.isPresent()); + assertEquals(secondBlock, result.get()); + } + @Test void getBlock_notFound() { Optional result = target.getBlock("0x2"); diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index 1ac91726598..ecbf44231ec 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -383,6 +383,34 @@ void getStorageAtAccountAndBlockHash() { new BlockRefParam(blockRef))); } + @Test + //[ "0x
", "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" -> return storage at given address in genesis block + void getStorageAtAccountAndBlockHashWithSingleIdentifier() { + //given + final ChainParams chain = chainWithAccount10kBalance(false); + // when + String result = chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam( "0x" + chain.block.getPrintableHash())); + // then + assertEquals(NON_EXISTING_KEY_RESPONSE, result ); + } + + @Test + //[ "0x
", "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" -> return storage at given address in genesis block + void getStorageAtAccountAndBlockHashWithSingleIdentifier_whenItsAInvalidHash() { + //given + String invalidBlockIdentifier = "0x00011231234123"; + final ChainParams chain = chainWithAccount10kBalance(false); + //when-then + Exception ex = assertThrows(RskJsonRpcRequestException.class, () -> chain.web3.eth_getStorageAt( + new HexAddressParam(chain.accountAddress), + new HexNumberParam("0x0"), + new BlockRefParam( invalidBlockIdentifier))); + assertEquals("Block " + invalidBlockIdentifier + " not found", ex.getMessage()); + } + @Test //[ "0x
", { "blockHash": "0x" } -> raise block-not-found error void getStorageAtAccountAndNonExistentBlockHash() { @@ -810,7 +838,7 @@ void getTransactionReceiptNotInMainBlockchain() { txs.add(tx); Block genesis = world.getBlockChain().getBestBlock(); Block block1 = new BlockBuilder(world.getBlockChain(), world.getBridgeSupportFactory(), - world.getBlockStore()).trieStore(world.getTrieStore()).parent(genesis).difficulty(3l).transactions(txs).build(); + world.getBlockStore()).trieStore(world.getTrieStore()).parent(genesis).difficulty(3L).transactions(txs).build(); assertEquals(ImportResult.IMPORTED_BEST, world.getBlockChain().tryToConnect(block1)); Block block1b = new BlockBuilder(world.getBlockChain(), world.getBridgeSupportFactory(), world.getBlockStore()).trieStore(world.getTrieStore()).parent(genesis) @@ -1018,7 +1046,7 @@ void getTransactionCount() { Transaction tx = new TransactionBuilder().sender(acc1).receiver(acc2).value(BigInteger.valueOf(1000000)).build(); List txs = new ArrayList<>(); txs.add(tx); - Block block1 = createCanonicalBlock(world, txs); + createCanonicalBlock(world, txs); String accountAddress = ByteUtil.toHexString(acc1.getAddress().getBytes()); @@ -3108,7 +3136,7 @@ void transactionReceiptAndResultHasTypeField() { Transaction tx = new TransactionBuilder().sender(acc1).receiver(acc2).value(BigInteger.valueOf(1000000)).build(); List txs = new ArrayList<>(); txs.add(tx); - Block block1 = createCanonicalBlock(world, txs); + createCanonicalBlock(world, txs); String hashString = tx.getHash().toHexString(); TxHashParam txHashParam = new TxHashParam(hashString); From 6b364a7e16b16340c73c49288536f83476dd8909 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 8 Feb 2024 14:33:23 -0300 Subject: [PATCH 115/137] Replace RSKIP414 for RSKIP417 --- .../src/main/java/co/rsk/peg/Bridge.java | 6 +- .../blockchain/upgrades/ConsensusRule.java | 2 +- rskj-core/src/main/resources/reference.conf | 2 +- .../src/test/java/co/rsk/peg/BridgeTest.java | 116 +++++++++--------- .../upgrades/ActivationConfigsForTest.java | 4 +- 5 files changed, 65 insertions(+), 65 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index a34cc844038..b81e4380744 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -17,7 +17,7 @@ */ package co.rsk.peg; -import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP414; +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP417; import co.rsk.bitcoinj.core.*; import co.rsk.bitcoinj.script.Script; @@ -380,7 +380,7 @@ public byte[] execute(byte[] data) throws VMException { teardown(); byte[] voidReturnValue = new byte[]{}; - if (!activations.isActive(RSKIP414)) { + if (!activations.isActive(RSKIP417)) { voidReturnValue = null; } @@ -413,7 +413,7 @@ private void validateLocalCall(BridgeParsedData bridgeParsedData) throws BridgeI } private void validateCallMessageType(BridgeParsedData bridgeParsedData) throws BridgeIllegalArgumentException { - if (activations.isActive(RSKIP414) && + if (activations.isActive(RSKIP417) && !bridgeParsedData.bridgeMethod.acceptsThisTypeOfCall(this.msgType)) { String errorMessage = String.format( "Call type (%s) not accepted by %s. Returning without execution.", diff --git a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java index cef4b0bbcd2..9a9efecf657 100644 --- a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java +++ b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ConsensusRule.java @@ -91,8 +91,8 @@ public enum ConsensusRule { RSKIP398("rskip398"), RSKIP400("rskip400"), // From EIP-2028 calldata gas cost reduction RSKIP412("rskip412"), // From EIP-3198 BASEFEE opcode - RSKIP414("rskip414"), RSKIP415("rskip415"), + RSKIP417("rskip417"), ; private String configKey; diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 55257c50fee..90d70354b52 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -77,8 +77,8 @@ blockchain = { rskip398 = arrowhead600 rskip400 = arrowhead600 rskip412 = arrowhead600 - rskip414 = arrowhead600 rskip415 = arrowhead600 + rskip417 = arrowhead600 } } gc = { diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 3b22d4801b7..d754ef7b7a8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -1114,7 +1114,7 @@ void addFederatorPublicKeyMultikey(MessageCall.MsgType msgType, ActivationConfig byte[] data = function.encode(Hex.decode(publicKey), Hex.decode(publicKey), Hex.decode(publicKey)); if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1171,7 +1171,7 @@ void addOneOffLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig byte[] data = function.encode(addressBase58, maxTransferValue); if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1203,7 +1203,7 @@ void addUnlimitedLockWhitelistAddress(MessageCall.MsgType msgType, ActivationCon byte[] data = function.encode(addressBase58); if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1248,7 +1248,7 @@ void addSignatures(MessageCall.MsgType msgType, ActivationConfig activationConfi CallTransaction.Function function = BridgeMethods.ADD_SIGNATURE.getFunction(); byte[] data = function.encode(Hex.decode(pegnatoryPublicKey), derEncodedSigs, rskTxHash.getBytes()); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1276,7 +1276,7 @@ void commitFederation(MessageCall.MsgType msgType, ActivationConfig activationCo CallTransaction.Function function = BridgeMethods.COMMIT_FEDERATION.getFunction(); byte[] data = function.encode(commitTransactionHash.getBytes()); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1301,7 +1301,7 @@ void createFederation(MessageCall.MsgType msgType, ActivationConfig activationCo CallTransaction.Function function = BridgeMethods.CREATE_FEDERATION.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -1331,7 +1331,7 @@ void getBtcBlockchainBestChainHeight(MessageCall.MsgType msgType, ActivationConf CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_BEST_CHAIN_HEIGHT.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1359,7 +1359,7 @@ void getBtcBlockchainInitialBlockHeight(MessageCall.MsgType msgType, ActivationC CallTransaction.Function function = BridgeMethods.GET_BTC_BLOCKCHAIN_INITIAL_BLOCK_HEIGHT.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1418,7 +1418,7 @@ void getBtcBlockchainBlockHashAtDepth(MessageCall.MsgType msgType, ActivationCon byte[] data = function.encode(depth); if (activationConfig.isActive(ConsensusRule.RSKIP89, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1461,7 +1461,7 @@ void getBtcTransactionConfirmations(MessageCall.MsgType msgType, ActivationConfi ); if (activationConfig.isActive(ConsensusRule.RSKIP122, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1497,7 +1497,7 @@ void getBtcTxHashProcessedHeight(MessageCall.MsgType msgType, ActivationConfig a CallTransaction.Function function = BridgeMethods.GET_BTC_TX_HASH_PROCESSED_HEIGHT.getFunction(); byte[] data = function.encode(btcTxHash.toString()); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1526,7 +1526,7 @@ void getFederationAddress(MessageCall.MsgType msgType, ActivationConfig activati CallTransaction.Function function = BridgeMethods.GET_FEDERATION_ADDRESS.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1553,7 +1553,7 @@ void getFederationCreationBlockNumber(MessageCall.MsgType msgType, ActivationCon CallTransaction.Function function = BridgeMethods.GET_FEDERATION_CREATION_BLOCK_NUMBER.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1581,7 +1581,7 @@ void getFederationCreationTime(MessageCall.MsgType msgType, ActivationConfig act CallTransaction.Function function = BridgeMethods.GET_FEDERATION_CREATION_TIME.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1608,7 +1608,7 @@ void getFederationSize(MessageCall.MsgType msgType, ActivationConfig activationC CallTransaction.Function function = BridgeMethods.GET_FEDERATION_SIZE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1635,7 +1635,7 @@ void getFederationThreshold(MessageCall.MsgType msgType, ActivationConfig activa CallTransaction.Function function = BridgeMethods.GET_FEDERATION_THRESHOLD.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1692,7 +1692,7 @@ void getFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationConfig a byte[] data = function.encode(federatorIndex, keyType.getValue()); if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1728,7 +1728,7 @@ void getFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig) CallTransaction.Function function = BridgeMethods.GET_FEE_PER_KB.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1756,7 +1756,7 @@ void getLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig activ CallTransaction.Function function = BridgeMethods.GET_LOCK_WHITELIST_ADDRESS.getFunction(); byte[] data = function.encode(index); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1785,7 +1785,7 @@ void getLockWhitelistEntryByAddress(MessageCall.MsgType msgType, ActivationConfi byte[] data = function.encode(addressBase58); if (activationConfig.isActive(ConsensusRule.RSKIP87, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1816,7 +1816,7 @@ void getLockWhitelistSize(MessageCall.MsgType msgType, ActivationConfig activati CallTransaction.Function function = BridgeMethods.GET_LOCK_WHITELIST_SIZE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1850,7 +1850,7 @@ void getMinimumLockTxValue(MessageCall.MsgType msgType, ActivationConfig activat CallTransaction.Function function = BridgeMethods.GET_MINIMUM_LOCK_TX_VALUE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1877,7 +1877,7 @@ void getPendingFederationHash(MessageCall.MsgType msgType, ActivationConfig acti CallTransaction.Function function = BridgeMethods.GET_PENDING_FEDERATION_HASH.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1905,7 +1905,7 @@ void getPendingFederationSize(MessageCall.MsgType msgType, ActivationConfig acti CallTransaction.Function function = BridgeMethods.GET_PENDING_FEDERATION_SIZE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -1964,7 +1964,7 @@ void getPendingFederatorPublicKeyOfType(MessageCall.MsgType msgType, ActivationC byte[] data = function.encode(federatorIndex, keyType.getValue()); if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2001,7 +2001,7 @@ void getRetiringFederationAddress(MessageCall.MsgType msgType, ActivationConfig CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_ADDRESS.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2028,7 +2028,7 @@ void getRetiringFederationCreationBlockNumber(MessageCall.MsgType msgType, Activ CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_CREATION_BLOCK_NUMBER.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2056,7 +2056,7 @@ void getRetiringFederationCreationTime(MessageCall.MsgType msgType, ActivationCo CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_CREATION_TIME.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2083,7 +2083,7 @@ void getRetiringFederationSize(MessageCall.MsgType msgType, ActivationConfig act CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_SIZE.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2110,7 +2110,7 @@ void getRetiringFederationThreshold(MessageCall.MsgType msgType, ActivationConfi CallTransaction.Function function = BridgeMethods.GET_RETIRING_FEDERATION_THRESHOLD.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2168,7 +2168,7 @@ void getRetiringFederatorPublicKeyOfType(MessageCall.MsgType msgType, Activation byte[] data = function.encode(federatorIndex, keyType.getValue()); if (activationConfig.isActive(ConsensusRule.RSKIP123, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2202,7 +2202,7 @@ void getStateForBtcReleaseClient(MessageCall.MsgType msgType, ActivationConfig a CallTransaction.Function function = BridgeMethods.GET_STATE_FOR_BTC_RELEASE_CLIENT.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2229,7 +2229,7 @@ void getStateForDebugging(MessageCall.MsgType msgType, ActivationConfig activati CallTransaction.Function function = BridgeMethods.GET_STATE_FOR_DEBUGGING.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2260,7 +2260,7 @@ void getLockingCap(MessageCall.MsgType msgType, ActivationConfig activationConfi byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2293,7 +2293,7 @@ void getActivePowpegRedeemScript(MessageCall.MsgType msgType, ActivationConfig a byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP293, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2321,7 +2321,7 @@ void getActiveFederationCreationBlockHeight(MessageCall.MsgType msgType, Activat byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP186, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2354,7 +2354,7 @@ void increaseLockingCap(MessageCall.MsgType msgType, ActivationConfig activation byte[] data = function.encode(newLockingCap); if (activationConfig.isActive(ConsensusRule.RSKIP134, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2388,7 +2388,7 @@ void isBtcTxHashAlreadyProcessed(MessageCall.MsgType msgType, ActivationConfig a CallTransaction.Function function = BridgeMethods.IS_BTC_TX_HASH_ALREADY_PROCESSED.getFunction(); byte[] data = function.encode(btcTxHash.toString()); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2430,7 +2430,7 @@ void receiveHeaders(MessageCall.MsgType msgType, ActivationConfig activationConf CallTransaction.Function function = BridgeMethods.RECEIVE_HEADERS.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2469,7 +2469,7 @@ void receiveHeader(MessageCall.MsgType msgType, ActivationConfig activationConfi byte[] data = function.encode(serializedBlockHeader); if (activationConfig.isActive(ConsensusRule.RSKIP200, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2515,7 +2515,7 @@ void registerBtcTransaction(MessageCall.MsgType msgType, ActivationConfig activa byte[] pmtSerialized = new byte[]{2}; byte[] data = function.encode(btcTxSerialized, height, pmtSerialized); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2544,7 +2544,7 @@ void releaseBtc(MessageCall.MsgType msgType, ActivationConfig activationConfig) CallTransaction.Function function = BridgeMethods.RELEASE_BTC.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2570,7 +2570,7 @@ void removeLockWhitelistAddress(MessageCall.MsgType msgType, ActivationConfig ac String addressBase58 = "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"; byte[] data = function.encode(addressBase58); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2593,7 +2593,7 @@ void rollbackFederation(MessageCall.MsgType msgType, ActivationConfig activation CallTransaction.Function function = BridgeMethods.ROLLBACK_FEDERATION.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2617,7 +2617,7 @@ void setLockWhiteListDisableBlockDelay(MessageCall.MsgType msgType, ActivationCo BigInteger disableBlockDelay = BigInteger.valueOf(100); byte[] data = function.encode(disableBlockDelay); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2653,7 +2653,7 @@ void updateCollections(MessageCall.MsgType msgType, ActivationConfig activationC CallTransaction.Function function = BridgeMethods.UPDATE_COLLECTIONS.getFunction(); byte[] data = function.encode(); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2679,7 +2679,7 @@ void voteFeePerKb(MessageCall.MsgType msgType, ActivationConfig activationConfig long feePerKB = 10_000; byte[] data = function.encode(feePerKB); - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2715,7 +2715,7 @@ void registerBtcCoinbaseTransaction(MessageCall.MsgType msgType, ActivationConfi ); if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2751,7 +2751,7 @@ void hasBtcBlockCoinbaseTransactionInformation(MessageCall.MsgType msgType, Acti byte[] data = function.encode(blockHash.getBytes()); if (activationConfig.isActive(ConsensusRule.RSKIP143, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATICCALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2797,7 +2797,7 @@ void registerFastBridgeBtcTransaction(MessageCall.MsgType msgType, ActivationCon ); if (activationConfig.isActive(ConsensusRule.RSKIP176, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !msgType.equals(MessageCall.MsgType.CALL)) { // Post arrowhead should fail for any msg type != CALL assertThrows(VMException.class, () -> bridge.execute(data)); } else { @@ -2835,7 +2835,7 @@ void getBtcBlockchainBestBlockHeader(MessageCall.MsgType msgType, ActivationConf byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2866,7 +2866,7 @@ void getBtcBlockchainBlockHeaderByHash(MessageCall.MsgType msgType, ActivationCo byte[] data = function.encode(hashBytes); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2897,7 +2897,7 @@ void getBtcBlockchainBlockHeaderByHeight(MessageCall.MsgType msgType, Activation byte[] data = function.encode(height); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2928,7 +2928,7 @@ void getBtcBlockchainParentBlockHeaderByHash(MessageCall.MsgType msgType, Activa byte[] data = function.encode(hashBytes); if (activationConfig.isActive(ConsensusRule.RSKIP220, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2957,7 +2957,7 @@ void getNextPegoutCreationBlockNumber(MessageCall.MsgType msgType, ActivationCon byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -2986,7 +2986,7 @@ void getQueuedPegoutsCount(MessageCall.MsgType msgType, ActivationConfig activat byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -3017,7 +3017,7 @@ void getEstimatedFeesForNextPegoutEvent(MessageCall.MsgType msgType, ActivationC byte[] data = function.encode(); if (activationConfig.isActive(ConsensusRule.RSKIP271, 0)) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0) && + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0) && !(msgType.equals(MessageCall.MsgType.CALL) || msgType.equals(MessageCall.MsgType.STATICCALL))) { // Post arrowhead should fail for any msg type != CALL or STATIC CALL assertThrows(VMException.class, () -> bridge.execute(data)); @@ -3053,7 +3053,7 @@ private static Stream msgTypesAndActivations() { } private void assertVoidMethodResult(ActivationConfig activationConfig, byte[] result) { - if (activationConfig.isActive(ConsensusRule.RSKIP414, 0)) { + if (activationConfig.isActive(ConsensusRule.RSKIP417, 0)) { assertArrayEquals(EMPTY_BYTE_ARRAY, result); } else { assertNull(result); diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java index 882ae05b71a..8318e2ff6d0 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigsForTest.java @@ -184,8 +184,8 @@ private static List getArrowhead600Rskips() { ConsensusRule.RSKIP379, ConsensusRule.RSKIP398, ConsensusRule.RSKIP400, - ConsensusRule.RSKIP414, - ConsensusRule.RSKIP415 + ConsensusRule.RSKIP415, + ConsensusRule.RSKIP417 )); return rskips; From fc602f5be876da50c18f0529c26cba25db0eb2c0 Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 9 Feb 2024 10:53:32 -0300 Subject: [PATCH 116/137] Return Optional.empty instead of null in executeBridgeMethod before RSKIP88 --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index b81e4380744..c8ad92e4ad6 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -435,14 +435,18 @@ private Optional executeBridgeMethod(BridgeParsedData bridgeParsedData) throw } catch (BridgeIllegalArgumentException ex) { String errorMessage = String.format("Error executing: %s", bridgeParsedData.bridgeMethod); logger.warn(errorMessage, ex); - if (!activations.isActive(ConsensusRule.RSKIP88)) { - return null; + if (shouldReturnNullInsteadOfBridgeException()) { + return Optional.empty(); } throw new BridgeIllegalArgumentException(errorMessage); } } + private boolean shouldReturnNullInsteadOfBridgeException() { + return !activations.isActive(ConsensusRule.RSKIP88); + } + private void teardown() throws IOException { bridgeSupport.save(); } From 4be3f98a176129ac02aeb346da8e6e995e4cad0e Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 9 Feb 2024 14:18:03 -0300 Subject: [PATCH 117/137] Fix execution handling for bridge void methods --- .../src/main/java/co/rsk/peg/Bridge.java | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index c8ad92e4ad6..a0ae391e045 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -376,14 +376,20 @@ public byte[] execute(byte[] data) throws VMException { } validateCall(bridgeParsedData); - Optional result = executeBridgeMethod(bridgeParsedData); - teardown(); - - byte[] voidReturnValue = new byte[]{}; - if (!activations.isActive(RSKIP417)) { - voidReturnValue = null; + Optional result; + try { + result = executeBridgeMethod(bridgeParsedData); + } catch (BridgeIllegalArgumentException ex) { + String errorMessage = String.format("Error executing: %s", bridgeParsedData.bridgeMethod); + logger.warn(errorMessage, ex); + if (shouldReturnNullInsteadOfException()) { + return null; + } + throw new BridgeIllegalArgumentException(errorMessage); } + teardown(); + byte[] voidReturnValue = calculateVoidReturnValue(); return result.map(bridgeParsedData.bridgeMethod.getFunction()::encodeOutputs).orElse(voidReturnValue); } catch (Exception ex) { logger.error(ex.getMessage(), ex); @@ -433,20 +439,25 @@ private Optional executeBridgeMethod(BridgeParsedData bridgeParsedData) throw BridgeMethodExecutor executor = bridgeParsedData.bridgeMethod.getExecutor(); return executor.execute(this, bridgeParsedData.args); } catch (BridgeIllegalArgumentException ex) { - String errorMessage = String.format("Error executing: %s", bridgeParsedData.bridgeMethod); - logger.warn(errorMessage, ex); - if (shouldReturnNullInsteadOfBridgeException()) { - return Optional.empty(); - } - - throw new BridgeIllegalArgumentException(errorMessage); + throw new BridgeIllegalArgumentException(); } } - private boolean shouldReturnNullInsteadOfBridgeException() { + private boolean shouldReturnNullInsteadOfException() { return !activations.isActive(ConsensusRule.RSKIP88); } + private byte[] calculateVoidReturnValue() { + if (shouldReturnNullOnVoidMethods()) { + return null; + } + return new byte[]{}; + } + + private boolean shouldReturnNullOnVoidMethods() { + return !activations.isActive(RSKIP417); + } + private void teardown() throws IOException { bridgeSupport.save(); } From 58e0bd1980b3fe51d81b8b471176cd83d9675c12 Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 9 Feb 2024 14:37:42 -0300 Subject: [PATCH 118/137] Refactor thrown bridge exception in execute bridge method --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index a0ae391e045..06cc2167efa 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -380,13 +380,12 @@ public byte[] execute(byte[] data) throws VMException { try { result = executeBridgeMethod(bridgeParsedData); } catch (BridgeIllegalArgumentException ex) { - String errorMessage = String.format("Error executing: %s", bridgeParsedData.bridgeMethod); - logger.warn(errorMessage, ex); if (shouldReturnNullInsteadOfException()) { return null; } - throw new BridgeIllegalArgumentException(errorMessage); + throw new BridgeIllegalArgumentException(ex.getMessage()); } + teardown(); byte[] voidReturnValue = calculateVoidReturnValue(); @@ -439,7 +438,10 @@ private Optional executeBridgeMethod(BridgeParsedData bridgeParsedData) throw BridgeMethodExecutor executor = bridgeParsedData.bridgeMethod.getExecutor(); return executor.execute(this, bridgeParsedData.args); } catch (BridgeIllegalArgumentException ex) { - throw new BridgeIllegalArgumentException(); + String errorMessage = String.format("Error executing: %s", bridgeParsedData.bridgeMethod); + logger.warn(errorMessage, ex); + + throw new BridgeIllegalArgumentException(errorMessage); } } From 723aa4ad465c694b43d97c6bf177c6962b301399 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 9 Feb 2024 15:16:10 -0300 Subject: [PATCH 119/137] Rethrow the same exception --- rskj-core/src/main/java/co/rsk/peg/Bridge.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/Bridge.java b/rskj-core/src/main/java/co/rsk/peg/Bridge.java index 06cc2167efa..e7d1049e1c6 100644 --- a/rskj-core/src/main/java/co/rsk/peg/Bridge.java +++ b/rskj-core/src/main/java/co/rsk/peg/Bridge.java @@ -383,9 +383,8 @@ public byte[] execute(byte[] data) throws VMException { if (shouldReturnNullInsteadOfException()) { return null; } - throw new BridgeIllegalArgumentException(ex.getMessage()); + throw ex; } - teardown(); byte[] voidReturnValue = calculateVoidReturnValue(); From 30fba2335e3f785aa85bd36ce8ed287ac2b0fc41 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 9 Feb 2024 15:27:34 -0300 Subject: [PATCH 120/137] Add RSKIP417 to ActivationConfigTest --- .../config/blockchain/upgrades/ActivationConfig.java | 4 ++-- .../config/blockchain/upgrades/ActivationConfigTest.java | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ActivationConfig.java b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ActivationConfig.java index d5af5f544ae..a0641854f13 100644 --- a/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ActivationConfig.java +++ b/rskj-core/src/main/java/org/ethereum/config/blockchain/upgrades/ActivationConfig.java @@ -36,8 +36,8 @@ public ActivationConfig(Map activationHeights) { List missing = new ArrayList<>(Arrays.asList(ConsensusRule.values())); missing.removeAll(activationHeights.keySet()); throw new IllegalArgumentException(String.format( - "The configuration must contain all consensus rule values but is missing [%s]", - missing.stream().map(ConsensusRule::getConfigKey).collect(Collectors.joining(", ")) + "The configuration must contain all consensus rule values but is missing [%s]", + missing.stream().map(ConsensusRule::getConfigKey).collect(Collectors.joining(", ")) )); } diff --git a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java index 694fac377bf..68951cfbf64 100644 --- a/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java +++ b/rskj-core/src/test/java/org/ethereum/config/blockchain/upgrades/ActivationConfigTest.java @@ -118,6 +118,7 @@ class ActivationConfigTest { " rskip400: arrowhead600", " rskip412: arrowhead600", " rskip415: arrowhead600", + " rskip417: arrowhead600", "}" )); @@ -133,8 +134,8 @@ void readBaseConfig() { @Test void readWithTwoUpgradesInOrchid060() { ActivationConfig config = ActivationConfig.read(BASE_CONFIG - .withValue("hardforkActivationHeights.orchid060", ConfigValueFactory.fromAnyRef(200)) - .withValue("consensusRules.rskip98", ConfigValueFactory.fromAnyRef("orchid060")) + .withValue("hardforkActivationHeights.orchid060", ConfigValueFactory.fromAnyRef(200)) + .withValue("consensusRules.rskip98", ConfigValueFactory.fromAnyRef("orchid060")) ); for (ConsensusRule value : ConsensusRule.values()) { @@ -148,8 +149,8 @@ void readWithTwoUpgradesInOrchid060() { @Test void readWithOneHardcodedActivationNumber() { - ActivationConfig config = ActivationConfig.read(BASE_CONFIG - .withValue("consensusRules.rskip85", ConfigValueFactory.fromAnyRef(200)) + ActivationConfig config = ActivationConfig.read( + BASE_CONFIG.withValue("consensusRules.rskip85", ConfigValueFactory.fromAnyRef(200)) ); for (ConsensusRule value : ConsensusRule.values()) { From fc4e43af7ad1d63dc80c9b47b97c379c7b3c6b69 Mon Sep 17 00:00:00 2001 From: julia zack Date: Fri, 9 Feb 2024 15:51:29 -0300 Subject: [PATCH 121/137] Add rskip417 to expected.conf file --- rskj-core/src/main/resources/expected.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index 6647e73e22e..9d12ab51874 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -91,6 +91,7 @@ blockchain = { rskip400 = rskip412 = rskip415 = + rskip417 = } } gc = { From f04ca301ba5056f1e02f8c4f7cdef3118ca59312 Mon Sep 17 00:00:00 2001 From: nathanieliov Date: Wed, 28 Feb 2024 21:34:18 -0400 Subject: [PATCH 122/137] - Set estimatedPegoutTxIndexBtcActivationHeight final value. - Set pegoutTxIndexGracePeriodInBtcBlocks final value. --- .../src/main/java/co/rsk/config/BridgeMainNetConstants.java | 2 +- .../src/main/java/co/rsk/config/BridgeTestNetConstants.java | 4 ++-- .../src/test/java/co/rsk/config/BridgeConstantsTest.java | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java index fbc7e22470e..63152d92781 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeMainNetConstants.java @@ -151,7 +151,7 @@ public class BridgeMainNetConstants extends BridgeConstants { numberOfBlocksBetweenPegouts = 360; // 3 hours of RSK blocks (considering 1 block every 30 seconds) - btcHeightWhenPegoutTxIndexActivates = 100; // TODO: TBD and change current mock value. This is an estimation of the btc block number once RSKIP379 is activated. + btcHeightWhenPegoutTxIndexActivates = 837_589; // Estimated date Wed, 03 Apr 2024 15:00:00 GMT. 832,430 was the block number at time of calculation pegoutTxIndexGracePeriodInBtcBlocks = 4_320; // 30 days in BTC blocks (considering 1 block every 10 minutes) } diff --git a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java index 21e475843b3..fbfaa8029a4 100644 --- a/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/config/BridgeTestNetConstants.java @@ -169,8 +169,8 @@ public class BridgeTestNetConstants extends BridgeConstants { numberOfBlocksBetweenPegouts = 360; // 3 hours of RSK blocks (considering 1 block every 30 seconds) - btcHeightWhenPegoutTxIndexActivates = 150; // TODO: TBD and change current mock value. This is an estimation of the btc block number once RSKIP379 is activated. - pegoutTxIndexGracePeriodInBtcBlocks = 4_320; // 30 days in BTC blocks (considering 1 block every 10 minutes) + btcHeightWhenPegoutTxIndexActivates = 2_589_553; // Estimated date Wed, 20 Mar 2024 15:00:00 GMT. 2,579,823 was the block number at time of calculation + pegoutTxIndexGracePeriodInBtcBlocks = 1_440; // 10 days in BTC blocks (considering 1 block every 10 minutes) } public static BridgeTestNetConstants getInstance() { diff --git a/rskj-core/src/test/java/co/rsk/config/BridgeConstantsTest.java b/rskj-core/src/test/java/co/rsk/config/BridgeConstantsTest.java index a31c3d9e948..0a47296d80c 100644 --- a/rskj-core/src/test/java/co/rsk/config/BridgeConstantsTest.java +++ b/rskj-core/src/test/java/co/rsk/config/BridgeConstantsTest.java @@ -124,8 +124,8 @@ void test_getMinimumPeginTxValue(BridgeConstants bridgeConstants, boolean isRSKI private static Stream getBtcHeightWhenPegoutTxIndexActivatesArgProvider() { return Stream.of( - Arguments.of(BridgeMainNetConstants.getInstance(), 100), - Arguments.of(BridgeTestNetConstants.getInstance(), 150), + Arguments.of(BridgeMainNetConstants.getInstance(), 837589), + Arguments.of(BridgeTestNetConstants.getInstance(), 2589553), Arguments.of(BridgeRegTestConstants.getInstance(), 250) ); } @@ -143,7 +143,7 @@ void test_getBtcHeightWhenPegoutTxIndexActivates(BridgeConstants bridgeConstants private static Stream getPegoutTxIndexGracePeriodInBtcBlocksArgProvider() { return Stream.of( Arguments.of(BridgeMainNetConstants.getInstance(), 4_320), - Arguments.of(BridgeTestNetConstants.getInstance(), 4_320), + Arguments.of(BridgeTestNetConstants.getInstance(), 1_440), Arguments.of(BridgeRegTestConstants.getInstance(), 100) ); } From bb94cda441e4525018c9515be47142357b1fb1f2 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 4 Mar 2024 17:48:24 -0300 Subject: [PATCH 123/137] Set Arrowhead activation heights for testnet and mainnet --- rskj-core/src/main/resources/config/main.conf | 2 +- rskj-core/src/main/resources/config/testnet.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rskj-core/src/main/resources/config/main.conf b/rskj-core/src/main/resources/config/main.conf index 6714121446c..d502c49382a 100644 --- a/rskj-core/src/main/resources/config/main.conf +++ b/rskj-core/src/main/resources/config/main.conf @@ -12,7 +12,7 @@ blockchain.config { hop400 = 4598500, hop401 = 4976300, fingerroot500 = 5468000, - arrowhead600 = -1 + arrowhead600 = 6223700 } } diff --git a/rskj-core/src/main/resources/config/testnet.conf b/rskj-core/src/main/resources/config/testnet.conf index fa1956af5ee..b07f13706f0 100644 --- a/rskj-core/src/main/resources/config/testnet.conf +++ b/rskj-core/src/main/resources/config/testnet.conf @@ -12,7 +12,7 @@ blockchain.config { hop400 = 3103000, hop401 = 3362200, fingerroot500 = 4015800, - arrowhead600 = -1 + arrowhead600 = 4927100 }, consensusRules = { rskip97 = -1, # disable orchid difficulty drop From 9e1655537149c4356a6b57929e953de5b0ffaf9e Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 4 Mar 2024 17:49:12 -0300 Subject: [PATCH 124/137] Set version modifier to ARROWHEAD --- rskj-core/src/main/resources/version.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rskj-core/src/main/resources/version.properties b/rskj-core/src/main/resources/version.properties index f093fc930f4..02227c7d802 100644 --- a/rskj-core/src/main/resources/version.properties +++ b/rskj-core/src/main/resources/version.properties @@ -1,2 +1,2 @@ versionNumber='6.0.0' -modifier="RC" +modifier="ARROWHEAD" From ad4451b0b83c78c2302a5f4302b74a7574103232 Mon Sep 17 00:00:00 2001 From: Angel Soto Date: Fri, 15 Dec 2023 19:42:21 +0100 Subject: [PATCH 125/137] Minor PR updates, update config path for this feature Updating from weighted average to weighted percentile method and naming updates Minor improvements related with PR comments Adding GasWeighted calculator and extracted legacy calculation to be able to choose which one could be used. --- .../src/main/java/co/rsk/RskContext.java | 4 +- .../co/rsk/config/RskSystemProperties.java | 15 ++ .../ethereum/listener/GasPriceCalculator.java | 51 +++++ .../ethereum/listener/GasPriceTracker.java | 82 +++---- .../PercentileGasPriceCalculator.java | 78 +++++++ .../listener/WeightedPercentileCalc.java | 50 +++++ .../WeightedPercentileGasPriceCalculator.java | 141 ++++++++++++ rskj-core/src/main/resources/expected.conf | 1 + rskj-core/src/main/resources/reference.conf | 4 +- .../test/java/co/rsk/NodeRunnerSmokeTest.java | 2 +- .../listener/GasPriceTrackerTest.java | 16 +- .../listener/WeightedPercentileCalcTest.java | 76 +++++++ ...ghtedPercentileGasPriceCalculatorTest.java | 204 ++++++++++++++++++ 13 files changed, 679 insertions(+), 45 deletions(-) create mode 100644 rskj-core/src/main/java/org/ethereum/listener/GasPriceCalculator.java create mode 100644 rskj-core/src/main/java/org/ethereum/listener/PercentileGasPriceCalculator.java create mode 100644 rskj-core/src/main/java/org/ethereum/listener/WeightedPercentileCalc.java create mode 100644 rskj-core/src/main/java/org/ethereum/listener/WeightedPercentileGasPriceCalculator.java create mode 100644 rskj-core/src/test/java/org/ethereum/listener/WeightedPercentileCalcTest.java create mode 100644 rskj-core/src/test/java/org/ethereum/listener/WeightedPercentileGasPriceCalculatorTest.java diff --git a/rskj-core/src/main/java/co/rsk/RskContext.java b/rskj-core/src/main/java/co/rsk/RskContext.java index f9ced02420c..8a80eec9deb 100644 --- a/rskj-core/src/main/java/co/rsk/RskContext.java +++ b/rskj-core/src/main/java/co/rsk/RskContext.java @@ -105,6 +105,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.facade.EthereumImpl; import org.ethereum.listener.CompositeEthereumListener; +import org.ethereum.listener.GasPriceCalculator; import org.ethereum.listener.GasPriceTracker; import org.ethereum.net.EthereumChannelInitializerFactory; import org.ethereum.net.NodeManager; @@ -558,7 +559,8 @@ public GasPriceTracker getGasPriceTracker() { double gasPriceMultiplier = getRskSystemProperties().gasPriceMultiplier(); if (this.gasPriceTracker == null) { - this.gasPriceTracker = GasPriceTracker.create(getBlockStore(), gasPriceMultiplier); + GasPriceCalculator.GasCalculatorType calculatorType = getRskSystemProperties().getGasCalculatorType(); + this.gasPriceTracker = GasPriceTracker.create(getBlockStore(), gasPriceMultiplier, calculatorType); } return this.gasPriceTracker; } diff --git a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java index 57ee131baa2..c1ee1116750 100644 --- a/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java +++ b/rskj-core/src/main/java/co/rsk/config/RskSystemProperties.java @@ -30,6 +30,7 @@ import org.ethereum.core.Account; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; +import org.ethereum.listener.GasPriceCalculator; import javax.annotation.Nullable; import java.nio.charset.StandardCharsets; @@ -58,6 +59,8 @@ public class RskSystemProperties extends SystemProperties { private static final String RPC_MODULES_PATH = "rpc.modules"; private static final String RPC_ETH_GET_LOGS_MAX_BLOCKS_TO_QUERY = "rpc.logs.maxBlocksToQuery"; private static final String RPC_ETH_GET_LOGS_MAX_LOGS_TO_RETURN = "rpc.logs.maxLogsToReturn"; + public static final String TX_GAS_PRICE_CALCULATOR_TYPE = "transaction.gasPriceCalculatorType"; + private static final String RPC_GAS_PRICE_MULTIPLIER_CONFIG = "rpc.gasPriceMultiplier"; private static final String DISCOVERY_BUCKET_SIZE = "peer.discovery.bucketSize"; @@ -506,6 +509,18 @@ public double getTopBest() { return value; } + public GasPriceCalculator.GasCalculatorType getGasCalculatorType() { + String value = configFromFiles.getString(TX_GAS_PRICE_CALCULATOR_TYPE); + if (value == null || value.isEmpty()) { + return GasPriceCalculator.GasCalculatorType.PLAIN_PERCENTILE; + } + GasPriceCalculator.GasCalculatorType gasCalculatorType = GasPriceCalculator.GasCalculatorType.fromString(value); + if(gasCalculatorType == null) { + throw new RskConfigurationException("Invalid gasPriceCalculatorType: " + value); + } + return gasCalculatorType; + } + private void fetchMethodTimeout(Config configElement, Map methodTimeoutMap) { configElement.getObject("methods.timeout") .unwrapped() diff --git a/rskj-core/src/main/java/org/ethereum/listener/GasPriceCalculator.java b/rskj-core/src/main/java/org/ethereum/listener/GasPriceCalculator.java new file mode 100644 index 00000000000..a8be9510a34 --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/listener/GasPriceCalculator.java @@ -0,0 +1,51 @@ +/* + * This file is part of RskJ + * Copyright (C) 2024 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.listener; + +import co.rsk.core.Coin; +import org.ethereum.core.Block; +import org.ethereum.core.TransactionReceipt; + +import java.util.List; +import java.util.Optional; + +public interface GasPriceCalculator { + public enum GasCalculatorType { + PLAIN_PERCENTILE, + WEIGHTED_PERCENTILE; + + public static GasCalculatorType fromString(String type) { + if (type == null) { + return null; + } + switch (type.toLowerCase()) { + case "weighted_percentile": + return WEIGHTED_PERCENTILE; + case "plain_percentile": + return PLAIN_PERCENTILE; + default: + return null; + } + } + } + + Optional getGasPrice(); + void onBlock(Block block, List receipts); + + GasCalculatorType getType(); +} diff --git a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java index d9a29d489c4..1d19ba277fb 100644 --- a/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java +++ b/rskj-core/src/main/java/org/ethereum/listener/GasPriceTracker.java @@ -23,7 +23,6 @@ import co.rsk.crypto.Keccak256; import co.rsk.remasc.RemascTransaction; import org.ethereum.core.Block; -import org.ethereum.core.Transaction; import org.ethereum.core.TransactionReceipt; import org.ethereum.db.BlockStore; import org.slf4j.Logger; @@ -35,10 +34,10 @@ /** * Calculates a 'reasonable' Gas price based on statistics of the latest transaction's Gas prices - * + *

* Normally the price returned should be sufficient to execute a transaction since ~25% of the latest * transactions were executed at this or lower price. - * + *

* Created by Anton Nashatyrev on 22.09.2015. */ public class GasPriceTracker extends EthereumListenerAdapter { @@ -53,8 +52,6 @@ public class GasPriceTracker extends EthereumListenerAdapter { private static final double DEFAULT_GAS_PRICE_MULTIPLIER = 1.1; - private final Coin[] txWindow = new Coin[TX_WINDOW_SIZE]; - private final Double[] blockWindow = new Double[BLOCK_WINDOW_SIZE]; private final AtomicReference bestBlockPriceRef = new AtomicReference<>(); @@ -62,27 +59,47 @@ public class GasPriceTracker extends EthereumListenerAdapter { private final double gasPriceMultiplier; private Coin defaultPrice = Coin.valueOf(20_000_000_000L); - private int txIdx = TX_WINDOW_SIZE - 1; - private int blockIdx = 0; - private Coin lastVal; + private final GasPriceCalculator gasPriceCalculator; - private GasPriceTracker(BlockStore blockStore, Double configMultiplier) { + private GasPriceTracker(BlockStore blockStore, GasPriceCalculator gasPriceCalculator, Double configMultiplier) { this.blockStore = blockStore; + this.gasPriceCalculator = gasPriceCalculator; this.gasPriceMultiplier = configMultiplier; } - public static GasPriceTracker create(BlockStore blockStore) { - return create(blockStore, DEFAULT_GAS_PRICE_MULTIPLIER); + public static GasPriceTracker create(BlockStore blockStore, GasPriceCalculator.GasCalculatorType gasCalculatorType) { + return create(blockStore, DEFAULT_GAS_PRICE_MULTIPLIER, gasCalculatorType); } - public static GasPriceTracker create(BlockStore blockStore, Double configMultiplier) { - GasPriceTracker gasPriceTracker = new GasPriceTracker(blockStore, configMultiplier); + public static GasPriceTracker create(BlockStore blockStore, Double configMultiplier, GasPriceCalculator.GasCalculatorType gasCalculatorType) { + GasPriceCalculator gasCal; + switch (gasCalculatorType) { + case WEIGHTED_PERCENTILE: + gasCal = new WeightedPercentileGasPriceCalculator(); + break; + case PLAIN_PERCENTILE: + gasCal = new PercentileGasPriceCalculator(); + break; + default: + throw new IllegalArgumentException("Unknown gas calculator type: " + gasCalculatorType); + } + GasPriceTracker gasPriceTracker = new GasPriceTracker(blockStore, gasCal, configMultiplier); gasPriceTracker.initializeWindowsFromDB(); + return gasPriceTracker; } + /** + * @deprecated Use {@link #create(BlockStore, GasPriceCalculator.GasCalculatorType)} instead. + */ + @Deprecated + public static GasPriceTracker create(BlockStore blockStore) { + //Will be using the legacy gas calculator as default option + return GasPriceTracker.create(blockStore, GasPriceCalculator.GasCalculatorType.PLAIN_PERCENTILE); + } + @Override public void onBestBlock(Block block, List receipts) { bestBlockPriceRef.set(block.getMinimumGasPrice()); @@ -96,38 +113,25 @@ public synchronized void onBlock(Block block, List receipts) trackBlockCompleteness(block); - for (Transaction tx : block.getTransactionsList()) { - onTransaction(tx); - } - + gasPriceCalculator.onBlock(block, receipts); logger.trace("End onBlock"); } - private void onTransaction(Transaction tx) { - if (tx instanceof RemascTransaction) { - return; - } - - trackGasPrice(tx); - } - public synchronized Coin getGasPrice() { - if (txWindow[0] == null) { // for some reason, not filled yet (i.e. not enough blocks on DB) + Optional gasPriceResult = gasPriceCalculator.getGasPrice(); + if(!gasPriceResult.isPresent()) { return defaultPrice; } - if (lastVal == null) { - Coin[] values = Arrays.copyOf(txWindow, TX_WINDOW_SIZE); - Arrays.sort(values); - lastVal = values[values.length / 4]; // 25% percentile - } + logger.debug("Gas provided by GasWindowCalc: {}", gasPriceResult.get()); Coin bestBlockPrice = bestBlockPriceRef.get(); if (bestBlockPrice == null) { - return lastVal; + logger.debug("Best block price not available, defaulting to {}", gasPriceResult.get()); + return gasPriceResult.get(); } - return Coin.max(lastVal, new Coin(new BigDecimal(bestBlockPrice.asBigInteger()) + return Coin.max(gasPriceResult.get(), new Coin(new BigDecimal(bestBlockPrice.asBigInteger()) .multiply(BigDecimal.valueOf(gasPriceMultiplier)).toBigInteger())); } @@ -180,14 +184,6 @@ private List getRequiredBlocksToFillWindowsFromDB() { return blocks; } - private void trackGasPrice(Transaction tx) { - if (txIdx == -1) { - txIdx = TX_WINDOW_SIZE - 1; - lastVal = null; // recalculate only 'sometimes' - } - txWindow[txIdx--] = tx.getGasPrice(); - } - private void trackBlockCompleteness(Block block) { double gasUsed = block.getGasUsed(); double gasLimit = block.getGasLimitAsInteger().doubleValue(); @@ -199,4 +195,8 @@ private void trackBlockCompleteness(Block block) { blockWindow[blockIdx++] = completeness; } + public GasPriceCalculator.GasCalculatorType getGasCalculatorType() { + return gasPriceCalculator.getType(); + } + } diff --git a/rskj-core/src/main/java/org/ethereum/listener/PercentileGasPriceCalculator.java b/rskj-core/src/main/java/org/ethereum/listener/PercentileGasPriceCalculator.java new file mode 100644 index 00000000000..5a4ccaa393e --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/listener/PercentileGasPriceCalculator.java @@ -0,0 +1,78 @@ +/* + * This file is part of RskJ + * Copyright (C) 2024 RSK Labs Ltd. + * (derived from ethereumJ library, Copyright (c) 2016 ) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.listener; + +import co.rsk.core.Coin; +import co.rsk.remasc.RemascTransaction; +import org.ethereum.core.Block; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionReceipt; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +public class PercentileGasPriceCalculator implements GasPriceCalculator { + private static final int TX_WINDOW_SIZE = 512; + + private final Coin[] txWindow = new Coin[TX_WINDOW_SIZE]; + private int txIdx = TX_WINDOW_SIZE - 1; + private Coin lastVal; + + @Override + public synchronized Optional getGasPrice() { + if (txWindow[0] == null) { // for some reason, not filled yet (i.e. not enough blocks on DB) + return Optional.empty(); + } else { + if (lastVal == null) { + Coin[] values = Arrays.copyOf(txWindow, TX_WINDOW_SIZE); + Arrays.sort(values); + lastVal = values[values.length / 4]; // 25% percentile + } + return Optional.of(lastVal); + } + } + + @Override + public synchronized void onBlock(Block block, List receipts) { + onBlock(block.getTransactionsList()); + } + + @Override + public GasCalculatorType getType() { + return GasCalculatorType.PLAIN_PERCENTILE; + } + + private void onBlock(List transactionList) { + for (Transaction tx : transactionList) { + if (!(tx instanceof RemascTransaction)) { + trackGasPrice(tx); + } + } + } + + private void trackGasPrice(Transaction tx) { + if (txIdx == -1) { + txIdx = TX_WINDOW_SIZE - 1; + lastVal = null; // recalculate only 'sometimes' + } + txWindow[txIdx--] = tx.getGasPrice(); + } + +} diff --git a/rskj-core/src/main/java/org/ethereum/listener/WeightedPercentileCalc.java b/rskj-core/src/main/java/org/ethereum/listener/WeightedPercentileCalc.java new file mode 100644 index 00000000000..046fc62f69a --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/listener/WeightedPercentileCalc.java @@ -0,0 +1,50 @@ +/* + * This file is part of RskJ + * Copyright (C) 2024 RSK Labs Ltd. + * (derived from ethereumJ library, Copyright (c) 2016 ) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.listener; + +import co.rsk.core.Coin; + +import java.util.Collections; +import java.util.List; + +class WeightedPercentileCalc { + + Coin calculateWeightedPercentile(float percentile, List gasEntries) { + if (gasEntries == null || gasEntries.isEmpty()) { + return null; + } + + Collections.sort(gasEntries); + + double totalWeight = gasEntries.stream().mapToLong(WeightedPercentileGasPriceCalculator.GasEntry::getGasUsed).sum(); + + double targetWeight = percentile / 100 * totalWeight; + + + double cumulativeWeight = 0; + for (WeightedPercentileGasPriceCalculator.GasEntry pair : gasEntries) { + cumulativeWeight += pair.getGasUsed(); + if (cumulativeWeight >= targetWeight) { + return pair.getGasPrice(); + } + } + + return null; + } +} diff --git a/rskj-core/src/main/java/org/ethereum/listener/WeightedPercentileGasPriceCalculator.java b/rskj-core/src/main/java/org/ethereum/listener/WeightedPercentileGasPriceCalculator.java new file mode 100644 index 00000000000..673573c491c --- /dev/null +++ b/rskj-core/src/main/java/org/ethereum/listener/WeightedPercentileGasPriceCalculator.java @@ -0,0 +1,141 @@ +/* + * This file is part of RskJ + * Copyright (C) 2024 RSK Labs Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.listener; + +import co.rsk.core.Coin; +import co.rsk.remasc.RemascTransaction; +import org.ethereum.core.Block; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionReceipt; + +import java.util.*; + +public class WeightedPercentileGasPriceCalculator implements GasPriceCalculator { + private static final int WINDOW_SIZE = 512; + public static final int REFERENCE_PERCENTILE = 25; + + private final ArrayDeque gasWindow; + private final WeightedPercentileCalc auxCalculator; + + private int txCount = 0; + private Coin cachedGasPrice = null; + + public WeightedPercentileGasPriceCalculator() { + this(new WeightedPercentileCalc()); + } + + public WeightedPercentileGasPriceCalculator(WeightedPercentileCalc weightedPercentileCalc) { + auxCalculator = weightedPercentileCalc; + gasWindow = new ArrayDeque<>(WINDOW_SIZE); + } + + @Override + public synchronized Optional getGasPrice() { + if (cachedGasPrice == null) { + cachedGasPrice = calculateGasPrice(); + } + return cachedGasPrice == null ? Optional.empty() : Optional.of(cachedGasPrice); + } + + @Override + public synchronized void onBlock(Block block, List receipts) { + for (TransactionReceipt receipt : receipts) { + if (!(receipt.getTransaction() instanceof RemascTransaction)) { + addTx(receipt.getTransaction(), new Coin(receipt.getGasUsed()).asBigInteger().longValue()); + } + } + } + + @Override + public GasCalculatorType getType() { + return GasCalculatorType.WEIGHTED_PERCENTILE; + } + + private void addTx(Transaction tx, long gasUsed) { + if (gasUsed == 0) { + return; + } + + txCount++; + + Coin gasPrice = tx.getGasPrice(); + + if (gasWindow.size() == WINDOW_SIZE) { + gasWindow.removeFirst(); + + } + gasWindow.add(new GasEntry(gasPrice, gasUsed)); + + if (txCount > WINDOW_SIZE) { + txCount = 0; // Reset the count + cachedGasPrice = null; // Invalidate the cached value to force recalculation when queried. + } + } + + private Coin calculateGasPrice() { + return auxCalculator.calculateWeightedPercentile(REFERENCE_PERCENTILE, new ArrayList<>(gasWindow)); + } + + static class GasEntry implements Comparable { + protected Coin gasPrice; + protected long gasUsed; + + GasEntry(Coin gasPrice, long gasUsed) { + this.gasPrice = gasPrice; + this.gasUsed = gasUsed; + } + + + public Coin getGasPrice() { + return gasPrice; + } + + public long getGasUsed() { + return gasUsed; + } + + @Override + public int compareTo + (GasEntry o) { + return this.gasPrice.compareTo(o.gasPrice); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof GasEntry)) { + return false; + } + GasEntry gasEntry = (GasEntry) o; + return gasUsed == gasEntry.gasUsed && + Objects.equals(gasPrice, gasEntry.gasPrice); + } + + @Override + public int hashCode() { + return Objects.hash(gasPrice, gasUsed); + } + + @Override + public String toString() { + return "(" + gasPrice + ", " + gasUsed + ")"; + } + } +} diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index 8b6461c0167..b48f4432a46 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -204,6 +204,7 @@ transaction = { threshold = timeout = } + gasPriceCalculatorType = gasPriceBump = accountSlots = accountTxRateLimit = { diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 5a2c3c7153a..f82fa66a6d9 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -167,7 +167,6 @@ peer { miner { # The default gas price minGasPrice = 0 - server { enabled = false isFixedClock = false @@ -234,6 +233,9 @@ transaction.outdated.threshold = 10 # (suggested value: 10 blocks * 10 seconds by block = 100 seconds) transaction.outdated.timeout = 650 +# choose the type of gas price calculator being PLAIN_PERCENTILE or WEIGHTED_PERCENTILE. The gas used by tx is taken into account only in WEIGHTED_PERCENTILE +transaction.gasPriceCalculatorType = PLAIN_PERCENTILE + # the percentage increase of gasPrice defined to accept a new transaction # with same nonce and sender while the previous one is not yet processed transaction.gasPriceBump = 40 diff --git a/rskj-core/src/test/java/co/rsk/NodeRunnerSmokeTest.java b/rskj-core/src/test/java/co/rsk/NodeRunnerSmokeTest.java index 0815c86ff7b..d435196a0d6 100644 --- a/rskj-core/src/test/java/co/rsk/NodeRunnerSmokeTest.java +++ b/rskj-core/src/test/java/co/rsk/NodeRunnerSmokeTest.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ - + package co.rsk; import org.ethereum.util.RskTestContext; diff --git a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java index 07382c02356..a76f9f83815 100644 --- a/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java +++ b/rskj-core/src/test/java/org/ethereum/listener/GasPriceTrackerTest.java @@ -152,7 +152,7 @@ void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_ReturnsBest @Test void getGasPrice_PriceWindowFilled_BestBlockReceivedWithGreaterPrice_GasPriceMultiplierOverWritten_ReturnsBestBlockAdjustedPriceWithNewBuffer() { - GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, 1.05); + GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore, 1.05, GasPriceCalculator.GasCalculatorType.PLAIN_PERCENTILE); Block bestBlock = makeBlock(Coin.valueOf(50_000_000_000L), 0, i -> null); Block block = makeBlock(Coin.valueOf(30_000_000_000L), TOTAL_SLOTS, i -> makeTx(Coin.valueOf(40_000_000_000L))); @@ -209,6 +209,20 @@ void isFeeMarketWorking_trueWhenAboveAverage() { assertTrue(gasPriceTracker.isFeeMarketWorking()); } + @Test + void gasTrackerIsCreatedWithTheCorrectType() { + GasPriceTracker gasPriceTracker = GasPriceTracker.create(blockStore); + assertEquals(GasPriceCalculator.GasCalculatorType.PLAIN_PERCENTILE, gasPriceTracker.getGasCalculatorType(), "Plain pecentile is the default one"); + + assertEquals(GasPriceCalculator.GasCalculatorType.PLAIN_PERCENTILE, + GasPriceTracker.create(blockStore, GasPriceCalculator.GasCalculatorType.PLAIN_PERCENTILE).getGasCalculatorType(), + "Plain percentile type is expected when passed as parameter"); + + assertEquals(GasPriceCalculator.GasCalculatorType.WEIGHTED_PERCENTILE, + GasPriceTracker.create(blockStore, GasPriceCalculator.GasCalculatorType.WEIGHTED_PERCENTILE).getGasCalculatorType(), + "Weighted percentile type is expected when passed as parameter"); + } + private static Block makeBlock(Coin mgp, int txCount, Function txMaker) { Block block = mock(Block.class); diff --git a/rskj-core/src/test/java/org/ethereum/listener/WeightedPercentileCalcTest.java b/rskj-core/src/test/java/org/ethereum/listener/WeightedPercentileCalcTest.java new file mode 100644 index 00000000000..cf048f8ffbb --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/listener/WeightedPercentileCalcTest.java @@ -0,0 +1,76 @@ +/* + * This file is part of RskJ + * Copyright (C) 2024 RSK Labs Ltd. + * (derived from ethereumJ library, Copyright (c) 2016 ) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.listener; + +import co.rsk.core.Coin; +import org.junit.jupiter.api.Test; + +import java.math.BigInteger; +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class WeightedPercentileCalcTest { + + @Test + void testCalculateWeightedPercentile() { + WeightedPercentileCalc weightedPercentileCalc = new WeightedPercentileCalc(); + + // Sample gas entries with smaller numbers + WeightedPercentileGasPriceCalculator.GasEntry entry1 = new WeightedPercentileGasPriceCalculator.GasEntry(new Coin(BigInteger.valueOf(100)), 1); + WeightedPercentileGasPriceCalculator.GasEntry entry2 = new WeightedPercentileGasPriceCalculator.GasEntry(new Coin(BigInteger.valueOf(200)), 3); + WeightedPercentileGasPriceCalculator.GasEntry entry3 = new WeightedPercentileGasPriceCalculator.GasEntry(new Coin(BigInteger.valueOf(300)), 1); + WeightedPercentileGasPriceCalculator.GasEntry entry4 = new WeightedPercentileGasPriceCalculator.GasEntry(new Coin(BigInteger.valueOf(500)), 10); + WeightedPercentileGasPriceCalculator.GasEntry entry5 = new WeightedPercentileGasPriceCalculator.GasEntry(new Coin(BigInteger.valueOf(400)), 1); + WeightedPercentileGasPriceCalculator.GasEntry entry6 = new WeightedPercentileGasPriceCalculator.GasEntry(new Coin(BigInteger.valueOf(700)), 2); + WeightedPercentileGasPriceCalculator.GasEntry entry7 = new WeightedPercentileGasPriceCalculator.GasEntry(new Coin(BigInteger.valueOf(600)), 4); + WeightedPercentileGasPriceCalculator.GasEntry entry8 = new WeightedPercentileGasPriceCalculator.GasEntry(new Coin(BigInteger.valueOf(800)), 1); + + + List gasEntries = Arrays.asList(entry1, entry2, entry3, entry4, entry5, entry6, entry7,entry8); + + + Coin result0 = weightedPercentileCalc.calculateWeightedPercentile(0, gasEntries); + assertEquals(new Coin(BigInteger.valueOf(100)), result0, "0th percentile should be 100"); + + Coin result10 = weightedPercentileCalc.calculateWeightedPercentile(1, gasEntries); + assertEquals(new Coin(BigInteger.valueOf(100)), result10, "1th percentile should be 100"); + + Coin result20 = weightedPercentileCalc.calculateWeightedPercentile(20.2f, gasEntries); + assertEquals(new Coin(BigInteger.valueOf(300)), result20, "20th percentile should be 300"); + + Coin result40 = weightedPercentileCalc.calculateWeightedPercentile(40, gasEntries); + assertEquals(new Coin(BigInteger.valueOf(500)), result40, "40th percentile should be 500"); + + Coin result50 = weightedPercentileCalc.calculateWeightedPercentile(50, gasEntries); + assertEquals(new Coin(BigInteger.valueOf(500)), result50, "50th percentile should be 500"); + + Coin result75 = weightedPercentileCalc.calculateWeightedPercentile(75, gasEntries); + assertEquals(new Coin(BigInteger.valueOf(600)), result75, "75th percentile should be 600"); + + Coin result90 = weightedPercentileCalc.calculateWeightedPercentile(90, gasEntries); + assertEquals(new Coin(BigInteger.valueOf(700)), result90, "90th percentile should be 600"); + + Coin result100 = weightedPercentileCalc.calculateWeightedPercentile(100, gasEntries); + assertEquals(new Coin(BigInteger.valueOf(800)), result100, "100th percentile should be 800"); + + + } +} \ No newline at end of file diff --git a/rskj-core/src/test/java/org/ethereum/listener/WeightedPercentileGasPriceCalculatorTest.java b/rskj-core/src/test/java/org/ethereum/listener/WeightedPercentileGasPriceCalculatorTest.java new file mode 100644 index 00000000000..597f5191202 --- /dev/null +++ b/rskj-core/src/test/java/org/ethereum/listener/WeightedPercentileGasPriceCalculatorTest.java @@ -0,0 +1,204 @@ +/* + * This file is part of RskJ + * Copyright (C) 2024 RSK Labs Ltd. + * (derived from ethereumJ library, Copyright (c) 2016 ) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +package org.ethereum.listener; + +import co.rsk.core.Coin; +import org.ethereum.core.Block; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionReceipt; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mockito; + +import java.math.BigInteger; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +class WeightedPercentileGasPriceCalculatorTest { + + private static final int WINDOW_SIZE = 512; + private WeightedPercentileGasPriceCalculator weightedPercentileGasPriceCalculator; + + + @BeforeEach + void setup() { + weightedPercentileGasPriceCalculator = new WeightedPercentileGasPriceCalculator(); + } + + @Test + void testCalculateWeightedPercentileWithNoTransactions() { + // Test when no transactions are added + assertNotNull(weightedPercentileGasPriceCalculator); + assertFalse(weightedPercentileGasPriceCalculator.getGasPrice().isPresent(), "Gas price should not be present when no transactions are added"); + } + + @Test + void testCalculateGasPriceWithZeroTotalGasUsed() { + // Test when the total gas used is zero + Block mockBlock = Mockito.mock(Block.class); + + TransactionReceipt mockReceipt = Mockito.mock(TransactionReceipt.class); + Transaction mockTransaction = Mockito.mock(Transaction.class); + when(mockTransaction.getGasPrice()).thenReturn(new Coin(BigInteger.valueOf(100))); + when(mockReceipt.getTransaction()).thenReturn(mockTransaction); + when(mockReceipt.getGasUsed()).thenReturn(BigInteger.ZERO.toByteArray()); + + weightedPercentileGasPriceCalculator.onBlock(mockBlock, Collections.singletonList(mockReceipt)); + + Optional gasPrice = weightedPercentileGasPriceCalculator.getGasPrice(); + assertFalse(gasPrice.isPresent(), "Gas price should not be present when total gas used is zero"); + } + + @Test + void testCalculateGasPriceWithSingleTransaction() { + // Test when a single transaction is added + Block mockBlock = Mockito.mock(Block.class); + + TransactionReceipt mockReceipt = Mockito.mock(TransactionReceipt.class); + Transaction mockTransaction = Mockito.mock(Transaction.class); + when(mockTransaction.getGasPrice()).thenReturn(new Coin(BigInteger.valueOf(100))); + when(mockReceipt.getTransaction()).thenReturn(mockTransaction); + when(mockReceipt.getGasUsed()).thenReturn(BigInteger.valueOf(500).toByteArray()); + + weightedPercentileGasPriceCalculator.onBlock(mockBlock, Collections.singletonList(mockReceipt)); + + Optional gasPrice = weightedPercentileGasPriceCalculator.getGasPrice(); + assertTrue(gasPrice.isPresent(), "Gas price should be present when a transaction is added"); + assertEquals(new Coin(BigInteger.valueOf(100)), gasPrice.get(), "Gas price should be the same as the single transaction's gas price"); + } + + @Test + void testCalculateGasPriceWithMultipleTransactionsSameGasUsage() { + // Test when multiple transactions are added + Block mockBlock = Mockito.mock(Block.class); + + TransactionReceipt mockReceipt1 = Mockito.mock(TransactionReceipt.class); + Transaction mockTransaction1 = Mockito.mock(Transaction.class); + when(mockTransaction1.getGasPrice()).thenReturn(new Coin(BigInteger.valueOf(100))); + when(mockReceipt1.getTransaction()).thenReturn(mockTransaction1); + when(mockReceipt1.getGasUsed()).thenReturn(BigInteger.valueOf(100).toByteArray()); + + TransactionReceipt mockReceipt2 = Mockito.mock(TransactionReceipt.class); + Transaction mockTransaction2 = Mockito.mock(Transaction.class); + when(mockTransaction2.getGasPrice()).thenReturn(new Coin(BigInteger.valueOf(300))); + when(mockReceipt2.getTransaction()).thenReturn(mockTransaction2); + when(mockReceipt2.getGasUsed()).thenReturn(BigInteger.valueOf(300).toByteArray()); + + TransactionReceipt mockReceipt3 = Mockito.mock(TransactionReceipt.class); + Transaction mockTransaction3 = Mockito.mock(Transaction.class); + when(mockTransaction3.getGasPrice()).thenReturn(new Coin(BigInteger.valueOf(200))); + when(mockReceipt3.getTransaction()).thenReturn(mockTransaction3); + when(mockReceipt3.getGasUsed()).thenReturn(BigInteger.valueOf(200).toByteArray()); + weightedPercentileGasPriceCalculator.onBlock(mockBlock, Arrays.asList(mockReceipt1, mockReceipt2, mockReceipt3)); + + Optional gasPrice = weightedPercentileGasPriceCalculator.getGasPrice(); + assertTrue(gasPrice.isPresent(), "Gas price should be present when multiple transactions are added"); + assertEquals(new Coin(BigInteger.valueOf(200)), gasPrice.get(), "Expecting 200 as weighted percentile for the provided set."); + } + + @Test + void testCalculateGasPriceWithPlainSet() { + Block mockBlock = Mockito.mock(Block.class); + List receipts = createMockReceipts(100, 1); + weightedPercentileGasPriceCalculator.onBlock(mockBlock, receipts); + Optional gasPrice = weightedPercentileGasPriceCalculator.getGasPrice(); + assertTrue(gasPrice.isPresent(), "Gas price should be present when multiple transactions are added"); + assertEquals(new Coin(BigInteger.valueOf(25)), gasPrice.get(), "Gas price should be the weighted average of multiple transactions"); + } + + @Test + void cacheValueIsNotUpdatedUntilWindowSizeIsReached() { + WeightedPercentileCalc percentileCalc = new WeightedPercentileCalc(); + WeightedPercentileCalc spy = spy(percentileCalc); + WeightedPercentileGasPriceCalculator gasPriceCalculator = new WeightedPercentileGasPriceCalculator(spy); + + Block mockBlock = Mockito.mock(Block.class); + gasPriceCalculator.onBlock(mockBlock, createMockReceipts(10, 1)); + + Optional result1 = gasPriceCalculator.getGasPrice(); + assertTrue(result1.isPresent(), "Gas price should be present when multiple transactions are added"); + + gasPriceCalculator.onBlock(mockBlock, createMockReceipts(WINDOW_SIZE - 20, 2)); + Optional result2 = gasPriceCalculator.getGasPrice(); + assertTrue(result2.isPresent(), "Gas price should be present when multiple transactions are added"); + + assertEquals(result1.get(), result2.get(), "Gas price is not updated if window threshold is not reached"); + verify(spy, times(1)).calculateWeightedPercentile(anyFloat(), anyList()); + + gasPriceCalculator.onBlock(mockBlock, createMockReceipts(30, 1)); + Optional result3 = gasPriceCalculator.getGasPrice(); + assertTrue(result3.isPresent(), "Gas price should be present when multiple transactions are added"); + + assertNotEquals(result1.get(), result3.get(), "Gas price is updated if window threshold is reached"); + verify(spy, times(2)).calculateWeightedPercentile(anyFloat(), anyList()); + } + + @Test + void olderTxAreRemovedWhenWindowLimitIsReach() { + Block mockBlock = Mockito.mock(Block.class); + WeightedPercentileCalc mockPC = Mockito.mock(WeightedPercentileCalc.class); + when(mockPC.calculateWeightedPercentile(anyFloat(), anyList())).thenReturn(new Coin(BigInteger.valueOf(1))); + + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); + WeightedPercentileGasPriceCalculator gpc = new WeightedPercentileGasPriceCalculator(mockPC); + + //Transactions are added until window size limit + gpc.onBlock(mockBlock, createMockReceipts(WINDOW_SIZE, 1)); + gpc.getGasPrice(); + + //New transactions are added to reach the window limit and re-calculate gas + TransactionReceipt mockReceipt = Mockito.mock(TransactionReceipt.class); + Transaction mockTransaction = Mockito.mock(Transaction.class); + when(mockTransaction.getGasPrice()).thenReturn(new Coin(BigInteger.valueOf(850))); + when(mockReceipt.getTransaction()).thenReturn(mockTransaction); + when(mockReceipt.getGasUsed()).thenReturn(BigInteger.valueOf(1).toByteArray()); + gpc.onBlock(mockBlock, Collections.singletonList(mockReceipt)); + gpc.getGasPrice(); + + verify(mockPC, times(2)).calculateWeightedPercentile(anyFloat(), captor.capture()); + List> gasPriceList = captor.getAllValues(); + + List firstList = gasPriceList.get(0); + Coin firstValueFirstList = firstList.get(0).getGasPrice(); + + assertEquals(new Coin(BigInteger.valueOf(1)), firstValueFirstList, "Gas price should be the same as the first transaction's gas price"); + + List secondList = gasPriceList.get(1); + //The second time the getGasPrice is called the first transaction should be removed and the new one added at the bottom + assertEquals(new Coin(BigInteger.valueOf(850)), secondList.get(secondList.size() - 1).getGasPrice(), "Gas price should be the same as the first transaction's gas price"); + assertEquals(firstList.subList(1, firstList.size() - 1), secondList.subList(0, secondList.size() - 2), "The first list should be the same as the second list without the first and last element"); + } + + private List createMockReceipts(int numOfReceipts, int gasUsed) { + List receipts = new ArrayList<>(); + for (int i = 0; i < numOfReceipts; i++) { + TransactionReceipt mockReceipt = Mockito.mock(TransactionReceipt.class); + Transaction mockTransaction = Mockito.mock(Transaction.class); + when(mockTransaction.getGasPrice()).thenReturn(new Coin(BigInteger.valueOf(1 + i))); + when(mockReceipt.getTransaction()).thenReturn(mockTransaction); + when(mockReceipt.getGasUsed()).thenReturn(BigInteger.valueOf(gasUsed).toByteArray()); + receipts.add(mockReceipt); + } + return receipts; + } + +} \ No newline at end of file From 00b57eafdb9333364d027ee39c3aa1984b8f4a61 Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 5 Mar 2024 16:05:25 -0300 Subject: [PATCH 126/137] Add missing imports --- .../java/co/rsk/peg/BridgeSupportFactory.java | 3 +- .../rsk/remasc/RemascFederationProvider.java | 2 +- .../src/test/java/co/rsk/peg/BridgeTest.java | 1 + .../peg/federation/P2shErpFederationTest.java | 41 +++++++++---------- .../remasc/RemascFederationProviderTest.java | 12 +++--- 5 files changed, 29 insertions(+), 30 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java index dcc9b9b8235..4c68f041258 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java @@ -25,9 +25,8 @@ import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.peg.utils.BridgeEventLoggerImpl; -import java.util.List; - import co.rsk.peg.utils.BrigeEventLoggerLegacyImpl; +import java.util.List; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.Block; diff --git a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java index 2d76cc3198a..de2b294947d 100644 --- a/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java +++ b/rskj-core/src/main/java/co/rsk/remasc/RemascFederationProvider.java @@ -18,8 +18,8 @@ package co.rsk.remasc; import co.rsk.core.RskAddress; -import co.rsk.peg.FederationMember; import co.rsk.peg.FederationSupport; +import co.rsk.peg.federation.FederationMember; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.crypto.ECKey; diff --git a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java index 1877e27fe7c..6b5e92d3693 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeTest.java @@ -19,6 +19,7 @@ import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationArgs; import co.rsk.peg.federation.FederationFactory; +import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.FederationMember.KeyType; import co.rsk.peg.federation.FederationTestUtils; import co.rsk.peg.flyover.FlyoverTxResponseCodes; diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java index dbf05b20e5c..5fcace9599d 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/P2shErpFederationTest.java @@ -1,36 +1,28 @@ package co.rsk.peg.federation; import static co.rsk.bitcoinj.script.Script.MAX_SCRIPT_ELEMENT_SIZE; -import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; -import static co.rsk.peg.federation.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; import static co.rsk.peg.bitcoin.RedeemScriptCreationException.Reason.INVALID_CSV_VALUE; import static co.rsk.peg.bitcoin.ScriptCreationException.Reason.ABOVE_MAX_SCRIPT_ELEMENT_SIZE; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.NULL_OR_EMPTY_EMERGENCY_KEYS; +import static co.rsk.peg.federation.ErpFederationCreationException.Reason.REDEEM_SCRIPT_CREATION_FAILED; import static org.junit.jupiter.api.Assertions.*; import co.rsk.bitcoinj.core.*; -import co.rsk.bitcoinj.script.*; -import co.rsk.config.BridgeConstants; -import co.rsk.config.BridgeMainNetConstants; -import co.rsk.config.BridgeRegTestConstants; -import co.rsk.config.BridgeTestNetConstants; +import co.rsk.bitcoinj.script.Script; +import co.rsk.bitcoinj.script.ScriptOpCodes; +import co.rsk.config.*; import co.rsk.peg.bitcoin.*; - +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.time.Instant; import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; import org.bouncycastle.util.encoders.Hex; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; @@ -64,9 +56,16 @@ void setup() { BtcECKey federator8PublicKey = BtcECKey.fromPublicOnly(Hex.decode("031aabbeb9b27258f98c2bf21f36677ae7bae09eb2d8c958ef41a20a6e88626d26")); BtcECKey federator9PublicKey = BtcECKey.fromPublicOnly(Hex.decode("0245ef34f5ee218005c9c21227133e8568a4f3f11aeab919c66ff7b816ae1ffeea")); defaultKeys = Arrays.asList( - federator0PublicKey, federator1PublicKey, federator2PublicKey, - federator3PublicKey, federator4PublicKey, federator5PublicKey, - federator6PublicKey, federator7PublicKey, federator8PublicKey, federator9PublicKey + federator0PublicKey, + federator1PublicKey, + federator2PublicKey, + federator3PublicKey, + federator4PublicKey, + federator5PublicKey, + federator6PublicKey, + federator7PublicKey, + federator8PublicKey, + federator9PublicKey ); defaultThreshold = defaultKeys.size() / 2 + 1; emergencyKeys = bridgeConstants.getErpFedPubKeysList(); @@ -529,7 +528,7 @@ void spendFromP2shErpFed( @Test void getMemberByBtcPublicKey_passing_existing_btcPublicKey_should_return_found_member(){ - BtcECKey existingMemberBtcPublicKey = standardKeys.get(0); + BtcECKey existingMemberBtcPublicKey = defaultKeys.get(0); Optional foundMember = federation.getMemberByBtcPublicKey(existingMemberBtcPublicKey); Assertions.assertTrue(foundMember.isPresent()); Assertions.assertEquals(existingMemberBtcPublicKey, foundMember.get().getBtcPublicKey()); diff --git a/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java b/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java index c91db4385cb..ec8e4b6df22 100644 --- a/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java +++ b/rskj-core/src/test/java/co/rsk/remasc/RemascFederationProviderTest.java @@ -1,22 +1,22 @@ package co.rsk.remasc; +import static org.mockito.Mockito.*; + import co.rsk.blockchain.utils.BlockGenerator; import co.rsk.config.BridgeMainNetConstants; import co.rsk.core.RskAddress; -import co.rsk.peg.*; +import co.rsk.peg.BridgeStorageProvider; +import co.rsk.peg.FederationSupport; +import co.rsk.peg.federation.FederationMember; import co.rsk.test.builders.BlockChainBuilder; import co.rsk.util.HexUtils; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ActivationConfigsForTest; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; +import org.ethereum.config.blockchain.upgrades.*; import org.ethereum.core.Blockchain; import org.ethereum.core.Genesis; import org.ethereum.vm.PrecompiledContracts; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import static org.mockito.Mockito.*; - /** * Created by ajlopez on 14/11/2017. */ From f90a5f3995fb01f9678c64ac4c028e7aadd54965 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Thu, 11 Jan 2024 17:29:51 -0300 Subject: [PATCH 127/137] add new pendingTx impl --- .../src/main/java/co/rsk/rpc/Web3EthModule.java | 2 ++ .../src/main/java/org/ethereum/rpc/Web3Impl.java | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/rpc/Web3EthModule.java b/rskj-core/src/main/java/co/rsk/rpc/Web3EthModule.java index f4e7df6e256..71e50475bb7 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/Web3EthModule.java +++ b/rskj-core/src/main/java/co/rsk/rpc/Web3EthModule.java @@ -121,6 +121,8 @@ default String eth_sendTransaction(CallArgumentsParam args) { TransactionResultDTO eth_getTransactionByBlockNumberAndIndex(BlockIdentifierParam bnOrId, HexIndexParam index) throws Exception; TransactionReceiptDTO eth_getTransactionReceipt(TxHashParam transactionHash) throws Exception; + TransactionResultDTO[] eth_pendingTransactions() throws Exception; + BlockResultDTO eth_getUncleByBlockHashAndIndex(BlockHashParam blockHash, HexIndexParam uncleIdx) throws Exception; diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index b0e56b7c691..be43f3c5484 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -40,8 +40,10 @@ import co.rsk.rpc.modules.rsk.RskModule; import co.rsk.rpc.modules.trace.TraceModule; import co.rsk.rpc.modules.txpool.TxPoolModule; +import co.rsk.rpc.modules.txpool.TxPoolModuleImpl; import co.rsk.scoring.*; import co.rsk.util.HexUtils; +import com.fasterxml.jackson.databind.JsonNode; import com.google.common.annotations.VisibleForTesting; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; @@ -852,6 +854,20 @@ public TransactionReceiptDTO eth_getTransactionReceipt(TxHashParam transactionHa return new TransactionReceiptDTO(block, txInfo, signatureCache); } + @Override + public TransactionResultDTO[] eth_pendingTransactions() { + JsonNode content = txPoolModule.content(); + JsonNode pendingTransactionsNode = content.get(TxPoolModuleImpl.PENDING); + + if (pendingTransactionsNode == null || pendingTransactionsNode.isEmpty()) { + return new TransactionResultDTO[0]; + } + + List transactionDTOs = new ArrayList<>(); + + return transactionDTOs.toArray(new TransactionResultDTO[0]); + } + @Override public BlockResultDTO eth_getUncleByBlockHashAndIndex(BlockHashParam blockHash, HexIndexParam uncleIdx) { BlockResultDTO s = null; From 53848edce06e38468114059a6a06272aeb00ad21 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Tue, 23 Jan 2024 10:30:31 -0300 Subject: [PATCH 128/137] fix tx pool fetching and filtering --- .../main/java/org/ethereum/rpc/Web3Impl.java | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index be43f3c5484..9a2c3568f27 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -17,6 +17,7 @@ */ package org.ethereum.rpc; +import co.rsk.bitcoinj.core.Address; import co.rsk.config.RskSystemProperties; import co.rsk.core.Coin; import co.rsk.core.RskAddress; @@ -78,6 +79,7 @@ import java.util.*; import java.util.function.Function; import java.util.function.UnaryOperator; +import java.util.stream.Collectors; import static co.rsk.util.HexUtils.*; import static java.lang.Math.max; @@ -856,16 +858,19 @@ public TransactionReceiptDTO eth_getTransactionReceipt(TxHashParam transactionHa @Override public TransactionResultDTO[] eth_pendingTransactions() { - JsonNode content = txPoolModule.content(); - JsonNode pendingTransactionsNode = content.get(TxPoolModuleImpl.PENDING); - - if (pendingTransactionsNode == null || pendingTransactionsNode.isEmpty()) { - return new TransactionResultDTO[0]; - } - - List transactionDTOs = new ArrayList<>(); - - return transactionDTOs.toArray(new TransactionResultDTO[0]); + // get pending txs + List pendingTransactions = web3InformationRetriever.getTransactions("pending"); + + // get list of accounts managed by the node + Set managedAccountSet = new HashSet<>(Arrays.asList(personalModule.listAccounts())); + + return pendingTransactions.stream() + .filter(tx -> { + String senderAddress = HexUtils.toJsonHex(tx.getSender(signatureCache).getBytes()); + return managedAccountSet.contains(senderAddress); + }) + .map(tx -> new TransactionResultDTO(null, null, tx, config.rpcZeroSignatureIfRemasc(), signatureCache)) + .toArray(TransactionResultDTO[]::new); } @Override From 0d62e1fa9de9e2e4a35dbbe98186dadce389163f Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Fri, 26 Jan 2024 11:33:29 -0300 Subject: [PATCH 129/137] fix address formating and add unit tests --- .../main/java/org/ethereum/rpc/Web3Impl.java | 2 +- .../java/org/ethereum/rpc/Web3ImplTest.java | 140 ++++++++++++++++++ 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index 9a2c3568f27..402b50d1f55 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -866,7 +866,7 @@ public TransactionResultDTO[] eth_pendingTransactions() { return pendingTransactions.stream() .filter(tx -> { - String senderAddress = HexUtils.toJsonHex(tx.getSender(signatureCache).getBytes()); + String senderAddress = tx.getSender(signatureCache).toJsonString(); return managedAccountSet.contains(senderAddress); }) .map(tx -> new TransactionResultDTO(null, null, tx, config.rpcZeroSignatureIfRemasc(), signatureCache)) diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index ecbf44231ec..545fcc0f3ee 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -26,6 +26,8 @@ import co.rsk.core.bc.TransactionPoolImpl; import co.rsk.crypto.Keccak256; import co.rsk.db.RepositoryLocator; +import co.rsk.logfilter.BlocksBloomStore; +import co.rsk.metrics.HashRateCalculator; import co.rsk.mine.MinerClient; import co.rsk.mine.MinerServer; import co.rsk.net.BlockProcessor; @@ -42,13 +44,17 @@ import co.rsk.rpc.modules.eth.EthModule; import co.rsk.rpc.modules.eth.EthModuleTransactionBase; import co.rsk.rpc.modules.eth.EthModuleWalletEnabled; +import co.rsk.rpc.modules.evm.EvmModule; +import co.rsk.rpc.modules.mnr.MnrModule; import co.rsk.rpc.modules.personal.PersonalModule; import co.rsk.rpc.modules.personal.PersonalModuleWalletDisabled; import co.rsk.rpc.modules.personal.PersonalModuleWalletEnabled; import co.rsk.rpc.modules.rsk.RskModule; import co.rsk.rpc.modules.rsk.RskModuleImpl; +import co.rsk.rpc.modules.trace.TraceModule; import co.rsk.rpc.modules.txpool.TxPoolModule; import co.rsk.rpc.modules.txpool.TxPoolModuleImpl; +import co.rsk.scoring.PeerScoringManager; import co.rsk.test.World; import co.rsk.test.builders.AccountBuilder; import co.rsk.test.builders.BlockBuilder; @@ -1102,6 +1108,140 @@ void getTransactionCountByNonCanonicalBlockHash() { final ChainParams chain = createChainWithATransaction(true); assertNonCanonicalBlockHash("0x1", chain.block, blockRef -> chain.web3.eth_getTransactionCount(new HexAddressParam(chain.accountAddress), new BlockRefParam(blockRef))); } + @Test + void pendingTransactionsNoTxShouldReturnEmptyList() { + World world = new World(); + Web3Impl web3 = createWeb3(world); + + TransactionResultDTO[] tr = web3.eth_pendingTransactions(); + + List trList = Arrays.asList(tr); + + assertNotNull(trList); + assertEquals(0, trList.size()); + } + + @Test + void pendingTransactionsWithManagedAccount() { + Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); + PersonalModule personalModule = mock(PersonalModule.class); + Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule); + + Transaction mockTransaction1 = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); + Transaction mockTransaction2 = mockTransactionFrom("0xa3a15ed8C3b83efC744F2e0A7824A00846C21860"); + + List pendingTransactions = Arrays.asList(mockTransaction1, mockTransaction2); + when(web3InformationRetriever.getTransactions("pending")).thenReturn(pendingTransactions); + + + Set managedAccounts = new HashSet<>(Arrays.asList("0x63a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase())); + when(personalModule.listAccounts()).thenReturn(managedAccounts.toArray(new String[0])); + + TransactionResultDTO[] result = web3.eth_pendingTransactions(); + + assertEquals(1, result.length, "Expected only transactions from managed accounts"); + } + + @Test + void pendingTransactionsWithMultipleManagedAccounts() { + Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); + PersonalModule personalModule = mock(PersonalModule.class); + Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule); + + Transaction mockTransaction1 = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); + Transaction mockTransaction2 = mockTransactionFrom("0xa3a15ed8C3b83efC744F2e0A7824A00846C21860"); + Transaction mockTransaction3 = mockTransactionFrom("0xb3b15ed8C3b83efC744F2e0A7824A00846C21860"); + + List pendingTransactions = Arrays.asList(mockTransaction1, mockTransaction2, mockTransaction3); + when(web3InformationRetriever.getTransactions("pending")).thenReturn(pendingTransactions); + + Set managedAccounts = new HashSet<>(Arrays.asList( + "0x63a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase(), + "0xa3a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase() + )); + + when(personalModule.listAccounts()).thenReturn(managedAccounts.toArray(new String[0])); + + TransactionResultDTO[] result = web3.eth_pendingTransactions(); + + assertEquals(2, result.length, "Expected transactions only from managed accounts"); + } + + @Test + void pendingTransactionsWithNoManagedAccountsShouldReturnEmptyList() { + Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); + PersonalModule personalModule = mock(PersonalModule.class); + Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule); + + Transaction mockTransaction = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); + + List pendingTransactions = Collections.singletonList(mockTransaction); + when(web3InformationRetriever.getTransactions("pending")).thenReturn(pendingTransactions); + + when(personalModule.listAccounts()).thenReturn(new String[0]); + + TransactionResultDTO[] result = web3.eth_pendingTransactions(); + + assertEquals(0, result.length, "Expected no transactions as there are no managed accounts"); + } + + private Transaction mockTransactionFrom(String senderAddress) { + Transaction transaction = mock(Transaction.class); + RskAddress address = new RskAddress(senderAddress); + when(transaction.getSender(any(SignatureCache.class))).thenReturn(address); + + byte[] mockHashBytes = new byte[32]; + Arrays.fill(mockHashBytes, (byte) 1); + Keccak256 mockHash = new Keccak256(mockHashBytes); + when(transaction.getHash()).thenReturn(mockHash); + when(transaction.getReceiveAddress()).thenReturn(address); + when(transaction.getNonce()).thenReturn(BigInteger.ZERO.toByteArray()); + when(transaction.getGasLimit()).thenReturn(BigInteger.valueOf(21000).toByteArray()); + when(transaction.getGasPrice()).thenReturn(Coin.valueOf(50_000_000_000L)); + when(transaction.getValue()).thenReturn(Coin.ZERO); + when(transaction.getData()).thenReturn(new byte[0]); + ECDSASignature mockSignature = new ECDSASignature(BigInteger.ONE, BigInteger.ONE); + when(transaction.getSignature()).thenReturn(mockSignature); + when(transaction.getEncodedV()).thenReturn((byte) 1); + + return transaction; + } + + private Web3Impl createWeb3WithMocks(Web3InformationRetriever web3InformationRetriever, PersonalModule personalModule) { + // Mock all the dependencies required by Web3Impl + Ethereum eth = mock(Ethereum.class); + Blockchain blockchain = mock(Blockchain.class); + BlockStore blockStore = mock(BlockStore.class); + ReceiptStore receiptStore = mock(ReceiptStore.class); + RskSystemProperties config = mock(RskSystemProperties.class); + MinerClient minerClient = mock(MinerClient.class); + MinerServer minerServer = mock(MinerServer.class); + EthModule ethModule = mock(EthModule.class); + EvmModule evmModule = mock(EvmModule.class); + TxPoolModule txPoolModule = mock(TxPoolModule.class); + MnrModule mnrModule = mock(MnrModule.class); + DebugModule debugModule = mock(DebugModule.class); + TraceModule traceModule = mock(TraceModule.class); + RskModule rskModule = mock(RskModule.class); + ChannelManager channelManager = mock(ChannelManager.class); + PeerScoringManager peerScoringManager = mock(PeerScoringManager.class); + PeerServer peerServer = mock(PeerServer.class); + BlockProcessor nodeBlockProcessor = mock(BlockProcessor.class); + HashRateCalculator hashRateCalculator = mock(HashRateCalculator.class); + ConfigCapabilities configCapabilities = mock(ConfigCapabilities.class); + BuildInfo buildInfo = mock(BuildInfo.class); + BlocksBloomStore blocksBloomStore = mock(BlocksBloomStore.class); + SyncProcessor syncProcessor = mock(SyncProcessor.class); + SignatureCache signatureCache = mock(SignatureCache.class); + + // Create Web3Impl with the mocked dependencies + return new Web3Impl(eth, blockchain, blockStore, receiptStore, config, minerClient, minerServer, + personalModule, ethModule, evmModule, txPoolModule, mnrModule, debugModule, + traceModule, rskModule, channelManager, peerScoringManager, peerServer, + nodeBlockProcessor, hashRateCalculator, configCapabilities, buildInfo, + blocksBloomStore, web3InformationRetriever, syncProcessor, signatureCache); + } + @Test void getBlockByNumber() { From 99f849e6063c8334f58330ab22a3fb509e255504 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Fri, 26 Jan 2024 14:51:42 -0300 Subject: [PATCH 130/137] make PENDING define public --- .../src/main/java/co/rsk/rpc/Web3InformationRetriever.java | 2 +- rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/Web3InformationRetriever.java b/rskj-core/src/main/java/co/rsk/rpc/Web3InformationRetriever.java index 328b8be17c1..40af9360099 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/Web3InformationRetriever.java +++ b/rskj-core/src/main/java/co/rsk/rpc/Web3InformationRetriever.java @@ -47,7 +47,7 @@ public class Web3InformationRetriever { private static final String EARLIEST = "earliest"; private static final String LATEST = "latest"; - private static final String PENDING = "pending"; + public static final String PENDING = "pending"; private final TransactionPool transactionPool; private final Blockchain blockchain; diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index 402b50d1f55..db26d021023 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -859,7 +859,7 @@ public TransactionReceiptDTO eth_getTransactionReceipt(TxHashParam transactionHa @Override public TransactionResultDTO[] eth_pendingTransactions() { // get pending txs - List pendingTransactions = web3InformationRetriever.getTransactions("pending"); + List pendingTransactions = web3InformationRetriever.getTransactions(Web3InformationRetriever.PENDING); // get list of accounts managed by the node Set managedAccountSet = new HashSet<>(Arrays.asList(personalModule.listAccounts())); From 65f41b8891d3ed93d180160f356b19e8e83dbb26 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Mon, 29 Jan 2024 01:52:10 -0300 Subject: [PATCH 131/137] add pendingTx method to EthModule --- .../co/rsk/rpc/modules/eth/EthModule.java | 5 +++++ .../main/java/org/ethereum/rpc/Web3Impl.java | 2 +- .../java/org/ethereum/rpc/Web3ImplTest.java | 19 +++++++++++-------- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java index 4c6c02f1c2f..4e423ef59e3 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java @@ -52,6 +52,7 @@ import javax.annotation.Nonnull; import java.io.IOException; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Optional; @@ -189,6 +190,10 @@ public String estimateGas(CallArgumentsParam args, @Nonnull BlockIdentifierParam } } + public List pendingTransactions() { + return transactionPool.getPendingTransactions(); + } + protected String internalEstimateGas(ProgramResult reversibleExecutionResult) { long estimatedGas = reversibleExecutionResult.getMovedRemainingGasToChild() ? reversibleExecutionResult.getGasUsed() + reversibleExecutionResult.getDeductedRefund() : diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index db26d021023..dc443d0f151 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -859,7 +859,7 @@ public TransactionReceiptDTO eth_getTransactionReceipt(TxHashParam transactionHa @Override public TransactionResultDTO[] eth_pendingTransactions() { // get pending txs - List pendingTransactions = web3InformationRetriever.getTransactions(Web3InformationRetriever.PENDING); + List pendingTransactions = ethModule.pendingTransactions(); // get list of accounts managed by the node Set managedAccountSet = new HashSet<>(Arrays.asList(personalModule.listAccounts())); diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index 545fcc0f3ee..5cd494c7ef7 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -77,6 +77,7 @@ import org.ethereum.facade.Ethereum; import org.ethereum.listener.GasPriceTracker; import org.ethereum.net.client.ConfigCapabilities; +import org.ethereum.net.eth.handler.Eth; import org.ethereum.net.server.ChannelManager; import org.ethereum.net.server.PeerServer; import org.ethereum.rpc.Simples.*; @@ -1124,14 +1125,15 @@ void pendingTransactionsNoTxShouldReturnEmptyList() { @Test void pendingTransactionsWithManagedAccount() { Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); + EthModule ethModule = mock(EthModule.class); PersonalModule personalModule = mock(PersonalModule.class); - Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule); + Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule, ethModule); Transaction mockTransaction1 = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); Transaction mockTransaction2 = mockTransactionFrom("0xa3a15ed8C3b83efC744F2e0A7824A00846C21860"); List pendingTransactions = Arrays.asList(mockTransaction1, mockTransaction2); - when(web3InformationRetriever.getTransactions("pending")).thenReturn(pendingTransactions); + when(ethModule.pendingTransactions()).thenReturn(pendingTransactions); Set managedAccounts = new HashSet<>(Arrays.asList("0x63a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase())); @@ -1145,15 +1147,16 @@ void pendingTransactionsWithManagedAccount() { @Test void pendingTransactionsWithMultipleManagedAccounts() { Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); + EthModule ethModule = mock(EthModule.class); PersonalModule personalModule = mock(PersonalModule.class); - Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule); + Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule, ethModule); Transaction mockTransaction1 = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); Transaction mockTransaction2 = mockTransactionFrom("0xa3a15ed8C3b83efC744F2e0A7824A00846C21860"); Transaction mockTransaction3 = mockTransactionFrom("0xb3b15ed8C3b83efC744F2e0A7824A00846C21860"); List pendingTransactions = Arrays.asList(mockTransaction1, mockTransaction2, mockTransaction3); - when(web3InformationRetriever.getTransactions("pending")).thenReturn(pendingTransactions); + when(ethModule.pendingTransactions()).thenReturn(pendingTransactions); Set managedAccounts = new HashSet<>(Arrays.asList( "0x63a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase(), @@ -1171,13 +1174,14 @@ void pendingTransactionsWithMultipleManagedAccounts() { void pendingTransactionsWithNoManagedAccountsShouldReturnEmptyList() { Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); PersonalModule personalModule = mock(PersonalModule.class); - Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule); + EthModule ethModule = mock(EthModule.class); + Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule, ethModule); Transaction mockTransaction = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); List pendingTransactions = Collections.singletonList(mockTransaction); - when(web3InformationRetriever.getTransactions("pending")).thenReturn(pendingTransactions); + when(ethModule.pendingTransactions()).thenReturn(pendingTransactions); when(personalModule.listAccounts()).thenReturn(new String[0]); TransactionResultDTO[] result = web3.eth_pendingTransactions(); @@ -1207,7 +1211,7 @@ private Transaction mockTransactionFrom(String senderAddress) { return transaction; } - private Web3Impl createWeb3WithMocks(Web3InformationRetriever web3InformationRetriever, PersonalModule personalModule) { + private Web3Impl createWeb3WithMocks(Web3InformationRetriever web3InformationRetriever, PersonalModule personalModule, EthModule ethModule) { // Mock all the dependencies required by Web3Impl Ethereum eth = mock(Ethereum.class); Blockchain blockchain = mock(Blockchain.class); @@ -1216,7 +1220,6 @@ private Web3Impl createWeb3WithMocks(Web3InformationRetriever web3InformationRet RskSystemProperties config = mock(RskSystemProperties.class); MinerClient minerClient = mock(MinerClient.class); MinerServer minerServer = mock(MinerServer.class); - EthModule ethModule = mock(EthModule.class); EvmModule evmModule = mock(EvmModule.class); TxPoolModule txPoolModule = mock(TxPoolModule.class); MnrModule mnrModule = mock(MnrModule.class); From 434927a7c763ebf76d1b40d7d51bc31a8a530c02 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Mon, 29 Jan 2024 18:15:23 -0300 Subject: [PATCH 132/137] remove unused imports --- rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index dc443d0f151..a00dbe97690 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -17,7 +17,6 @@ */ package org.ethereum.rpc; -import co.rsk.bitcoinj.core.Address; import co.rsk.config.RskSystemProperties; import co.rsk.core.Coin; import co.rsk.core.RskAddress; @@ -41,10 +40,8 @@ import co.rsk.rpc.modules.rsk.RskModule; import co.rsk.rpc.modules.trace.TraceModule; import co.rsk.rpc.modules.txpool.TxPoolModule; -import co.rsk.rpc.modules.txpool.TxPoolModuleImpl; import co.rsk.scoring.*; import co.rsk.util.HexUtils; -import com.fasterxml.jackson.databind.JsonNode; import com.google.common.annotations.VisibleForTesting; import org.ethereum.config.blockchain.upgrades.ConsensusRule; import org.ethereum.core.*; @@ -79,7 +76,6 @@ import java.util.*; import java.util.function.Function; import java.util.function.UnaryOperator; -import java.util.stream.Collectors; import static co.rsk.util.HexUtils.*; import static java.lang.Math.max; From 5829e6fbbbabd24965f23d65e690440d933b1db9 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Tue, 6 Feb 2024 09:56:34 -0300 Subject: [PATCH 133/137] move pendingTx logic to EthModuleWallet --- rskj-core/src/main/java/co/rsk/RskContext.java | 2 +- .../java/co/rsk/rpc/modules/eth/EthModule.java | 9 +++------ .../rsk/rpc/modules/eth/EthModuleWallet.java | 6 ++++++ .../modules/eth/EthModuleWalletDisabled.java | 7 +++++++ .../modules/eth/EthModuleWalletEnabled.java | 16 +++++++++++++++- .../main/java/org/ethereum/rpc/Web3Impl.java | 12 +----------- .../co/rsk/mine/TransactionModuleTest.java | 2 +- .../org/ethereum/rpc/Web3ImplLogsTest.java | 2 +- .../org/ethereum/rpc/Web3ImplScoringTest.java | 2 +- .../java/org/ethereum/rpc/Web3ImplTest.java | 18 +++++++++++------- 10 files changed, 47 insertions(+), 29 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/RskContext.java b/rskj-core/src/main/java/co/rsk/RskContext.java index 8a80eec9deb..dd184fbb1b2 100644 --- a/rskj-core/src/main/java/co/rsk/RskContext.java +++ b/rskj-core/src/main/java/co/rsk/RskContext.java @@ -1869,7 +1869,7 @@ private EthModuleWallet getEthModuleWallet() { if (wallet == null) { ethModuleWallet = new EthModuleWalletDisabled(); } else { - ethModuleWallet = new EthModuleWalletEnabled(wallet); + ethModuleWallet = new EthModuleWalletEnabled(wallet, transactionPool); } } diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java index 4e423ef59e3..7ce45d42fdb 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java @@ -51,10 +51,7 @@ import javax.annotation.Nonnull; import java.io.IOException; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import static java.util.Arrays.copyOfRange; import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError; @@ -190,8 +187,8 @@ public String estimateGas(CallArgumentsParam args, @Nonnull BlockIdentifierParam } } - public List pendingTransactions() { - return transactionPool.getPendingTransactions(); + public List ethPendingTransactions() { + return ethModuleWallet.ethPendingTransactions(); } protected String internalEstimateGas(ProgramResult reversibleExecutionResult) { diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWallet.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWallet.java index aaf90d7ff35..c63744a19f7 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWallet.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWallet.java @@ -18,9 +18,15 @@ package co.rsk.rpc.modules.eth; +import org.ethereum.core.Transaction; + +import java.util.List; + public interface EthModuleWallet { String[] accounts(); String sign(String addr, String data); + + public List ethPendingTransactions(); } \ No newline at end of file diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java index 4cf03242cd2..5416840fbe8 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java @@ -18,10 +18,12 @@ package co.rsk.rpc.modules.eth; +import org.ethereum.core.Transaction; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Arrays; +import java.util.List; import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError; @@ -36,6 +38,11 @@ public String[] accounts() { return accounts; } + @Override + public List ethPendingTransactions() { + throw invalidParamError("Local wallet is disabled in this node"); + } + @Override public String sign(String addr, String data) { LOGGER.debug("eth_sign({}, {}): {}", addr, data, null); diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java index 7ac52b5e3a1..b50ee981f36 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java @@ -22,10 +22,14 @@ import java.nio.charset.StandardCharsets; import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; import co.rsk.core.RskAddress; import org.bouncycastle.util.BigIntegers; import org.ethereum.core.Account; +import org.ethereum.core.Transaction; +import org.ethereum.core.TransactionPool; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; import org.ethereum.crypto.signature.ECDSASignature; @@ -41,9 +45,11 @@ public class EthModuleWalletEnabled implements EthModuleWallet { private static final Logger LOGGER = LoggerFactory.getLogger("web3"); private final Wallet wallet; + private final TransactionPool transactionPool; - public EthModuleWalletEnabled(Wallet wallet) { + public EthModuleWalletEnabled(Wallet wallet, TransactionPool transactionPool) { this.wallet = wallet; + this.transactionPool = transactionPool; } @Override @@ -90,4 +96,12 @@ private String sign(String data, ECKey ecKey) { new byte[]{signature.getV()} )); } + @Override + public List ethPendingTransactions() { + List pendingTxs = transactionPool.getPendingTransactions(); + String[] managedAccounts = accounts(); + return pendingTxs.stream() + .filter(tx -> Arrays.stream(managedAccounts).anyMatch(acc -> acc.equals(tx.getSender().toString()))) + .collect(Collectors.toList()); + } } \ No newline at end of file diff --git a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java index a00dbe97690..c43896fbb59 100644 --- a/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java +++ b/rskj-core/src/main/java/org/ethereum/rpc/Web3Impl.java @@ -854,17 +854,7 @@ public TransactionReceiptDTO eth_getTransactionReceipt(TxHashParam transactionHa @Override public TransactionResultDTO[] eth_pendingTransactions() { - // get pending txs - List pendingTransactions = ethModule.pendingTransactions(); - - // get list of accounts managed by the node - Set managedAccountSet = new HashSet<>(Arrays.asList(personalModule.listAccounts())); - - return pendingTransactions.stream() - .filter(tx -> { - String senderAddress = tx.getSender(signatureCache).toJsonString(); - return managedAccountSet.contains(senderAddress); - }) + return ethModule.ethPendingTransactions().stream() .map(tx -> new TransactionResultDTO(null, null, tx, config.rpcZeroSignatureIfRemasc(), signatureCache)) .toArray(TransactionResultDTO[]::new); } diff --git a/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java b/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java index 8e1aff4e871..69f39bc16cc 100644 --- a/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java +++ b/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java @@ -643,7 +643,7 @@ private Web3Impl internalCreateEnvironment(Blockchain blockchain, EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockchain, transactionPool, reversibleTransactionExecutor1, new ExecutionBlockRetriever(blockchain, null, null), - repositoryLocator, new EthModuleWalletEnabled(wallet), transactionModule, + repositoryLocator, new EthModuleWalletEnabled(wallet, transactionPool), transactionModule, new BridgeSupportFactory( btcBlockStoreFactory, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), signatureCache), diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java index b9cbe67c95a..d9cc47dc524 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java @@ -1092,7 +1092,7 @@ private Web3Impl createWeb3() { EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockChain, transactionPool, null, new ExecutionBlockRetriever(blockChain, null, null), - null, new EthModuleWalletEnabled(wallet), null, + null, new EthModuleWalletEnabled(wallet, transactionPool), null, new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), new BlockTxSignatureCache(new ReceivedTxSignatureCache())), config.getGasEstimationCap(), diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplScoringTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplScoringTest.java index c86d0a04e9f..76260141ec2 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplScoringTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplScoringTest.java @@ -393,7 +393,7 @@ private static Web3Impl createWeb3(PeerScoringManager peerScoringManager) { EthModule em = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), world.getBlockChain(), null, null, new ExecutionBlockRetriever(world.getBlockChain(), null, null), - null, new EthModuleWalletEnabled(wallet), null, + null, new EthModuleWalletEnabled(wallet, world.getTransactionPool()), null, new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), new BlockTxSignatureCache(new ReceivedTxSignatureCache())), config.getGasEstimationCap(), diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index 5cd494c7ef7..5c97ac4e733 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -19,6 +19,7 @@ package org.ethereum.rpc; import co.rsk.Flusher; +import co.rsk.TestHelpers.Tx; import co.rsk.config.RskSystemProperties; import co.rsk.config.TestSystemProperties; import co.rsk.core.*; @@ -77,7 +78,6 @@ import org.ethereum.facade.Ethereum; import org.ethereum.listener.GasPriceTracker; import org.ethereum.net.client.ConfigCapabilities; -import org.ethereum.net.eth.handler.Eth; import org.ethereum.net.server.ChannelManager; import org.ethereum.net.server.PeerServer; import org.ethereum.rpc.Simples.*; @@ -1133,7 +1133,7 @@ void pendingTransactionsWithManagedAccount() { Transaction mockTransaction2 = mockTransactionFrom("0xa3a15ed8C3b83efC744F2e0A7824A00846C21860"); List pendingTransactions = Arrays.asList(mockTransaction1, mockTransaction2); - when(ethModule.pendingTransactions()).thenReturn(pendingTransactions); + when(ethModule.ethPendingTransactions()).thenReturn(pendingTransactions); Set managedAccounts = new HashSet<>(Arrays.asList("0x63a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase())); @@ -1156,7 +1156,7 @@ void pendingTransactionsWithMultipleManagedAccounts() { Transaction mockTransaction3 = mockTransactionFrom("0xb3b15ed8C3b83efC744F2e0A7824A00846C21860"); List pendingTransactions = Arrays.asList(mockTransaction1, mockTransaction2, mockTransaction3); - when(ethModule.pendingTransactions()).thenReturn(pendingTransactions); + when(ethModule.ethPendingTransactions()).thenReturn(pendingTransactions); Set managedAccounts = new HashSet<>(Arrays.asList( "0x63a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase(), @@ -1180,10 +1180,14 @@ void pendingTransactionsWithNoManagedAccountsShouldReturnEmptyList() { Transaction mockTransaction = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); List pendingTransactions = Collections.singletonList(mockTransaction); + // mock transactionPool.getPendingTransactions() to return a list of transactions + when(ethModule.ethPendingTransactions()).thenReturn(pendingTransactions); + - when(ethModule.pendingTransactions()).thenReturn(pendingTransactions); when(personalModule.listAccounts()).thenReturn(new String[0]); + + TransactionResultDTO[] result = web3.eth_pendingTransactions(); assertEquals(0, result.length, "Expected no transactions as there are no managed accounts"); @@ -2746,7 +2750,7 @@ private Web3Impl createWeb3(SimpleEthereum eth, PeerServer peerServer) { EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockchain, transactionPool, null, new ExecutionBlockRetriever(blockchain, null, null), - null, new EthModuleWalletEnabled(wallet), null, + null, new EthModuleWalletEnabled(wallet, transactionPool), null, new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), signatureCache), config.getGasEstimationCap(), @@ -2863,7 +2867,7 @@ private Web3Impl createWeb3( TransactionGateway transactionGateway = new TransactionGateway(new SimpleChannelManager(), transactionPool); EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockchain, transactionPool, executor, - new ExecutionBlockRetriever(blockchain, null, null), repositoryLocator, new EthModuleWalletEnabled(wallet), + new ExecutionBlockRetriever(blockchain, null, null), repositoryLocator, new EthModuleWalletEnabled(wallet, transactionPool), new EthModuleTransactionBase(config.getNetworkConstants(), wallet, transactionPool, transactionGateway), new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), signatureCache), @@ -2927,7 +2931,7 @@ private Web3Impl createWeb3CallNoReturn( EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockchain, transactionPool, executor, new ExecutionBlockRetriever(blockchain, null, null), repositoryLocator, - new EthModuleWalletEnabled(wallet), + new EthModuleWalletEnabled(wallet, transactionPool), new EthModuleTransactionBase(config.getNetworkConstants(), wallet, transactionPool, null), new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), signatureCache), From d2078ba8b6144877fe73b51d3b49b38e573c6432 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Wed, 7 Feb 2024 10:16:51 -0300 Subject: [PATCH 134/137] fix empty response for disabled wallet --- .../java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java index 5416840fbe8..6a70c38f03c 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletDisabled.java @@ -23,6 +23,7 @@ import org.slf4j.LoggerFactory; import java.util.Arrays; +import java.util.Collections; import java.util.List; import static org.ethereum.rpc.exception.RskJsonRpcRequestException.invalidParamError; @@ -40,7 +41,9 @@ public String[] accounts() { @Override public List ethPendingTransactions() { - throw invalidParamError("Local wallet is disabled in this node"); + List transactions = Collections.emptyList(); + LOGGER.debug("eth_pendingTransactions(): {}", transactions); + return transactions; } @Override From 97cc42ed9902ca052f1fd9a4803275e3b02c0e5d Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Wed, 7 Feb 2024 20:27:38 -0300 Subject: [PATCH 135/137] fix EthModule impl and unit tests@ --- .../co/rsk/rpc/modules/eth/EthModule.java | 2 +- .../rsk/rpc/modules/eth/EthModuleWallet.java | 2 +- .../modules/eth/EthModuleWalletEnabled.java | 4 +- .../co/rsk/rpc/modules/eth/EthModuleTest.java | 164 ++++++++++++++++++ .../java/org/ethereum/rpc/Web3ImplTest.java | 78 +++------ 5 files changed, 188 insertions(+), 62 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java index 7ce45d42fdb..3602f3fa400 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModule.java @@ -188,7 +188,7 @@ public String estimateGas(CallArgumentsParam args, @Nonnull BlockIdentifierParam } public List ethPendingTransactions() { - return ethModuleWallet.ethPendingTransactions(); + return ethModuleWallet.ethPendingTransactions(); } protected String internalEstimateGas(ProgramResult reversibleExecutionResult) { diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWallet.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWallet.java index c63744a19f7..fdc363ddafc 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWallet.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWallet.java @@ -28,5 +28,5 @@ public interface EthModuleWallet { String sign(String addr, String data); - public List ethPendingTransactions(); + List ethPendingTransactions(); } \ No newline at end of file diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java index b50ee981f36..f326fe3e588 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java @@ -99,9 +99,9 @@ private String sign(String data, ECKey ecKey) { @Override public List ethPendingTransactions() { List pendingTxs = transactionPool.getPendingTransactions(); - String[] managedAccounts = accounts(); + List managedAccounts = Arrays.asList(accounts()); return pendingTxs.stream() - .filter(tx -> Arrays.stream(managedAccounts).anyMatch(acc -> acc.equals(tx.getSender().toString()))) + .filter(tx -> managedAccounts.contains(tx.getSender().toJsonString())) .collect(Collectors.toList()); } } \ No newline at end of file diff --git a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java index e2e030935a0..95a47af19b1 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java @@ -19,10 +19,12 @@ import co.rsk.config.BridgeConstants; import co.rsk.config.TestSystemProperties; +import co.rsk.core.Coin; import co.rsk.core.ReversibleTransactionExecutor; import co.rsk.core.RskAddress; import co.rsk.core.Wallet; import co.rsk.core.bc.PendingState; +import co.rsk.crypto.Keccak256; import co.rsk.db.RepositoryLocator; import co.rsk.net.TransactionGateway; import co.rsk.peg.BridgeSupportFactory; @@ -33,6 +35,7 @@ import org.ethereum.config.Constants; import org.ethereum.core.*; import org.ethereum.crypto.ECKey; +import org.ethereum.crypto.signature.ECDSASignature; import org.ethereum.datasource.HashMapDB; import org.ethereum.rpc.CallArguments; import org.ethereum.rpc.exception.RskJsonRpcRequestException; @@ -49,6 +52,11 @@ import org.junit.jupiter.api.Test; import org.mockito.ArgumentCaptor; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.*; @@ -731,4 +739,160 @@ void whenExecuteSendTransactionWithInputAndDataParameters_callExecutorWithInput( .receiveTransaction(transactionCaptor.capture()); assertArrayEquals(Hex.decode(expectedDataValue), transactionCaptor.getValue().getData()); } + + @Test + void testEthPendingTransactionsWithNoTransactions() { + EthModuleWallet ethModuleWalletMock = mock(EthModuleWallet.class); + TransactionPool transactionPoolMock = mock(TransactionPool.class); + when(transactionPoolMock.getPendingTransactions()).thenReturn(Collections.emptyList()); + + Block block = mock(Block.class); + ExecutionBlockRetriever.Result blockResult = mock(ExecutionBlockRetriever.Result.class); + when(blockResult.getBlock()).thenReturn(block); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + Blockchain blockchain = mock(Blockchain.class); + + ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); + + EthModule ethModule = new EthModule( + null, + Constants.REGTEST_CHAIN_ID, + blockchain, + transactionPoolMock, + reversibleTransactionExecutor, + retriever, + mock(RepositoryLocator.class), + ethModuleWalletMock, + null, + new BridgeSupportFactory( + null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + List result = ethModule.ethPendingTransactions(); + + assertTrue(result.isEmpty(), "Expected no transactions"); + } + + @Test + void pendingTransactionsWithMultipleManagedAccounts() { + Wallet wallet = mock(Wallet.class); + TransactionPool transactionPoolMock = mock(TransactionPool.class); + EthModuleWalletEnabled ethModuleWallet = new EthModuleWalletEnabled(wallet, transactionPoolMock); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + Blockchain blockchain = mock(Blockchain.class); + ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); + + EthModule ethModule = new EthModule( + null, + Constants.REGTEST_CHAIN_ID, + blockchain, + transactionPoolMock, + reversibleTransactionExecutor, + retriever, + mock(RepositoryLocator.class), + ethModuleWallet, + null, + new BridgeSupportFactory(null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + Transaction mockTransaction1 = createMockTransaction("0x63a15ed8c3b83efc744f2e0a7824a00846c21860"); + Transaction mockTransaction2 = createMockTransaction( "0xa3a15ed8c3b83efc744f2e0a7824a00846c21860"); + Transaction mockTransaction3 = createMockTransaction( "0xb3a15ed8c3b83efc744f2e0a7824a00846c21860"); + List allTransactions = Arrays.asList(mockTransaction1, mockTransaction2, mockTransaction3); + + when(transactionPoolMock.getPendingTransactions()).thenReturn(allTransactions); + when(ethModuleWallet.accounts()).thenReturn(new String[]{"0x63a15ed8c3b83efc744f2e0a7824a00846c21860", "0xa3a15ed8c3b83efc744f2e0a7824a00846c21860"}); + + List result = ethModule.ethPendingTransactions(); + + assertEquals(2, result.size(), "Expected only transactions from managed accounts"); + } + + @Test + void pendingTransactionsWithNoManagedAccounts() { + Wallet wallet = mock(Wallet.class); + TransactionPool transactionPoolMock = mock(TransactionPool.class); + EthModuleWalletEnabled ethModuleWallet = new EthModuleWalletEnabled(wallet, transactionPoolMock); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + Blockchain blockchain = mock(Blockchain.class); + ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); + + EthModule ethModule = new EthModule( + null, + Constants.REGTEST_CHAIN_ID, + blockchain, + transactionPoolMock, + reversibleTransactionExecutor, + retriever, + mock(RepositoryLocator.class), + ethModuleWallet, + null, + new BridgeSupportFactory(null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + Transaction mockTransaction1 = createMockTransaction("0x63a15ed8c3b83efc744f2e0a7824a00846c21860"); + Transaction mockTransaction2 = createMockTransaction("0x13a15ed8c3b83efc744f2e0a7824a00846c21860"); + List allTransactions = Arrays.asList(mockTransaction1, mockTransaction2); + + when(transactionPoolMock.getPendingTransactions()).thenReturn(allTransactions); + when(ethModuleWallet.accounts()).thenReturn(new String[]{}); + + List result = ethModule.ethPendingTransactions(); + + assertTrue(result.isEmpty(), "Expected no transactions as there are no managed accounts"); + } + + @Test + void pendingTransactionsWithWalletDisabled() { + TransactionPool transactionPoolMock = mock(TransactionPool.class); + EthModuleWalletDisabled ethModuleWallet = new EthModuleWalletDisabled(); + ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); + Blockchain blockchain = mock(Blockchain.class); + ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); + + EthModule ethModule = new EthModule( + null, + Constants.REGTEST_CHAIN_ID, + blockchain, + transactionPoolMock, + reversibleTransactionExecutor, + retriever, + mock(RepositoryLocator.class), + ethModuleWallet, + null, + new BridgeSupportFactory(null, null, null, signatureCache), + config.getGasEstimationCap(), + config.getCallGasCap()); + + List result = ethModule.ethPendingTransactions(); + + assertTrue(result.isEmpty(), "Expected no transactions as wallet is disabled"); + } + + + private Transaction createMockTransaction(String fromAddress) { + Transaction transaction = mock(Transaction.class); + RskAddress address = new RskAddress(fromAddress); + System.out.println("mock address: " + address); + when(transaction.getSender()).thenReturn(address); + + byte[] mockHashBytes = new byte[32]; + Arrays.fill(mockHashBytes, (byte) 1); + Keccak256 mockHash = new Keccak256(mockHashBytes); + when(transaction.getHash()).thenReturn(mockHash); + when(transaction.getReceiveAddress()).thenReturn(address); + when(transaction.getNonce()).thenReturn(BigInteger.ZERO.toByteArray()); + when(transaction.getGasLimit()).thenReturn(BigInteger.valueOf(21000).toByteArray()); + when(transaction.getGasPrice()).thenReturn(Coin.valueOf(50_000_000_000L)); + when(transaction.getValue()).thenReturn(Coin.ZERO); + when(transaction.getData()).thenReturn(new byte[0]); + ECDSASignature mockSignature = new ECDSASignature(BigInteger.ONE, BigInteger.ONE); + when(transaction.getSignature()).thenReturn(mockSignature); + when(transaction.getEncodedV()).thenReturn((byte) 1); + + return transaction; + } } diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index 5c97ac4e733..b19d2cf8f2c 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -19,7 +19,6 @@ package org.ethereum.rpc; import co.rsk.Flusher; -import co.rsk.TestHelpers.Tx; import co.rsk.config.RskSystemProperties; import co.rsk.config.TestSystemProperties; import co.rsk.core.*; @@ -1123,74 +1122,38 @@ void pendingTransactionsNoTxShouldReturnEmptyList() { } @Test - void pendingTransactionsWithManagedAccount() { - Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); - EthModule ethModule = mock(EthModule.class); - PersonalModule personalModule = mock(PersonalModule.class); - Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule, ethModule); - - Transaction mockTransaction1 = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); - Transaction mockTransaction2 = mockTransactionFrom("0xa3a15ed8C3b83efC744F2e0A7824A00846C21860"); - - List pendingTransactions = Arrays.asList(mockTransaction1, mockTransaction2); - when(ethModule.ethPendingTransactions()).thenReturn(pendingTransactions); - - - Set managedAccounts = new HashSet<>(Arrays.asList("0x63a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase())); - when(personalModule.listAccounts()).thenReturn(managedAccounts.toArray(new String[0])); - - TransactionResultDTO[] result = web3.eth_pendingTransactions(); - - assertEquals(1, result.length, "Expected only transactions from managed accounts"); - } - - @Test - void pendingTransactionsWithMultipleManagedAccounts() { - Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); - EthModule ethModule = mock(EthModule.class); - PersonalModule personalModule = mock(PersonalModule.class); - Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule, ethModule); - - Transaction mockTransaction1 = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); - Transaction mockTransaction2 = mockTransactionFrom("0xa3a15ed8C3b83efC744F2e0A7824A00846C21860"); - Transaction mockTransaction3 = mockTransactionFrom("0xb3b15ed8C3b83efC744F2e0A7824A00846C21860"); + void pendingTransactionsReturnsFilteredList() { + EthModule ethModuleMock = mock(EthModule.class); - List pendingTransactions = Arrays.asList(mockTransaction1, mockTransaction2, mockTransaction3); - when(ethModule.ethPendingTransactions()).thenReturn(pendingTransactions); + Web3Impl web3 = createWeb3WithMocks(ethModuleMock); - Set managedAccounts = new HashSet<>(Arrays.asList( - "0x63a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase(), - "0xa3a15ed8C3b83efC744F2e0A7824A00846C21860".toLowerCase() - )); + Transaction mockTransaction1 = mockTransactionFrom("0x63a15ed8c3b83efc744f2e0a7824a00846c21860"); + Transaction mockTransaction2 = mockTransactionFrom( "0xa3a15ed8c3b83efc744f2e0a7824a00846c21860"); + Transaction mockTransaction3 = mockTransactionFrom( "0xb3a15ed8c3b83efc744f2e0a7824a00846c21860"); + List allTransactions = Arrays.asList(mockTransaction1, mockTransaction2, mockTransaction3); - when(personalModule.listAccounts()).thenReturn(managedAccounts.toArray(new String[0])); + when(ethModuleMock.ethPendingTransactions()).thenReturn(allTransactions); TransactionResultDTO[] result = web3.eth_pendingTransactions(); - assertEquals(2, result.length, "Expected transactions only from managed accounts"); + assertEquals(3, result.length, "Expected all transactions"); } @Test - void pendingTransactionsWithNoManagedAccountsShouldReturnEmptyList() { - Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); - PersonalModule personalModule = mock(PersonalModule.class); - EthModule ethModule = mock(EthModule.class); - Web3Impl web3 = createWeb3WithMocks(web3InformationRetriever, personalModule, ethModule); - - Transaction mockTransaction = mockTransactionFrom("0x63a15ed8C3b83efC744F2e0A7824A00846C21860"); + void pendingTransactionsReturnsCorrectTransaction() { + EthModule ethModuleMock = mock(EthModule.class); - List pendingTransactions = Collections.singletonList(mockTransaction); - // mock transactionPool.getPendingTransactions() to return a list of transactions - when(ethModule.ethPendingTransactions()).thenReturn(pendingTransactions); - - - when(personalModule.listAccounts()).thenReturn(new String[0]); + Web3Impl web3 = createWeb3WithMocks(ethModuleMock); + Transaction mockTransaction1 = mockTransactionFrom("0x63a15ed8c3b83efc744f2e0a7824a00846c21860"); + List allTransactions = Arrays.asList(mockTransaction1); + when(ethModuleMock.ethPendingTransactions()).thenReturn(allTransactions); TransactionResultDTO[] result = web3.eth_pendingTransactions(); - assertEquals(0, result.length, "Expected no transactions as there are no managed accounts"); + assertEquals(1, result.length, "Expected only one transaction"); + assertEquals("0x63a15ed8c3b83efc744f2e0a7824a00846c21860", result[0].getFrom()); } private Transaction mockTransactionFrom(String senderAddress) { @@ -1215,13 +1178,11 @@ private Transaction mockTransactionFrom(String senderAddress) { return transaction; } - private Web3Impl createWeb3WithMocks(Web3InformationRetriever web3InformationRetriever, PersonalModule personalModule, EthModule ethModule) { - // Mock all the dependencies required by Web3Impl + private Web3Impl createWeb3WithMocks(EthModule ethModule) { Ethereum eth = mock(Ethereum.class); Blockchain blockchain = mock(Blockchain.class); BlockStore blockStore = mock(BlockStore.class); ReceiptStore receiptStore = mock(ReceiptStore.class); - RskSystemProperties config = mock(RskSystemProperties.class); MinerClient minerClient = mock(MinerClient.class); MinerServer minerServer = mock(MinerServer.class); EvmModule evmModule = mock(EvmModule.class); @@ -1240,6 +1201,8 @@ private Web3Impl createWeb3WithMocks(Web3InformationRetriever web3InformationRet BlocksBloomStore blocksBloomStore = mock(BlocksBloomStore.class); SyncProcessor syncProcessor = mock(SyncProcessor.class); SignatureCache signatureCache = mock(SignatureCache.class); + Web3InformationRetriever web3InformationRetriever = mock(Web3InformationRetriever.class); + PersonalModule personalModule = mock(PersonalModule.class); // Create Web3Impl with the mocked dependencies return new Web3Impl(eth, blockchain, blockStore, receiptStore, config, minerClient, minerServer, @@ -1249,7 +1212,6 @@ private Web3Impl createWeb3WithMocks(Web3InformationRetriever web3InformationRet blocksBloomStore, web3InformationRetriever, syncProcessor, signatureCache); } - @Test void getBlockByNumber() { World world = new World(); From 5b7754ca155f77b4239b7e2f51c9679aa9571cc0 Mon Sep 17 00:00:00 2001 From: maximo santoro Date: Fri, 9 Feb 2024 10:25:18 -0300 Subject: [PATCH 136/137] add signature cache to EthModuleWalletEnabled class --- rskj-core/src/main/java/co/rsk/RskContext.java | 2 +- .../rsk/rpc/modules/eth/EthModuleWalletEnabled.java | 11 +++++------ .../test/java/co/rsk/mine/TransactionModuleTest.java | 2 +- .../java/co/rsk/rpc/modules/eth/EthModuleTest.java | 6 +++--- .../test/java/org/ethereum/rpc/Web3ImplLogsTest.java | 2 +- .../java/org/ethereum/rpc/Web3ImplScoringTest.java | 2 +- .../src/test/java/org/ethereum/rpc/Web3ImplTest.java | 6 +++--- 7 files changed, 15 insertions(+), 16 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/RskContext.java b/rskj-core/src/main/java/co/rsk/RskContext.java index dd184fbb1b2..992f64395e6 100644 --- a/rskj-core/src/main/java/co/rsk/RskContext.java +++ b/rskj-core/src/main/java/co/rsk/RskContext.java @@ -1869,7 +1869,7 @@ private EthModuleWallet getEthModuleWallet() { if (wallet == null) { ethModuleWallet = new EthModuleWalletDisabled(); } else { - ethModuleWallet = new EthModuleWalletEnabled(wallet, transactionPool); + ethModuleWallet = new EthModuleWalletEnabled(wallet, getTransactionPool(), getReceivedTxSignatureCache()); } } diff --git a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java index f326fe3e588..006896464df 100644 --- a/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java +++ b/rskj-core/src/main/java/co/rsk/rpc/modules/eth/EthModuleWalletEnabled.java @@ -27,9 +27,7 @@ import co.rsk.core.RskAddress; import org.bouncycastle.util.BigIntegers; -import org.ethereum.core.Account; -import org.ethereum.core.Transaction; -import org.ethereum.core.TransactionPool; +import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.crypto.HashUtil; import org.ethereum.crypto.signature.ECDSASignature; @@ -43,13 +41,14 @@ public class EthModuleWalletEnabled implements EthModuleWallet { private static final Logger LOGGER = LoggerFactory.getLogger("web3"); - private final Wallet wallet; private final TransactionPool transactionPool; + private final SignatureCache signatureCache; - public EthModuleWalletEnabled(Wallet wallet, TransactionPool transactionPool) { + public EthModuleWalletEnabled(Wallet wallet, TransactionPool transactionPool, SignatureCache signatureCache) { this.wallet = wallet; this.transactionPool = transactionPool; + this.signatureCache = signatureCache; } @Override @@ -101,7 +100,7 @@ public List ethPendingTransactions() { List pendingTxs = transactionPool.getPendingTransactions(); List managedAccounts = Arrays.asList(accounts()); return pendingTxs.stream() - .filter(tx -> managedAccounts.contains(tx.getSender().toJsonString())) + .filter(tx -> managedAccounts.contains(tx.getSender(signatureCache).toJsonString())) .collect(Collectors.toList()); } } \ No newline at end of file diff --git a/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java b/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java index 69f39bc16cc..1d2f6641773 100644 --- a/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java +++ b/rskj-core/src/test/java/co/rsk/mine/TransactionModuleTest.java @@ -643,7 +643,7 @@ private Web3Impl internalCreateEnvironment(Blockchain blockchain, EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockchain, transactionPool, reversibleTransactionExecutor1, new ExecutionBlockRetriever(blockchain, null, null), - repositoryLocator, new EthModuleWalletEnabled(wallet, transactionPool), transactionModule, + repositoryLocator, new EthModuleWalletEnabled(wallet, transactionPool, signatureCache), transactionModule, new BridgeSupportFactory( btcBlockStoreFactory, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), signatureCache), diff --git a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java index 95a47af19b1..b8b740adec1 100644 --- a/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java +++ b/rskj-core/src/test/java/co/rsk/rpc/modules/eth/EthModuleTest.java @@ -778,7 +778,7 @@ void testEthPendingTransactionsWithNoTransactions() { void pendingTransactionsWithMultipleManagedAccounts() { Wallet wallet = mock(Wallet.class); TransactionPool transactionPoolMock = mock(TransactionPool.class); - EthModuleWalletEnabled ethModuleWallet = new EthModuleWalletEnabled(wallet, transactionPoolMock); + EthModuleWalletEnabled ethModuleWallet = new EthModuleWalletEnabled(wallet, transactionPoolMock, signatureCache); ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); Blockchain blockchain = mock(Blockchain.class); ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); @@ -814,7 +814,7 @@ void pendingTransactionsWithMultipleManagedAccounts() { void pendingTransactionsWithNoManagedAccounts() { Wallet wallet = mock(Wallet.class); TransactionPool transactionPoolMock = mock(TransactionPool.class); - EthModuleWalletEnabled ethModuleWallet = new EthModuleWalletEnabled(wallet, transactionPoolMock); + EthModuleWalletEnabled ethModuleWallet = new EthModuleWalletEnabled(wallet, transactionPoolMock, signatureCache); ExecutionBlockRetriever retriever = mock(ExecutionBlockRetriever.class); Blockchain blockchain = mock(Blockchain.class); ReversibleTransactionExecutor reversibleTransactionExecutor = mock(ReversibleTransactionExecutor.class); @@ -877,7 +877,7 @@ private Transaction createMockTransaction(String fromAddress) { Transaction transaction = mock(Transaction.class); RskAddress address = new RskAddress(fromAddress); System.out.println("mock address: " + address); - when(transaction.getSender()).thenReturn(address); + when(transaction.getSender(any(SignatureCache.class))).thenReturn(address); byte[] mockHashBytes = new byte[32]; Arrays.fill(mockHashBytes, (byte) 1); diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java index d9cc47dc524..6afe3b19df5 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplLogsTest.java @@ -1092,7 +1092,7 @@ private Web3Impl createWeb3() { EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockChain, transactionPool, null, new ExecutionBlockRetriever(blockChain, null, null), - null, new EthModuleWalletEnabled(wallet, transactionPool), null, + null, new EthModuleWalletEnabled(wallet, transactionPool, signatureCache), null, new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), new BlockTxSignatureCache(new ReceivedTxSignatureCache())), config.getGasEstimationCap(), diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplScoringTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplScoringTest.java index 76260141ec2..a31a8fc3af0 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplScoringTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplScoringTest.java @@ -393,7 +393,7 @@ private static Web3Impl createWeb3(PeerScoringManager peerScoringManager) { EthModule em = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), world.getBlockChain(), null, null, new ExecutionBlockRetriever(world.getBlockChain(), null, null), - null, new EthModuleWalletEnabled(wallet, world.getTransactionPool()), null, + null, new EthModuleWalletEnabled(wallet, world.getTransactionPool(), world.getBlockTxSignatureCache()), null, new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), new BlockTxSignatureCache(new ReceivedTxSignatureCache())), config.getGasEstimationCap(), diff --git a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java index b19d2cf8f2c..93972addb83 100644 --- a/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java +++ b/rskj-core/src/test/java/org/ethereum/rpc/Web3ImplTest.java @@ -2712,7 +2712,7 @@ private Web3Impl createWeb3(SimpleEthereum eth, PeerServer peerServer) { EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockchain, transactionPool, null, new ExecutionBlockRetriever(blockchain, null, null), - null, new EthModuleWalletEnabled(wallet, transactionPool), null, + null, new EthModuleWalletEnabled(wallet, transactionPool, signatureCache), null, new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), signatureCache), config.getGasEstimationCap(), @@ -2829,7 +2829,7 @@ private Web3Impl createWeb3( TransactionGateway transactionGateway = new TransactionGateway(new SimpleChannelManager(), transactionPool); EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockchain, transactionPool, executor, - new ExecutionBlockRetriever(blockchain, null, null), repositoryLocator, new EthModuleWalletEnabled(wallet, transactionPool), + new ExecutionBlockRetriever(blockchain, null, null), repositoryLocator, new EthModuleWalletEnabled(wallet, transactionPool, signatureCache), new EthModuleTransactionBase(config.getNetworkConstants(), wallet, transactionPool, transactionGateway), new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), signatureCache), @@ -2893,7 +2893,7 @@ private Web3Impl createWeb3CallNoReturn( EthModule ethModule = new EthModule( config.getNetworkConstants().getBridgeConstants(), config.getNetworkConstants().getChainId(), blockchain, transactionPool, executor, new ExecutionBlockRetriever(blockchain, null, null), repositoryLocator, - new EthModuleWalletEnabled(wallet, transactionPool), + new EthModuleWalletEnabled(wallet, transactionPool, signatureCache), new EthModuleTransactionBase(config.getNetworkConstants(), wallet, transactionPool, null), new BridgeSupportFactory( null, config.getNetworkConstants().getBridgeConstants(), config.getActivationConfig(), signatureCache), From 4683a65a0b1fe233d7f7b542b5b2af0763417936 Mon Sep 17 00:00:00 2001 From: fmacleal Date: Tue, 6 Feb 2024 00:30:16 +0100 Subject: [PATCH 137/137] Fix from jmh benchmark Fixing EthCallPlan to add gasLimit to the request Refactoring of branch to merge it to master In order to fix the jmh benchmarking test, we need to refactor and remove some changes made to run test locally. --- .../jmh/web3/BenchmarkLocalWalletWeb3.java | 4 +-- .../java/co/rsk/jmh/web3/BenchmarkWeb3.java | 2 +- .../co/rsk/jmh/web3/plan/EthCallPlan.java | 30 +++++-------------- ...aWalletlPlan.java => LocalWalletPlan.java} | 2 +- .../jmh/resources/conf/testnet-3_860_000.conf | 1 + 5 files changed, 12 insertions(+), 27 deletions(-) rename rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/{LocaWalletlPlan.java => LocalWalletPlan.java} (97%) diff --git a/rskj-core/src/jmh/java/co/rsk/jmh/web3/BenchmarkLocalWalletWeb3.java b/rskj-core/src/jmh/java/co/rsk/jmh/web3/BenchmarkLocalWalletWeb3.java index 6d5b0fa6bdb..8425156b6cd 100644 --- a/rskj-core/src/jmh/java/co/rsk/jmh/web3/BenchmarkLocalWalletWeb3.java +++ b/rskj-core/src/jmh/java/co/rsk/jmh/web3/BenchmarkLocalWalletWeb3.java @@ -18,7 +18,7 @@ package co.rsk.jmh.web3; -import co.rsk.jmh.web3.plan.LocaWalletlPlan; +import co.rsk.jmh.web3.plan.LocalWalletPlan; import co.rsk.jmh.web3.plan.TransactionPlan; import org.openjdk.jmh.annotations.*; import org.web3j.protocol.core.methods.request.Transaction; @@ -57,7 +57,7 @@ public void ethSendTransaction_ContractCall(TransactionPlan plan) throws Benchma } @Benchmark - public void ethSign(LocaWalletlPlan plan) throws BenchmarkWeb3Exception { + public void ethSign(LocalWalletPlan plan) throws BenchmarkWeb3Exception { String address = plan.getEthSignAddress(); String message = plan.getEthSignMessage(); plan.getWeb3Connector().ethSign(address, message); diff --git a/rskj-core/src/jmh/java/co/rsk/jmh/web3/BenchmarkWeb3.java b/rskj-core/src/jmh/java/co/rsk/jmh/web3/BenchmarkWeb3.java index 729c14c4ea5..d3e722a02c8 100644 --- a/rskj-core/src/jmh/java/co/rsk/jmh/web3/BenchmarkWeb3.java +++ b/rskj-core/src/jmh/java/co/rsk/jmh/web3/BenchmarkWeb3.java @@ -198,7 +198,7 @@ public void traceFilterBetweenBlockRange(TracePlan plan) throws BenchmarkWeb3Exc } @Benchmark - @Timeout(time = 60) + @Timeout(time = 100) public void traceFilterBetweenAddresses(TracePlan plan) throws BenchmarkWeb3Exception { plan.getWeb3Connector().traceFilter(plan.getFromBlock(), plan.getToBlock(), plan.getFromAddresses(), plan.getToAddresses()); } diff --git a/rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/EthCallPlan.java b/rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/EthCallPlan.java index 76cd809a0c9..56144da0940 100644 --- a/rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/EthCallPlan.java +++ b/rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/EthCallPlan.java @@ -18,16 +18,13 @@ package co.rsk.jmh.web3.plan; -import co.rsk.jmh.helpers.BenchmarkHelper; import co.rsk.jmh.web3.BenchmarkWeb3Exception; import co.rsk.jmh.web3.e2e.RskModuleWeb3j; import org.openjdk.jmh.annotations.Level; import org.openjdk.jmh.annotations.Scope; import org.openjdk.jmh.annotations.Setup; import org.openjdk.jmh.annotations.State; -import org.openjdk.jmh.annotations.TearDown; import org.openjdk.jmh.infra.BenchmarkParams; -import org.web3j.protocol.core.methods.response.Transaction; import java.math.BigInteger; @@ -44,29 +41,16 @@ public void setUp(BenchmarkParams params) throws BenchmarkWeb3Exception { ethCallArguments = buildEthCallArguments(); } - private Transaction setupTransaction() { - Transaction tx = new Transaction(); - - tx.setFrom(configuration.getString("eth_call.transaction.from")); - tx.setTo(configuration.getString("eth_call.transaction.to")); - tx.setGas(configuration.getString("eth_call.transaction.gas")); - tx.setGasPrice(configuration.getString("eth_call.transaction.gasPrice")); - tx.setValue(configuration.getString("eth_call.transaction.value")); - tx.setInput(configuration.getString("eth_call.transaction.input")); - - return tx; - } - private RskModuleWeb3j.EthCallArguments buildEthCallArguments() { RskModuleWeb3j.EthCallArguments args = new RskModuleWeb3j.EthCallArguments(); - Transaction tx = setupTransaction(); - args.setFrom(tx.getFrom()); - args.setTo(tx.getTo()); - args.setGas("0x" + tx.getGas().toString(16)); - args.setGasPrice("0x" + tx.getGasPrice().toString(16)); - args.setValue("0x" + tx.getValue().toString(16)); - args.setData(tx.getInput()); + args.setGasLimit(configuration.getString("eth_call.gasLimit")); + args.setFrom(configuration.getString("eth_call.transaction.from")); + args.setTo(configuration.getString("eth_call.transaction.to")); + args.setGas(configuration.getString("eth_call.transaction.gas")); + args.setGasPrice(configuration.getString("eth_call.transaction.gasPrice")); + args.setValue(configuration.getString("eth_call.transaction.value")); + args.setData(configuration.getString("eth_call.transaction.input")); return args; } diff --git a/rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/LocaWalletlPlan.java b/rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/LocalWalletPlan.java similarity index 97% rename from rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/LocaWalletlPlan.java rename to rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/LocalWalletPlan.java index 7e34b60e4e7..8d87749530f 100644 --- a/rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/LocaWalletlPlan.java +++ b/rskj-core/src/jmh/java/co/rsk/jmh/web3/plan/LocalWalletPlan.java @@ -26,7 +26,7 @@ import org.openjdk.jmh.infra.BenchmarkParams; @State(Scope.Benchmark) -public class LocaWalletlPlan extends BasePlan{ +public class LocalWalletPlan extends BasePlan{ public static final String ETH_SIGN_ADDRESS = "ethSign.address"; public static final String ETH_SIGN_MESSAGE = "ethSign.message"; diff --git a/rskj-core/src/jmh/resources/conf/testnet-3_860_000.conf b/rskj-core/src/jmh/resources/conf/testnet-3_860_000.conf index 444e0c1ec0a..46a249de586 100644 --- a/rskj-core/src/jmh/resources/conf/testnet-3_860_000.conf +++ b/rskj-core/src/jmh/resources/conf/testnet-3_860_000.conf @@ -69,6 +69,7 @@ trace.fromAddresses=0x0000000000000000000000000000000000000000 ############################ # eth_call ############################ +eth_call.gasLimit=0x4e252e0 eth_call.transaction.blockNumber=0x362193 eth_call.transaction.from=0x4a727d7943b563462c96d40689836600d20b983b eth_call.transaction.to=0x19f64674d8a5b4e652319f5e239efd3bc969a1fe