From 1a98ed627cfd1a7195f4d872398b3adebebaa2b5 Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 27 Aug 2024 11:40:28 -0300 Subject: [PATCH 01/17] Add RSKIP427 activation code --- .../blockchain/upgrades/ConsensusRule.java | 3 +- rskj-core/src/main/resources/expected.conf | 1 + rskj-core/src/main/resources/reference.conf | 1 + .../upgrades/ActivationConfigTest.java | 220 +++++++++--------- .../upgrades/ActivationConfigsForTest.java | 57 ++--- 5 files changed, 128 insertions(+), 154 deletions(-) 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 dae0a171212..014229ac9f4 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 @@ -95,12 +95,13 @@ public enum ConsensusRule { RSKIP412("rskip412"), // From EIP-3198 BASEFEE opcode RSKIP415("rskip415"), RSKIP417("rskip417"), + RSKIP427("rskip427"), RSKIP428("rskip428"), RSKIP434("rskip434"), RSKIP438("rskip438") ; - private String configKey; + private final String configKey; ConsensusRule(String configKey) { this.configKey = configKey; diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index 5ed4c5d4d1d..6dc5b16c5c5 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -96,6 +96,7 @@ blockchain = { rskip412 = rskip415 = rskip417 = + rskip427 = rskip428 = rskip434 = rskip438 = diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index 9b108e40fc7..a7d71a2b4db 100644 --- a/rskj-core/src/main/resources/reference.conf +++ b/rskj-core/src/main/resources/reference.conf @@ -81,6 +81,7 @@ blockchain = { rskip412 = arrowhead600 rskip415 = arrowhead600 rskip417 = arrowhead600 + rskip427 = lovell700 rskip428 = lovell700 rskip434 = arrowhead631 rskip438 = lovell700 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 167d30f3f8b..d94e90569ce 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 @@ -18,115 +18,115 @@ package org.ethereum.config.blockchain.upgrades; -import com.typesafe.config.Config; -import com.typesafe.config.ConfigFactory; -import com.typesafe.config.ConfigValueFactory; +import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import com.typesafe.config.*; import org.hamcrest.MatcherAssert; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -import static org.hamcrest.Matchers.is; - class ActivationConfigTest { private static final Config BASE_CONFIG = ConfigFactory.parseString(String.join("\n", - "hardforkActivationHeights: {", - " genesis: 0", - " bahamas: 0", - " afterBridgeSync: 0,", - " orchid: 0,", - " orchid060: 0,", - " wasabi100: 0", - " papyrus200: 0", - " twoToThree: 0", - " iris300: 0", - " hop400: 0", - " hop401: 0", - " fingerroot500: 0", - " arrowhead600: 0", - " arrowhead631: 0", - " lovell700: 0", - "},", - "consensusRules: {", - " areBridgeTxsPaid: afterBridgeSync,", - " rskip85: orchid,", - " rskip87: orchid,", - " rskip88: orchid,", - " rskip89: orchid,", - " rskip90: orchid,", - " rskip91: orchid,", - " rskip92: orchid,", - " rskip97: orchid,", - " rskip98: orchid,", - " rskip103: orchid060,", - " rskip106: wasabi100,", - " rskip110: wasabi100,", - " rskip119: wasabi100,", - " rskip120: wasabi100,", - " rskip122: wasabi100,", - " rskip123: wasabi100,", - " rskip124: wasabi100,", - " rskip125: wasabi100", - " rskip126: wasabi100", - " rskip132: wasabi100", - " rskip134: papyrus200", - " rskip136: bahamas", - " rskip137: papyrus200", - " rskip140: papyrus200,", - " rskip143: papyrus200", - " rskip146: papyrus200", - " rskip150: twoToThree", - " rskip151: papyrus200", - " rskip152: papyrus200", - " rskip156: papyrus200", - " rskipUMM: papyrus200", - " rskip153: iris300", - " rskip169: iris300", - " rskip170: iris300", - " rskip171: iris300", - " rskip174: iris300", - " rskip176: iris300", - " rskip179: iris300", - " rskip180: iris300", - " rskip181: iris300", - " rskip185: iris300", - " rskip186: iris300", - " rskip191: iris300", - " rskip197: iris300", - " rskip199: iris300", - " rskip200: iris300", - " rskip201: iris300", - " rskip203: arrowhead600", - " rskip218: iris300", - " rskip219: iris300", - " rskip220: iris300", - " rskip252: fingerroot500", - " rskip271: hop400", - " rskip284: hop400", - " rskip290: hop400", - " rskip293: hop400", - " rskip294: hop400", - " rskip144: arrowhead600", - " rskip297: hop400", - " rskip351: arrowhead600", - " rskip326: fingerroot500", - " rskip353: hop401", - " rskip357: hop401", - " rskip374: fingerroot500", - " rskip375: fingerroot500", - " rskip376: arrowhead600", - " rskip377: fingerroot500", - " rskip379: arrowhead600", - " rskip383: fingerroot500", - " rskip385: fingerroot500", - " rskip398: arrowhead600", - " rskip400: arrowhead600", - " rskip412: arrowhead600", - " rskip415: arrowhead600", - " rskip417: arrowhead600", - " rskip434: arrowhead631", - " rskip428: lovell700", - " rskip438: lovell700", - "}" + "hardforkActivationHeights: {", + " genesis: 0", + " bahamas: 0", + " afterBridgeSync: 0,", + " orchid: 0,", + " orchid060: 0,", + " wasabi100: 0", + " papyrus200: 0", + " twoToThree: 0", + " iris300: 0", + " hop400: 0", + " hop401: 0", + " fingerroot500: 0", + " arrowhead600: 0", + " arrowhead631: 0", + " lovell700: 0", + "},", + "consensusRules: {", + " areBridgeTxsPaid: afterBridgeSync,", + " rskip85: orchid,", + " rskip87: orchid,", + " rskip88: orchid,", + " rskip89: orchid,", + " rskip90: orchid,", + " rskip91: orchid,", + " rskip92: orchid,", + " rskip97: orchid,", + " rskip98: orchid,", + " rskip103: orchid060,", + " rskip106: wasabi100,", + " rskip110: wasabi100,", + " rskip119: wasabi100,", + " rskip120: wasabi100,", + " rskip122: wasabi100,", + " rskip123: wasabi100,", + " rskip124: wasabi100,", + " rskip125: wasabi100", + " rskip126: wasabi100", + " rskip132: wasabi100", + " rskip134: papyrus200", + " rskip136: bahamas", + " rskip137: papyrus200", + " rskip140: papyrus200,", + " rskip143: papyrus200", + " rskip144: arrowhead600", + " rskip146: papyrus200", + " rskip150: twoToThree", + " rskip151: papyrus200", + " rskip152: papyrus200", + " rskip156: papyrus200", + " rskipUMM: papyrus200", + " rskip153: iris300", + " rskip169: iris300", + " rskip170: iris300", + " rskip171: iris300", + " rskip174: iris300", + " rskip176: iris300", + " rskip179: iris300", + " rskip180: iris300", + " rskip181: iris300", + " rskip185: iris300", + " rskip186: iris300", + " rskip191: iris300", + " rskip197: iris300", + " rskip199: iris300", + " rskip200: iris300", + " rskip201: iris300", + " rskip203: arrowhead600", + " rskip218: iris300", + " rskip219: iris300", + " rskip220: iris300", + " rskip252: fingerroot500", + " rskip271: hop400", + " rskip284: hop400", + " rskip290: hop400", + " rskip293: hop400", + " rskip294: hop400", + " rskip297: hop400", + " rskip326: fingerroot500", + " rskip351: arrowhead600", + " rskip353: hop401", + " rskip357: hop401", + " rskip374: fingerroot500", + " rskip375: fingerroot500", + " rskip376: arrowhead600", + " rskip377: fingerroot500", + " rskip379: arrowhead600", + " rskip383: fingerroot500", + " rskip385: fingerroot500", + " rskip398: arrowhead600", + " rskip400: arrowhead600", + " rskip412: arrowhead600", + " rskip415: arrowhead600", + " rskip417: arrowhead600", + " rskip427: lovell700", + " rskip428: lovell700", + " rskip434: arrowhead631", + " rskip438: lovell700", + "}" )); @Test @@ -172,36 +172,36 @@ void readWithOneHardcodedActivationNumber() { @Test void failsReadingWithMissingNetworkUpgrade() { Config config = BASE_CONFIG.withoutPath("consensusRules.rskip85"); - Assertions.assertThrows(IllegalArgumentException.class, () -> ActivationConfig.read(config)); + assertThrows(IllegalArgumentException.class, () -> ActivationConfig.read(config)); } @Test void failsReadingWithMissingHardFork() { Config config = BASE_CONFIG.withoutPath("hardforkActivationHeights.orchid"); - Assertions.assertThrows(IllegalArgumentException.class, () -> ActivationConfig.read(config)); + assertThrows(IllegalArgumentException.class, () -> ActivationConfig.read(config)); } @Test void failsReadingWithUnknownForkConfiguration() { Config config = BASE_CONFIG.withValue("hardforkActivationHeights.orkid", ConfigValueFactory.fromAnyRef(200)); - Assertions.assertThrows(IllegalArgumentException.class, () -> ActivationConfig.read(config)); + assertThrows(IllegalArgumentException.class, () -> ActivationConfig.read(config)); } @Test void failsReadingWithUnknownUpgradeConfiguration() { Config config = BASE_CONFIG.withValue("consensusRules.rskip420", ConfigValueFactory.fromAnyRef("orchid")); - Assertions.assertThrows(IllegalArgumentException.class, () -> ActivationConfig.read(config)); + assertThrows(IllegalArgumentException.class, () -> ActivationConfig.read(config)); } @Test void headerVersion0() { ActivationConfig config = ActivationConfigsForTest.allBut(ConsensusRule.RSKIP351); - Assertions.assertEquals((byte) 0x0, config.getHeaderVersion(10)); + assertEquals((byte) 0x0, config.getHeaderVersion(10)); } @Test void headerVersion1() { ActivationConfig config = ActivationConfigsForTest.all(); - Assertions.assertEquals((byte) 0x1, config.getHeaderVersion(10)); + assertEquals((byte) 0x1, config.getHeaderVersion(10)); } } 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 889f5db90cf..4aab321e760 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 @@ -19,12 +19,11 @@ package org.ethereum.config.blockchain.upgrades; import com.typesafe.config.ConfigFactory; -import org.ethereum.config.SystemProperties; - -import javax.annotation.Nullable; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.ethereum.config.SystemProperties; @SuppressWarnings({"squid:S2187"}) // used from another class public class ActivationConfigsForTest { @@ -32,12 +31,11 @@ public class ActivationConfigsForTest { private static final ActivationConfig REGTEST = read("config/regtest"); private static List getPaidBridgeTxsRskip() { - return Arrays.asList(ConsensusRule.ARE_BRIDGE_TXS_PAID); + return Collections.singletonList(ConsensusRule.ARE_BRIDGE_TXS_PAID); } private static List getOrchidRskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( ConsensusRule.RSKIP85, ConsensusRule.RSKIP87, ConsensusRule.RSKIP88, @@ -48,8 +46,6 @@ private static List getOrchidRskips() { ConsensusRule.RSKIP97, ConsensusRule.RSKIP98 )); - - return rskips; } private static List getOrchid060Rskips() { @@ -60,8 +56,7 @@ private static List getOrchid060Rskips() { } private static List getWasabi100Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( ConsensusRule.RSKIP103, ConsensusRule.RSKIP106, ConsensusRule.RSKIP110, @@ -74,8 +69,6 @@ private static List getWasabi100Rskips() { ConsensusRule.RSKIP126, ConsensusRule.RSKIP132 )); - - return rskips; } private static List getBahamasRskips() { @@ -93,8 +86,7 @@ private static List getTwoToThreeRskips() { } private static List getPapyrus200Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( ConsensusRule.RSKIP134, ConsensusRule.RSKIP137, ConsensusRule.RSKIP140, @@ -106,13 +98,10 @@ private static List getPapyrus200Rskips() { ConsensusRule.RSKIP156, ConsensusRule.RSKIPUMM )); - - return rskips; } private static List getIris300Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( ConsensusRule.RSKIP153, ConsensusRule.RSKIP169, ConsensusRule.RSKIP170, @@ -133,13 +122,10 @@ private static List getIris300Rskips() { ConsensusRule.RSKIP219, ConsensusRule.RSKIP220 )); - - return rskips; } private static List getHop400Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( ConsensusRule.RSKIP271, ConsensusRule.RSKIP284, ConsensusRule.RSKIP290, @@ -147,23 +133,17 @@ private static List getHop400Rskips() { ConsensusRule.RSKIP294, ConsensusRule.RSKIP297 )); - - return rskips; } private static List getHop401Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( ConsensusRule.RSKIP353, ConsensusRule.RSKIP357 )); - - return rskips; } private static List getFingerroot500Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( ConsensusRule.RSKIP252, ConsensusRule.RSKIP326, ConsensusRule.RSKIP374, @@ -172,13 +152,10 @@ private static List getFingerroot500Rskips() { ConsensusRule.RSKIP383, ConsensusRule.RSKIP385 )); - - return rskips; } private static List getArrowhead600Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( ConsensusRule.RSKIP203, ConsensusRule.RSKIP376, ConsensusRule.RSKIP379, @@ -189,25 +166,19 @@ private static List getArrowhead600Rskips() { ConsensusRule.RSKIP144, ConsensusRule.RSKIP351 )); - - return rskips; } private static List getArrowhead631Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Collections.singletonList( + return new ArrayList<>(Collections.singletonList( ConsensusRule.RSKIP434 )); - - return rskips; } private static List getLovell700Rskips() { - List rskips = new ArrayList<>(); - rskips.addAll(Arrays.asList( + return new ArrayList<>(Arrays.asList( + ConsensusRule.RSKIP427, ConsensusRule.RSKIP428 )); - return rskips; } public static ActivationConfig genesis() { From 1ed44ecb227dfa1d81e29dbf0f4063a9c7b1e1df Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 27 Aug 2024 12:21:37 -0300 Subject: [PATCH 02/17] Change signature in BridgeEventLogger to receive RskAddress object instead of String --- .../main/java/co/rsk/peg/BridgeEvents.java | 10 +- .../main/java/co/rsk/peg/BridgeSupport.java | 2 +- .../co/rsk/peg/utils/BridgeEventLogger.java | 2 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 4 +- .../rsk/peg/BridgeSupportReleaseBtcTest.java | 100 +++++++++--------- .../peg/utils/BridgeEventLoggerImplTest.java | 2 +- .../rsk/peg/utils/BridgeEventLoggerTest.java | 96 +++++++++-------- 7 files changed, 114 insertions(+), 102 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeEvents.java b/rskj-core/src/main/java/co/rsk/peg/BridgeEvents.java index 4683068e18c..6ea69bfb988 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeEvents.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeEvents.java @@ -75,11 +75,11 @@ public enum BridgeEvents { } ), RELEASE_REQUEST_REJECTED("release_request_rejected", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)), - new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)), - new CallTransaction.Param(false, Fields.REASON, SolidityType.getType(SolidityType.INT256)) - } + new CallTransaction.Param[]{ + new CallTransaction.Param(true, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)), + new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)), + new CallTransaction.Param(false, Fields.REASON, SolidityType.getType(SolidityType.INT256)) + } ), BATCH_PEGOUT_CREATED("batch_pegout_created", new CallTransaction.Param[]{ 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 2bb9323ddf8..8f1b8d1fc5f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -856,7 +856,7 @@ private void refundAndEmitRejectEvent(Coin value, RskAddress senderAddress, Reje } private void emitRejectEvent(Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { - eventLogger.logReleaseBtcRequestRejected(senderAddress.toHexString(), value, reason); + eventLogger.logReleaseBtcRequestRejected(senderAddress, value, reason); } /** 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 6184db4d756..4e83f059aaa 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 @@ -67,7 +67,7 @@ default void logReleaseBtcRequestReceived(String sender, Address btcDestinationA throw new UnsupportedOperationException(); } - default void logReleaseBtcRequestRejected(String sender, Coin amount, RejectedPegoutReason reason) { + default void logReleaseBtcRequestRejected(RskAddress sender, Coin amount, RejectedPegoutReason reason) { throw new UnsupportedOperationException(); } 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 b5ead3941e8..08a5bde82fb 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 @@ -219,9 +219,9 @@ private void logReleaseBtcRequestReceived(String sender, String btcDestinationAd } @Override - public void logReleaseBtcRequestRejected(String sender, Coin amount, RejectedPegoutReason reason) { + public void logReleaseBtcRequestRejected(RskAddress sender, Coin amount, RejectedPegoutReason reason) { CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); - byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender); + byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender.toHexString()); List encodedTopics = LogInfo.byteArrayToList(encodedTopicsInBytes); byte[] encodedData = event.encodeEventData(amount.getValue(), reason.getValue()); 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 6628e71992d..7944f00fb3b 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -17,26 +17,33 @@ */ package co.rsk.peg; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.*; + import co.rsk.bitcoinj.core.*; -import co.rsk.peg.constants.BridgeConstants; -import co.rsk.peg.constants.BridgeRegTestConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.db.MutableTrieCache; import co.rsk.db.MutableTrieImpl; import co.rsk.peg.bitcoin.BitcoinTestUtils; +import co.rsk.peg.constants.BridgeConstants; +import co.rsk.peg.constants.BridgeRegTestConstants; import co.rsk.peg.federation.*; import co.rsk.peg.federation.constants.FederationConstants; import co.rsk.peg.feeperkb.FeePerKbSupport; import co.rsk.peg.feeperkb.FeePerKbSupportImpl; import co.rsk.peg.storage.BridgeStorageAccessorImpl; import co.rsk.peg.storage.StorageAccessor; -import co.rsk.peg.utils.BridgeEventLogger; -import co.rsk.peg.utils.BridgeEventLoggerImpl; -import co.rsk.peg.utils.RejectedPegoutReason; +import co.rsk.peg.utils.*; import co.rsk.test.builders.BridgeSupportBuilder; import co.rsk.test.builders.FederationSupportBuilder; import co.rsk.trie.Trie; +import java.io.IOException; +import java.math.BigInteger; +import java.time.Instant; +import java.util.*; +import java.util.stream.Collectors; import org.bouncycastle.util.encoders.Hex; import org.ethereum.TestUtils; import org.ethereum.config.Constants; @@ -51,30 +58,10 @@ import org.ethereum.vm.PrecompiledContracts; import org.ethereum.vm.program.InternalTransaction; import org.ethereum.vm.program.Program; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertInstanceOf; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.fail; 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.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.*; - class BridgeSupportReleaseBtcTest { - private static final String TO_ADDRESS = "0000000000000000000000000000000000000006"; private static final BigInteger DUST_AMOUNT = new BigInteger("1"); private static final BigInteger NONCE = new BigInteger("0"); @@ -82,6 +69,7 @@ class BridgeSupportReleaseBtcTest { private static final BigInteger GAS_LIMIT = new BigInteger("1000"); private static final String DATA = "80af2871"; private static final ECKey SENDER = new ECKey(); + private static final RskAddress BRIDGE_ADDRESS = PrecompiledContracts.BRIDGE_ADDR; private BridgeConstants bridgeConstants; private FederationConstants federationConstants; @@ -1172,7 +1160,12 @@ private void testPegoutMinimumWithFeeVerificationPass(Coin feePerKB, Coin value) when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(true); List logInfo = new ArrayList<>(); - eventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); + eventLogger = spy(new BridgeEventLoggerImpl( + bridgeConstants, + activationMock, + logInfo, + signatureCache + )); bridgeSupport = initBridgeSupport(eventLogger, activationMock); when(feePerKbSupport.getFeePerKb()).thenReturn(feePerKB); @@ -1197,20 +1190,23 @@ private void testPegoutMinimumWithFeeVerificationPass(Coin feePerKB, Coin value) verify(eventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); } - private void testPegoutMinimumWithFeeVerificationRejectedByLowAmount(Coin feePerKB, Coin value) - throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(true); - - RskAddress bridgeAddress = PrecompiledContracts.BRIDGE_ADDR; + private void testPegoutMinimumWithFeeVerificationRejectedByLowAmount(Coin feePerKB, Coin value) throws IOException { + ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0); List logInfo = new ArrayList<>(); - eventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); + eventLogger = spy(new BridgeEventLoggerImpl( + bridgeConstants, + activationMock, + logInfo, + signatureCache + )); bridgeSupport = initBridgeSupport(eventLogger, activationMock); when(feePerKbSupport.getFeePerKb()).thenReturn(feePerKB); - int pegoutSize = BridgeUtils.getRegularPegoutTxSize(activationMock, federationStorageProvider.getNewFederation(federationConstants, activationMock)); + int pegoutSize = BridgeUtils.getRegularPegoutTxSize( + irisActivations, + federationStorageProvider.getNewFederation(federationConstants, irisActivations) + ); Coin minValueAccordingToFee = feePerKbSupport.getFeePerKb().div(1000).times(pegoutSize); Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times(bridgeConstants.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100)); @@ -1225,7 +1221,7 @@ private void testPegoutMinimumWithFeeVerificationRejectedByLowAmount(Coin feePer co.rsk.core.Coin coin = co.rsk.core.Coin.fromBitcoin(value); - verify(repository, times(1)).transfer(bridgeAddress, senderAddress, coin); + verify(repository, times(1)).transfer(BRIDGE_ADDRESS, senderAddress, coin); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); @@ -1233,25 +1229,31 @@ private void testPegoutMinimumWithFeeVerificationRejectedByLowAmount(Coin feePer verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); - verify(eventLogger, times(1)) - .logReleaseBtcRequestRejected(senderAddress.toHexString(), value, RejectedPegoutReason.LOW_AMOUNT); + verify(eventLogger, times(1)).logReleaseBtcRequestRejected( + senderAddress, + value, + RejectedPegoutReason.LOW_AMOUNT + ); } - private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(Coin feePerKB, Coin value) - throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(true); - - RskAddress bridgeAddress = PrecompiledContracts.BRIDGE_ADDR; + private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(Coin feePerKB, Coin value) throws IOException { + ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0); List logInfo = new ArrayList<>(); - eventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); + eventLogger = spy(new BridgeEventLoggerImpl( + bridgeConstants, + activationMock, + logInfo, + signatureCache + )); bridgeSupport = initBridgeSupport(eventLogger, activationMock); when(feePerKbSupport.getFeePerKb()).thenReturn(feePerKB); - int pegoutSize = BridgeUtils.getRegularPegoutTxSize(activationMock, federationStorageProvider.getNewFederation(federationConstants, activationMock)); + int pegoutSize = BridgeUtils.getRegularPegoutTxSize( + irisActivations, + federationStorageProvider.getNewFederation(federationConstants, irisActivations) + ); Coin minValueAccordingToFee = feePerKbSupport.getFeePerKb().div(1000).times(pegoutSize); Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times(bridgeConstants.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100)); @@ -1266,7 +1268,7 @@ private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(Coin fe co.rsk.core.Coin coin = co.rsk.core.Coin.fromBitcoin(value); - verify(repository, times(1)).transfer(bridgeAddress, senderAddress, coin); + verify(repository, times(1)).transfer(BRIDGE_ADDRESS, senderAddress, coin); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); @@ -1275,7 +1277,7 @@ private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(Coin fe verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); verify(eventLogger, times(1)).logReleaseBtcRequestRejected( - senderAddress.toHexString(), + senderAddress, value, RejectedPegoutReason.FEE_ABOVE_VALUE ); 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 bff03605651..7d73247207e 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 @@ -462,7 +462,7 @@ void testLogReleaseBtcRequestRejected() { Coin amount = Coin.COIN; RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; - eventLogger.logReleaseBtcRequestRejected(RSK_ADDRESS.toString(), amount, reason); + eventLogger.logReleaseBtcRequestRejected(RSK_ADDRESS, amount, reason); commonAssertLogs(eventLogs); assertTopics(2, eventLogs); diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java index 4fdc3281252..5e0417a683f 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java @@ -1,25 +1,19 @@ package co.rsk.peg.utils; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; + import co.rsk.bitcoinj.core.*; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.PegTestUtils; - -import static org.junit.jupiter.api.Assertions.*; - import co.rsk.peg.pegin.RejectedPeginReason; -import java.util.Arrays; +import java.util.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.List; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; - class BridgeEventLoggerTest { - private BridgeEventLogger eventLogger; private BtcTransaction btcTxMock; private Keccak256 rskTxHash; @@ -33,40 +27,48 @@ void setup() { @Test void testLogLockBtc() { - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logLockBtc(mock(RskAddress.class), btcTxMock, mock(Address.class), - Coin.SATOSHI); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logLockBtc( + mock(RskAddress.class), + btcTxMock, + mock(Address.class), + Coin.SATOSHI + )); } @Test void testLogPeginBtc() { - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logPeginBtc(mock(RskAddress.class), btcTxMock, Coin.SATOSHI, 1); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logPeginBtc( + mock(RskAddress.class), + btcTxMock, + Coin.SATOSHI, + 1 + )); } @Test void testLogReleaseBtcRequested() { byte[] rskTxHashBytes = rskTxHash.getBytes(); - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logReleaseBtcRequested(rskTxHashBytes, btcTxMock, Coin.SATOSHI); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logReleaseBtcRequested( + rskTxHashBytes, + btcTxMock, + Coin.SATOSHI + )); } @Test void testLogRejectedPegin() { - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logRejectedPegin(btcTxMock, RejectedPeginReason.PEGIN_CAP_SURPASSED); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logRejectedPegin( + btcTxMock, + RejectedPeginReason.PEGIN_CAP_SURPASSED + )); } @Test void testLogUnrefundablePegin() { - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logUnrefundablePegin(btcTxMock, - UnrefundablePeginReason.LEGACY_PEGIN_UNDETERMINED_SENDER); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logUnrefundablePegin( + btcTxMock, + UnrefundablePeginReason.LEGACY_PEGIN_UNDETERMINED_SENDER + )); } @Test @@ -76,43 +78,51 @@ void testLogReleaseBtcRequestReceived() { Address btcDestinationAddress = Address.fromBase58( NetworkParameters.fromID(NetworkParameters.ID_REGTEST), base58Address); Coin amount = Coin.COIN; - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logReleaseBtcRequestReceived(sender, btcDestinationAddress, amount); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logReleaseBtcRequestReceived( + sender, + btcDestinationAddress, + amount + )); } @Test void testLogReleaseBtcRequestRejected() { - String sender = "0x00000000000000000000000000000000000000"; + RskAddress sender = new RskAddress("0x0000000000000000000000000000000000000000"); Coin amount = Coin.COIN; RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logReleaseBtcRequestRejected(sender, amount, reason); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logReleaseBtcRequestRejected( + sender, + amount, + reason + )); } @Test void logBatchPegoutCreated() { Sha256Hash btcTxHash = btcTxMock.getHash(); List rskTxHashes = new ArrayList<>(); - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logBatchPegoutCreated(btcTxHash, rskTxHashes); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logBatchPegoutCreated( + btcTxHash, + rskTxHashes + )); } @Test void logPegoutConfirmed() { Sha256Hash btcTxHash = btcTxMock.getHash(); - assertThrows(UnsupportedOperationException.class, () -> { - eventLogger.logPegoutConfirmed(btcTxHash, 5); - }); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logPegoutConfirmed( + btcTxHash, + 5 + )); } @Test void logPegoutTransactionCreated() { Sha256Hash btcTxHash = btcTxMock.getHash(); List outpointValues = Arrays.asList(Coin.COIN, Coin.SATOSHI, Coin.FIFTY_COINS); - assertThrows(UnsupportedOperationException.class, - () -> eventLogger.logPegoutTransactionCreated(btcTxHash, outpointValues)); + assertThrows(UnsupportedOperationException.class, () -> eventLogger.logPegoutTransactionCreated( + btcTxHash, + outpointValues + )); } } From f86c46f9e8413047dec5ebb1fc36c0abd77445e5 Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 3 Sep 2024 16:24:17 -0300 Subject: [PATCH 03/17] Change logReleaseBtcRequestRejected to receive a co.rsk.core.Coin --- .../co/rsk/peg/utils/BridgeEventLogger.java | 2 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 31 ++++++++++--------- .../rsk/peg/utils/BridgeEventLoggerTest.java | 4 +-- 3 files changed, 19 insertions(+), 18 deletions(-) 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 4e83f059aaa..3df8ef6c255 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 @@ -67,7 +67,7 @@ default void logReleaseBtcRequestReceived(String sender, Address btcDestinationA throw new UnsupportedOperationException(); } - default void logReleaseBtcRequestRejected(RskAddress sender, Coin amount, RejectedPegoutReason reason) { + default void logReleaseBtcRequestRejected(RskAddress sender, co.rsk.core.Coin amount, RejectedPegoutReason reason) { throw new UnsupportedOperationException(); } 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 08a5bde82fb..07c9621f4cf 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 @@ -18,30 +18,24 @@ package co.rsk.peg.utils; import co.rsk.bitcoinj.core.*; -import co.rsk.peg.constants.BridgeConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; import co.rsk.peg.BridgeEvents; import co.rsk.peg.bitcoin.UtxoUtils; +import co.rsk.peg.constants.BridgeConstants; import co.rsk.peg.federation.Federation; import co.rsk.peg.federation.FederationMember; import co.rsk.peg.federation.constants.FederationConstants; import co.rsk.peg.pegin.RejectedPeginReason; +import java.util.List; +import java.util.function.Function; +import java.util.stream.Collectors; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; -import org.ethereum.core.Block; -import org.ethereum.core.CallTransaction; -import org.ethereum.core.SignatureCache; -import org.ethereum.core.Transaction; +import org.ethereum.core.*; import org.ethereum.crypto.ECKey; import org.ethereum.util.ByteUtil; -import org.ethereum.vm.DataWord; -import org.ethereum.vm.LogInfo; -import org.ethereum.vm.PrecompiledContracts; - -import java.util.List; -import java.util.function.Function; -import java.util.stream.Collectors; +import org.ethereum.vm.*; /** * Responsible for logging events triggered by BridgeContract. @@ -57,7 +51,12 @@ public class BridgeEventLoggerImpl implements BridgeEventLogger { private final List logs; private final ActivationConfig.ForBlock activations; - public BridgeEventLoggerImpl(BridgeConstants bridgeConstants, ActivationConfig.ForBlock activations, List logs, SignatureCache signatureCache) { + public BridgeEventLoggerImpl( + BridgeConstants bridgeConstants, + ActivationConfig.ForBlock activations, + List logs, + SignatureCache signatureCache) { + this.activations = activations; this.bridgeConstants = bridgeConstants; this.signatureCache = signatureCache; @@ -219,11 +218,13 @@ private void logReleaseBtcRequestReceived(String sender, String btcDestinationAd } @Override - public void logReleaseBtcRequestRejected(RskAddress sender, Coin amount, RejectedPegoutReason reason) { + public void logReleaseBtcRequestRejected(RskAddress sender, co.rsk.core.Coin amount, RejectedPegoutReason reason) { CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender.toHexString()); List encodedTopics = LogInfo.byteArrayToList(encodedTopicsInBytes); - byte[] encodedData = event.encodeEventData(amount.getValue(), reason.getValue()); + byte[] encodedData = activations.isActive(ConsensusRule.RSKIP427) ? + event.encodeEventData(amount.asBigInteger(), reason.getValue()) : + event.encodeEventData(amount.toBitcoin().getValue(), reason.getValue()); this.logs.add(new LogInfo(BRIDGE_CONTRACT_ADDRESS, encodedTopics, encodedData)); } diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java index 5e0417a683f..e66215f7e1a 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java @@ -88,8 +88,8 @@ void testLogReleaseBtcRequestReceived() { @Test void testLogReleaseBtcRequestRejected() { RskAddress sender = new RskAddress("0x0000000000000000000000000000000000000000"); - Coin amount = Coin.COIN; - RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; + co.rsk.core.Coin amount = co.rsk.core.Coin.valueOf(100_000_000L); + RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; // Any reason, just testing the call to the method assertThrows(UnsupportedOperationException.class, () -> eventLogger.logReleaseBtcRequestRejected( sender, amount, From 8616222d1d3635e4f38d17b3d1d915307b8721b4 Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 3 Sep 2024 17:12:41 -0300 Subject: [PATCH 04/17] Test logReleaseBtcRequestRejected pre and post RSKIP427 --- .../peg/utils/BridgeEventLoggerImplTest.java | 29 ++++++++++++++++--- .../rsk/peg/utils/BridgeEventLoggerTest.java | 2 +- 2 files changed, 26 insertions(+), 5 deletions(-) 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 7d73247207e..c76b2a40464 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 @@ -62,7 +62,7 @@ class BridgeEventLoggerImplTest { private static final FederationConstants FEDERATION_CONSTANTS = BRIDGE_CONSTANTS.getFederationConstants(); private static final NetworkParameters NETWORK_PARAMETERS = BRIDGE_CONSTANTS.getBtcParams(); private static final BtcTransaction BTC_TRANSACTION = new BtcTransaction(NETWORK_PARAMETERS); - private static final RskAddress RSK_ADDRESS = new RskAddress("0x0000000000000000000000000000000000000000"); + private static final RskAddress RSK_ADDRESS = new RskAddress("0x0000000000000000000000000000000000000101"); private static final Keccak256 RSK_TX_HASH = RskTestUtils.createHash(1); private List eventLogs; @@ -458,8 +458,29 @@ void testLogReleaseBtcRequestReceivedAfterRSKIP326HardFork() { } @Test - void testLogReleaseBtcRequestRejected() { - Coin amount = Coin.COIN; + void testLogReleaseBtcRequestRejected_preRSKIP427_logAmountAsSatoshis() { + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0); + eventLogger = new BridgeEventLoggerImpl(BRIDGE_CONSTANTS, arrowheadActivations, eventLogs, signatureCache); + + co.rsk.core.Coin amount = co.rsk.core.Coin.valueOf(100_000_000_000_000_000L); + RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; + + eventLogger.logReleaseBtcRequestRejected(RSK_ADDRESS, amount, reason); + + commonAssertLogs(eventLogs); + assertTopics(2, eventLogs); + assertEvent( + eventLogs, + 0, + BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(), + new Object[]{RSK_ADDRESS.toString()}, + new Object[]{amount.toBitcoin().getValue(), reason.getValue()} + ); + } + + @Test + void testLogReleaseBtcRequestRejected_postRSKIP427_logAmountAsWeis() { + co.rsk.core.Coin amount = co.rsk.core.Coin.valueOf(100_000_000_000_000_000L); RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; eventLogger.logReleaseBtcRequestRejected(RSK_ADDRESS, amount, reason); @@ -471,7 +492,7 @@ void testLogReleaseBtcRequestRejected() { 0, BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(), new Object[]{RSK_ADDRESS.toString()}, - new Object[]{amount.value, reason.getValue()} + new Object[]{amount.asBigInteger(), reason.getValue()} ); } diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java index e66215f7e1a..01f913e03e2 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java @@ -88,7 +88,7 @@ void testLogReleaseBtcRequestReceived() { @Test void testLogReleaseBtcRequestRejected() { RskAddress sender = new RskAddress("0x0000000000000000000000000000000000000000"); - co.rsk.core.Coin amount = co.rsk.core.Coin.valueOf(100_000_000L); + co.rsk.core.Coin amount = co.rsk.core.Coin.valueOf(100_000_000_000_000_000L); RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; // Any reason, just testing the call to the method assertThrows(UnsupportedOperationException.class, () -> eventLogger.logReleaseBtcRequestRejected( sender, From e5ba2699a13d48cde6e5777e49261885b518c104 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 16 Sep 2024 12:52:55 -0300 Subject: [PATCH 05/17] Pass weis as the value to be used by release_request_rejected event --- .../main/java/co/rsk/peg/BridgeSupport.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 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 8f1b8d1fc5f..de125926417 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -808,7 +808,6 @@ private void saveNewUTXOs(BtcTransaction btcTx) { */ public void releaseBtc(Transaction rskTx) throws IOException { final co.rsk.core.Coin pegoutValueInWeis = rskTx.getValue(); - final Coin pegoutValueInSatoshis = pegoutValueInWeis.toBitcoin(); final RskAddress senderAddress = rskTx.getSender(signatureCache); logger.debug( "[releaseBtc] Releasing {} weis from RSK address {} in tx {}", @@ -824,7 +823,7 @@ public void releaseBtc(Transaction rskTx) throws IOException { senderAddress ); if (activations.isActive(ConsensusRule.RSKIP185)) { - emitRejectEvent(pegoutValueInSatoshis, senderAddress, RejectedPegoutReason.CALLER_CONTRACT); + emitRejectEvent(pegoutValueInWeis, senderAddress, RejectedPegoutReason.CALLER_CONTRACT); return; } else { String message = "Contract calling releaseBTC"; @@ -837,10 +836,10 @@ public void releaseBtc(Transaction rskTx) throws IOException { Address btcDestinationAddress = BridgeUtils.recoverBtcAddressFromEthTransaction(rskTx, networkParameters); logger.debug("[releaseBtc] BTC destination address: {}", btcDestinationAddress); - requestRelease(btcDestinationAddress, pegoutValueInSatoshis, rskTx); + requestRelease(btcDestinationAddress, pegoutValueInWeis, rskTx); } - private void refundAndEmitRejectEvent(Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { + private void refundAndEmitRejectEvent(co.rsk.core.Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { logger.trace( "[refundAndEmitRejectEvent] Executing a refund of {} to {}. Reason: {}", value, @@ -850,12 +849,12 @@ private void refundAndEmitRejectEvent(Coin value, RskAddress senderAddress, Reje rskRepository.transfer( PrecompiledContracts.BRIDGE_ADDR, senderAddress, - co.rsk.core.Coin.fromBitcoin(value) + value ); emitRejectEvent(value, senderAddress, reason); } - private void emitRejectEvent(Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { + private void emitRejectEvent(co.rsk.core.Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { eventLogger.logReleaseBtcRequestRejected(senderAddress, value, reason); } @@ -865,10 +864,11 @@ private void emitRejectEvent(Coin value, RskAddress senderAddress, RejectedPegou * to be processed later. * * @param destinationAddress the destination BTC address. - * @param value the amount of BTC to release. - * @throws IOException if there's an error while processing the request. + * @param releaseRequestedValue the amount of RBTC requested to be released. + * @throws IOException if there is an error getting the release request queue from storage */ - private void requestRelease(Address destinationAddress, Coin value, Transaction rskTx) throws IOException { + private void requestRelease(Address destinationAddress, co.rsk.core.Coin releaseRequestedValue, Transaction rskTx) throws IOException { + Coin valueToRelease = releaseRequestedValue.toBitcoin(); Optional optionalRejectedPegoutReason = Optional.empty(); if (activations.isActive(RSKIP219)) { int pegoutSize = getRegularPegoutTxSize(activations, getActiveFederation()); @@ -886,11 +886,11 @@ private void requestRelease(Address destinationAddress, Coin value, Transaction .divide(100) ); // add the gap - // The pegout value should be greater or equals than the max of these two values + // The pegout releaseRequestedValue should be greater or equals than the max of these two values Coin minValue = Coin.valueOf(Math.max(bridgeConstants.getMinimumPegoutTxValue().value, requireFundsForFee.value)); // Since Iris the peg-out the rule is that the minimum is inclusive - if (value.isLessThan(minValue)) { + if (valueToRelease.isLessThan(minValue)) { optionalRejectedPegoutReason = Optional.of( Objects.equals(minValue, requireFundsForFee) ? RejectedPegoutReason.FEE_ABOVE_VALUE: @@ -899,7 +899,7 @@ private void requestRelease(Address destinationAddress, Coin value, Transaction } } else { // For legacy peg-outs the rule stated that the minimum was exclusive - if (!value.isGreaterThan(bridgeConstants.getLegacyMinimumPegoutTxValue())) { + if (!valueToRelease.isGreaterThan(bridgeConstants.getLegacyMinimumPegoutTxValue())) { optionalRejectedPegoutReason = Optional.of(RejectedPegoutReason.LOW_AMOUNT); } } @@ -909,27 +909,27 @@ private void requestRelease(Address destinationAddress, Coin value, Transaction "[requestRelease] releaseBtc ignored. To {}. Tx {}. Value {}. Reason: {}", destinationAddress, rskTx, - value, + releaseRequestedValue, optionalRejectedPegoutReason.get() ); if (activations.isActive(ConsensusRule.RSKIP185)) { refundAndEmitRejectEvent( - value, + releaseRequestedValue, rskTx.getSender(signatureCache), optionalRejectedPegoutReason.get() ); } } else { if (activations.isActive(ConsensusRule.RSKIP146)) { - provider.getReleaseRequestQueue().add(destinationAddress, value, rskTx.getHash()); + provider.getReleaseRequestQueue().add(destinationAddress, valueToRelease, rskTx.getHash()); } else { - provider.getReleaseRequestQueue().add(destinationAddress, value); + provider.getReleaseRequestQueue().add(destinationAddress, valueToRelease); } if (activations.isActive(ConsensusRule.RSKIP185)) { - eventLogger.logReleaseBtcRequestReceived(rskTx.getSender(signatureCache).toHexString(), destinationAddress, value); + eventLogger.logReleaseBtcRequestReceived(rskTx.getSender(signatureCache).toHexString(), destinationAddress, valueToRelease); } - logger.info("[requestRelease] releaseBtc successful to {}. Tx {}. Value {}.", destinationAddress, rskTx, value); + logger.info("[requestRelease] releaseBtc successful to {}. Tx {}. Value {}.", destinationAddress, rskTx, releaseRequestedValue); } } From a0aa7be50209e92d928f397ed9ff349c43846a71 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 16 Sep 2024 12:53:16 -0300 Subject: [PATCH 06/17] Refactor BridgeSupportReleaseBtcTest --- .../rsk/peg/BridgeSupportReleaseBtcTest.java | 874 +++++++++--------- 1 file changed, 443 insertions(+), 431 deletions(-) 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 7944f00fb3b..00f40aa87e3 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -28,7 +28,7 @@ import co.rsk.db.MutableTrieImpl; import co.rsk.peg.bitcoin.BitcoinTestUtils; import co.rsk.peg.constants.BridgeConstants; -import co.rsk.peg.constants.BridgeRegTestConstants; +import co.rsk.peg.constants.BridgeMainNetConstants; import co.rsk.peg.federation.*; import co.rsk.peg.federation.constants.FederationConstants; import co.rsk.peg.feeperkb.FeePerKbSupport; @@ -41,7 +41,6 @@ import co.rsk.trie.Trie; import java.io.IOException; import java.math.BigInteger; -import java.time.Instant; import java.util.*; import java.util.stream.Collectors; import org.bouncycastle.util.encoders.Hex; @@ -49,7 +48,6 @@ 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.db.MutableRepository; @@ -62,24 +60,20 @@ import org.junit.jupiter.api.Test; class BridgeSupportReleaseBtcTest { - private static final String TO_ADDRESS = "0000000000000000000000000000000000000006"; - private static final BigInteger DUST_AMOUNT = new BigInteger("1"); private static final BigInteger NONCE = new BigInteger("0"); private static final BigInteger GAS_PRICE = new BigInteger("100"); private static final BigInteger GAS_LIMIT = new BigInteger("1000"); private static final String DATA = "80af2871"; private static final ECKey SENDER = new ECKey(); private static final RskAddress BRIDGE_ADDRESS = PrecompiledContracts.BRIDGE_ADDR; + private static final BridgeConstants BRIDGE_CONSTANTS = BridgeMainNetConstants.getInstance(); + private static final FederationConstants FEDERATION_CONSTANTS = BRIDGE_CONSTANTS.getFederationConstants(); + private static final NetworkParameters NETWORK_PARAMETERS = BRIDGE_CONSTANTS.getBtcParams(); + private static final ActivationConfig.ForBlock ACTIVATIONS_ALL = ActivationConfigsForTest.all().forBlock(0L); - private BridgeConstants bridgeConstants; - private FederationConstants federationConstants; - private NetworkParameters networkParameters; - private ActivationConfig.ForBlock activationsBeforeForks; - private final ActivationConfig.ForBlock activationMock = mock(ActivationConfig.ForBlock.class); private Federation activeFederation; private Repository repository; private BridgeEventLogger eventLogger; - private UTXO utxo; private BridgeStorageProvider provider; private FederationStorageProvider federationStorageProvider; private BridgeSupport bridgeSupport; @@ -91,28 +85,23 @@ class BridgeSupportReleaseBtcTest { @BeforeEach void setUpOnEachTest() { signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); - bridgeConstants = new BridgeRegTestConstants(); - federationConstants = bridgeConstants.getFederationConstants(); - networkParameters = bridgeConstants.getBtcParams(); - activationsBeforeForks = ActivationConfigsForTest.genesis().forBlock(0); - activeFederation = getFederation(); + activeFederation = P2shErpFederationBuilder.builder().build(); repository = spy(createRepository()); eventLogger = mock(BridgeEventLogger.class); - utxo = buildUTXO(); - provider = initProvider(repository, activationMock); - federationStorageProvider = initFederationStorageProvider(repository, activationMock); + provider = initProvider(); + federationStorageProvider = initFederationStorageProvider(); bridgeSupportBuilder = BridgeSupportBuilder.builder(); feePerKbSupport = mock(FeePerKbSupportImpl.class); - when(feePerKbSupport.getFeePerKb()).thenReturn(bridgeConstants.getFeePerKbConstants().getGenesisFeePerKb()); - bridgeSupport = spy(initBridgeSupport(eventLogger, activationMock)); + when(feePerKbSupport.getFeePerKb()).thenReturn(Coin.valueOf(5_000L)); + bridgeSupport = spy(initBridgeSupport(eventLogger, ACTIVATIONS_ALL)); releaseTx = buildReleaseRskTx(); } @Test void noLogEvents_before_rskip_146_185() throws IOException { - provider = initProvider(repository, activationsBeforeForks); - bridgeSupport = initBridgeSupport(eventLogger, activationsBeforeForks); + ActivationConfig.ForBlock wasabiActivation = ActivationConfigsForTest.wasabi100().forBlock(0L); + bridgeSupport = initBridgeSupport(eventLogger, wasabiActivation); bridgeSupport.releaseBtc(releaseTx); Transaction rskTx = buildUpdateTx(); @@ -125,9 +114,10 @@ void noLogEvents_before_rskip_146_185() throws IOException { } @Test - void eventLogger_logReleaseBtcRequested_after_rskip_146() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); + void eventLogger_logReleaseBtcRequested_after_rskip146_before_rskip185() throws IOException { + ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); + bridgeSupport = initBridgeSupport(eventLogger, papyrusActivations); bridgeSupport.releaseBtc(releaseTx); Transaction rskTx = buildUpdateTx(); @@ -141,9 +131,6 @@ void eventLogger_logReleaseBtcRequested_after_rskip_146() throws IOException { @Test void eventLogger_logReleaseBtcRequested_after_rskip_146_185() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - bridgeSupport.releaseBtc(releaseTx); Transaction rskTx = buildUpdateTx(); @@ -152,52 +139,52 @@ void eventLogger_logReleaseBtcRequested_after_rskip_146_185() throws IOException verify(repository, never()).transfer(any(), any(), any()); verify(eventLogger, times(1)).logReleaseBtcRequested(any(byte[].class), any(BtcTransaction.class), any(Coin.class)); verify(eventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); - verify(eventLogger, times(0)).logReleaseBtcRequestRejected(any(), any(), any()); + verify(eventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); } @Test - void eventLogger_logReleaseBtcRequested_after_rskip_146_185_326() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP326)).thenReturn(true); + void eventLogger_logReleaseBtcRequested_release_before_papyrus_and_updateCollections_after_papyrus() throws IOException { + ActivationConfig.ForBlock wasabiActivations = ActivationConfigsForTest.wasabi100().forBlock(0L); + ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); + bridgeSupport = initBridgeSupport(eventLogger, wasabiActivations); bridgeSupport.releaseBtc(releaseTx); + bridgeSupport = initBridgeSupport(eventLogger, papyrusActivations); Transaction rskTx = buildUpdateTx(); bridgeSupport.updateCollections(rskTx); verify(repository, never()).transfer(any(), any(), any()); - verify(eventLogger, times(1)).logReleaseBtcRequested(any(byte[].class), any(BtcTransaction.class), any(Coin.class)); - verify(eventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); - verify(eventLogger, times(0)).logReleaseBtcRequestRejected(any(), any(), any()); + verify(eventLogger, never()).logReleaseBtcRequested(any(byte[].class), any(BtcTransaction.class), any(Coin.class)); + verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); + verify(eventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); } @Test - void eventLogger_logReleaseBtcRequested_release_before_activation_and_updateCollections_after_activation() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(false); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(false); + void handmade_release_before_rskip_146_185() throws IOException { + ActivationConfig.ForBlock wasabiActivations = ActivationConfigsForTest.wasabi100().forBlock(0L); + bridgeSupport = initBridgeSupport(eventLogger, wasabiActivations); bridgeSupport.releaseBtc(releaseTx); - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - - bridgeSupport = initBridgeSupport(eventLogger, activationMock); - Transaction rskTx = buildUpdateTx(); + rskTx.sign(new ECKey().getPrivKeyBytes()); bridgeSupport.updateCollections(rskTx); verify(repository, never()).transfer(any(), any(), any()); + assertEquals(1, provider.getPegoutsWaitingForConfirmations().getEntries().size()); + assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); + verify(eventLogger, never()).logReleaseBtcRequested(any(byte[].class), any(BtcTransaction.class), any(Coin.class)); verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); verify(eventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); } @Test - void handmade_release_before_rskip_146_185() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(false); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(false); + void handmade_release_after_rskip146_before_rskip185() throws IOException { + ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); + bridgeSupport = initBridgeSupport(eventLogger, papyrusActivations); bridgeSupport.releaseBtc(releaseTx); Transaction rskTx = buildUpdateTx(); @@ -207,46 +194,65 @@ void handmade_release_before_rskip_146_185() throws IOException { verify(repository, never()).transfer(any(), any(), any()); assertEquals(1, provider.getPegoutsWaitingForConfirmations().getEntries().size()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); - - verify(eventLogger, never()).logReleaseBtcRequested(any(byte[].class), any(BtcTransaction.class), any(Coin.class)); - verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); - verify(eventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); + verify(eventLogger, times(1)).logReleaseBtcRequested( + any(byte[].class), + any(BtcTransaction.class), + any(Coin.class) + ); } @Test - void handmade_release_after_rskip_146() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(false); + void handmade_release_after_rskip_146_185_before_rskip326() throws IOException { + ActivationConfig.ForBlock hopActivations = ActivationConfigsForTest.hop400().forBlock(0L); List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + hopActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, hopActivations); bridgeSupport.releaseBtc(releaseTx); Transaction rskTx = buildUpdateTx(); - rskTx.sign(new ECKey().getPrivKeyBytes()); + rskTx.sign(SENDER.getPrivKeyBytes()); bridgeSupport.updateCollections(rskTx); verify(repository, never()).transfer(any(), any(), any()); + assertEquals(1, provider.getPegoutsWaitingForConfirmations().getEntries().size()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); + + assertEquals(4, logInfo.size()); verify(bridgeEventLogger, times(1)).logReleaseBtcRequested( any(byte[].class), any(BtcTransaction.class), any(Coin.class) ); + verify(bridgeEventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); + verify(bridgeEventLogger, times(1)).logUpdateCollections(any()); + verify(bridgeEventLogger, times(1)).logBatchPegoutCreated(any(), any()); + + LogInfo firstLog = logInfo.get(0); + CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(); + Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; + assertInstanceOf(byte[].class, btcDestinationAddress); } @Test - void handmade_release_after_rskip_146_185() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP326)).thenReturn(false); + void handmade_release_after_rskip_146_185_326_before_rskip428() throws IOException { + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0L); List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + arrowheadActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, arrowheadActivations); bridgeSupport.releaseBtc(releaseTx); @@ -259,7 +265,7 @@ void handmade_release_after_rskip_146_185() throws IOException { assertEquals(1, provider.getPegoutsWaitingForConfirmations().getEntries().size()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); - assertEquals(3, logInfo.size()); + assertEquals(4, logInfo.size()); verify(bridgeEventLogger, times(1)).logReleaseBtcRequested( any(byte[].class), any(BtcTransaction.class), @@ -267,23 +273,24 @@ void handmade_release_after_rskip_146_185() throws IOException { ); verify(bridgeEventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); verify(bridgeEventLogger, times(1)).logUpdateCollections(any()); + verify(bridgeEventLogger, times(1)).logBatchPegoutCreated(any(), any()); - LogInfo logInfo1 = logInfo.get(0); - CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(); - Object btcDestinationAddress = event.decodeEventData(logInfo1.getData())[0]; - assertInstanceOf(byte[].class, btcDestinationAddress); + LogInfo firstLog = logInfo.get(0); + CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(); + Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; + assertInstanceOf(String.class, btcDestinationAddress); } @Test - void handmade_release_after_rskip_146_185_326() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP326)).thenReturn(true); - + void handmade_release_after_rskip_146_185_326_428() throws IOException { List logInfo = new ArrayList<>(); - - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, ACTIVATIONS_ALL); bridgeSupport.releaseBtc(releaseTx); @@ -296,33 +303,37 @@ void handmade_release_after_rskip_146_185_326() throws IOException { assertEquals(1, provider.getPegoutsWaitingForConfirmations().getEntries().size()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); - assertEquals(3, logInfo.size()); + assertEquals(5, logInfo.size()); verify(bridgeEventLogger, times(1)).logReleaseBtcRequested( any(byte[].class), any(BtcTransaction.class), any(Coin.class) ); - verify(bridgeEventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); verify(bridgeEventLogger, times(1)).logUpdateCollections(any()); + verify(bridgeEventLogger, times(1)).logBatchPegoutCreated(any(), any()); + verify(bridgeEventLogger, times(1)).logPegoutTransactionCreated(any(), any()); - LogInfo logInfo1 = logInfo.get(0); + LogInfo firstLog = logInfo.get(0); CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(); - Object btcDestinationAddress = event.decodeEventData(logInfo1.getData())[0]; + Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; assertInstanceOf(String.class, btcDestinationAddress); } @Test - void handmade_release_after_rskip_146_rejected_lowAmount() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(false); - + void handmade_release_after_rskip146_before_rskip185_rejected_lowAmount() throws IOException { + ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + papyrusActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, papyrusActivations); - releaseTx = buildReleaseRskTx(Coin.ZERO); + releaseTx = buildReleaseRskTx(co.rsk.core.Coin.ZERO); bridgeSupport.releaseBtc(releaseTx); Transaction rskTx = buildUpdateTx(); @@ -336,20 +347,21 @@ void handmade_release_after_rskip_146_rejected_lowAmount() throws IOException { verify(bridgeEventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); assertEquals(1, logInfo.size()); - verify(bridgeEventLogger, times(1)).logUpdateCollections(any()); } @Test void handmade_release_after_rskip_146_185_rejected_lowAmount() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, ACTIVATIONS_ALL); - releaseTx = buildReleaseRskTx(Coin.ZERO); + releaseTx = buildReleaseRskTx(co.rsk.core.Coin.ZERO); bridgeSupport.releaseBtc(releaseTx); Transaction rskTx = buildUpdateTx(); @@ -357,7 +369,7 @@ void handmade_release_after_rskip_146_185_rejected_lowAmount() throws IOExceptio bridgeSupport.updateCollections(rskTx); verify(repository, times(1)).transfer( - argThat(a -> a.equals(PrecompiledContracts.BRIDGE_ADDR)), + argThat(a -> a.equals(BRIDGE_ADDRESS)), argThat(a -> a.equals(new RskAddress(SENDER.getAddress()))), argThat(a -> a.equals(co.rsk.core.Coin.fromBitcoin(Coin.ZERO))) ); @@ -371,21 +383,30 @@ void handmade_release_after_rskip_146_185_rejected_lowAmount() throws IOExceptio verify(bridgeEventLogger, times(1)).logUpdateCollections(any()); } - @Test - void handmade_release_after_rskip_146_185_rejected_contractCaller() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); + void handmade_release_after_rskip146_before_rskip185_rejected_contractCaller_throws_exception() { + ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); + bridgeSupport = initBridgeSupport(eventLogger, papyrusActivations); + releaseTx = buildReleaseRskTx_fromContract(co.rsk.core.Coin.fromBitcoin(Coin.COIN)); + assertThrows(Program.OutOfGasException.class, () -> bridgeSupport.releaseBtc(releaseTx)); + } + + @Test + void handmade_release_after_rskip_146_185_rejected_contractCaller_emits_rejection_event() throws IOException { List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, ACTIVATIONS_ALL); - releaseTx = buildReleaseRskTx_fromContract(Coin.COIN); + releaseTx = buildReleaseRskTx_fromContract(co.rsk.core.Coin.fromBitcoin(Coin.COIN)); bridgeSupport.releaseBtc(releaseTx); - // Create Contract transaction Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); bridgeSupport.updateCollections(rskTx); @@ -404,40 +425,24 @@ void handmade_release_after_rskip_146_185_rejected_contractCaller() throws IOExc } @Test - void handmade_release_after_rskip_146_rejected_contractCaller() throws IOException { - - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(false); - - List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); - - releaseTx = buildReleaseRskTx_fromContract(Coin.COIN); - try { - bridgeSupport.releaseBtc(releaseTx); - fail(); - } catch (Program.OutOfGasException e) { - assertTrue(e.getMessage().contains("Contract calling releaseBTC")); - } - } - - @Test - void release_after_rskip_219() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(true); + void release_after_rskip219_before_rskip326() throws IOException { + ActivationConfig.ForBlock hopActivations = ActivationConfigsForTest.hop400().forBlock(0L); List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + hopActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, hopActivations); // Get a value between old and new minimum pegout values - Coin middle = bridgeConstants.getLegacyMinimumPegoutTxValue().subtract(bridgeConstants.getMinimumPegoutTxValue()).div(2); - Coin value = bridgeConstants.getMinimumPegoutTxValue().add(middle); - assertTrue(value.isLessThan(bridgeConstants.getLegacyMinimumPegoutTxValue())); - assertTrue(value.isGreaterThan(bridgeConstants.getMinimumPegoutTxValue())); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); + Coin middle = BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue().subtract(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()).div(2); + Coin value = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().add(middle); + assertTrue(value.isLessThan(BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue())); + assertTrue(value.isGreaterThan(BRIDGE_CONSTANTS.getMinimumPegoutTxValue())); + bridgeSupport.releaseBtc(buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(value))); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); @@ -449,29 +454,31 @@ void release_after_rskip_219() throws IOException { assertEquals(1, logInfo.size()); verify(bridgeEventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); - LogInfo logInfo1 = logInfo.get(0); + LogInfo firstLog = logInfo.get(0); CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(); - Object btcDestinationAddress = event.decodeEventData(logInfo1.getData())[0]; + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; assertInstanceOf(byte[].class, btcDestinationAddress); } @Test void release_after_rskip_219_326() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP326)).thenReturn(true); - List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, ACTIVATIONS_ALL); // Get a value between old and new minimum pegout values - Coin middle = bridgeConstants.getLegacyMinimumPegoutTxValue().subtract(bridgeConstants.getMinimumPegoutTxValue()).div(2); - Coin value = bridgeConstants.getMinimumPegoutTxValue().add(middle); - assertTrue(value.isLessThan(bridgeConstants.getLegacyMinimumPegoutTxValue())); - assertTrue(value.isGreaterThan(bridgeConstants.getMinimumPegoutTxValue())); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); + Coin middle = BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue().subtract(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()).div(2); + Coin value = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().add(middle); + assertTrue(value.isLessThan(BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue())); + assertTrue(value.isGreaterThan(BRIDGE_CONSTANTS.getMinimumPegoutTxValue())); + bridgeSupport.releaseBtc(buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(value))); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); @@ -483,76 +490,87 @@ void release_after_rskip_219_326() throws IOException { assertEquals(1, logInfo.size()); verify(bridgeEventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); - LogInfo logInfo1 = logInfo.get(0); + LogInfo firstLog = logInfo.get(0); CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(); - Object btcDestinationAddress = event.decodeEventData(logInfo1.getData())[0]; + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; assertInstanceOf(String.class, btcDestinationAddress); } @Test void release_before_rskip_219() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(false); + ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + papyrusActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, papyrusActivations); // Get a value between old and new minimum pegout values - Coin middle = bridgeConstants.getLegacyMinimumPegoutTxValue().subtract(bridgeConstants.getMinimumPegoutTxValue()).div(2); - Coin value = bridgeConstants.getMinimumPegoutTxValue().add(middle); - assertTrue(value.isLessThan(bridgeConstants.getLegacyMinimumPegoutTxValue())); - assertTrue(value.isGreaterThan(bridgeConstants.getMinimumPegoutTxValue())); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); + Coin middle = BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue().subtract(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()).div(2); + Coin value = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().add(middle); + assertTrue(value.isLessThan(BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue())); + assertTrue(value.isGreaterThan(BRIDGE_CONSTANTS.getMinimumPegoutTxValue())); + bridgeSupport.releaseBtc(buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(value))); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); - assertEquals(1, logInfo.size()); + assertEquals(0, logInfo.size()); verify(bridgeEventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); - verify(bridgeEventLogger, times(1)).logReleaseBtcRequestRejected(any(), any(), any()); + verify(bridgeEventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); } @Test void release_before_rskip_219_minimum_exclusive() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(false); + ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + papyrusActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, papyrusActivations); // Get a value exactly to legacy minimum - Coin value = bridgeConstants.getLegacyMinimumPegoutTxValue(); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); + Coin value = BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue(); + bridgeSupport.releaseBtc(buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(value))); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); - assertEquals(1, logInfo.size()); + assertEquals(0, logInfo.size()); verify(bridgeEventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); - verify(bridgeEventLogger, times(1)).logReleaseBtcRequestRejected(any(), any(), any()); + verify(bridgeEventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); } @Test - void release_after_rskip_219_minimum_inclusive() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(true); + void release_after_rskip219_before_rskip326_minimum_inclusive() throws IOException { + ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + irisActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, irisActivations); // Get a value exactly to current minimum - Coin value = bridgeConstants.getMinimumPegoutTxValue(); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); + Coin value = BRIDGE_CONSTANTS.getMinimumPegoutTxValue(); + bridgeSupport.releaseBtc(buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(value))); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); @@ -564,26 +582,28 @@ void release_after_rskip_219_minimum_inclusive() throws IOException { assertEquals(1, logInfo.size()); verify(bridgeEventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); - LogInfo logInfo1 = logInfo.get(0); + LogInfo firstLog = logInfo.get(0); CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(); - Object btcDestinationAddress = event.decodeEventData(logInfo1.getData())[0]; + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; assertInstanceOf(byte[].class, btcDestinationAddress); } @Test void release_after_rskip_219_326_minimum_inclusive() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP326)).thenReturn(true); - List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl(bridgeConstants, activationMock, logInfo, signatureCache)); - bridgeSupport = initBridgeSupport(bridgeEventLogger, activationMock); + BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(bridgeEventLogger, ACTIVATIONS_ALL); // Get a value exactly to current minimum - Coin value = bridgeConstants.getMinimumPegoutTxValue(); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); + Coin value = BRIDGE_CONSTANTS.getMinimumPegoutTxValue(); + bridgeSupport.releaseBtc(buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(value))); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); @@ -595,74 +615,80 @@ void release_after_rskip_219_326_minimum_inclusive() throws IOException { assertEquals(1, logInfo.size()); verify(bridgeEventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); - LogInfo logInfo1 = logInfo.get(0); + LogInfo firstLog = logInfo.get(0); CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(); - Object btcDestinationAddress = event.decodeEventData(logInfo1.getData())[0]; - assertInstanceOf(String.class, btcDestinationAddress); + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; + assertInstanceOf(String.class, btcDestinationAddress); } @Test void release_verify_fee_below_fee_is_rejected() throws IOException { - Coin value = bridgeConstants.getMinimumPegoutTxValue().add(Coin.SATOSHI); - testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(Coin.COIN, value); + Coin value = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().add(Coin.SATOSHI); + testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(Coin.COIN, co.rsk.core.Coin.fromBitcoin(value)); } @Test void release_verify_fee_above_fee_but_below_gap_is_rejected_before_rskip_271() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(false); + ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); Coin feePerKB = Coin.COIN; - int pegoutSize = BridgeUtils.getRegularPegoutTxSize(activationMock, federationStorageProvider.getNewFederation(federationConstants, activationMock)); + int pegoutSize = BridgeUtils.getRegularPegoutTxSize( + irisActivations, + federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, irisActivations) + ); Coin value = feePerKB.div(1000).times(pegoutSize); - testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(feePerKB, value); + testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(feePerKB, co.rsk.core.Coin.fromBitcoin(value)); } @Test void release_verify_fee_above_fee_but_below_gap_is_rejected_after_rskip_271() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); Coin feePerKB = Coin.COIN; - int pegoutSize = BridgeUtils.getRegularPegoutTxSize(activationMock, federationStorageProvider.getNewFederation(federationConstants, activationMock)); + int pegoutSize = BridgeUtils.getRegularPegoutTxSize( + ACTIVATIONS_ALL, + federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, ACTIVATIONS_ALL) + ); Coin value = feePerKB.div(1000).times(pegoutSize); - testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(feePerKB, value); + testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(feePerKB, co.rsk.core.Coin.fromBitcoin(value)); } @Test void release_verify_fee_above_fee_but_below_minimum_is_rejected() throws IOException { + Coin valueBelowMinimum = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().minus(Coin.SATOSHI); testPegoutMinimumWithFeeVerificationRejectedByLowAmount( Coin.MILLICOIN, - bridgeConstants.getMinimumPegoutTxValue().minus(Coin.SATOSHI) + co.rsk.core.Coin.fromBitcoin(valueBelowMinimum) ); } @Test void release_verify_fee_above_fee_and_minimum_is_accepted() throws IOException { - testPegoutMinimumWithFeeVerificationPass(Coin.COIN, Coin.FIFTY_COINS); + testPegoutMinimumWithFeeVerificationPass(Coin.COIN, co.rsk.core.Coin.fromBitcoin(Coin.FIFTY_COINS)); } @Test - void test_processPegoutsIndividually_before_RSKIP271_activation() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(false); + void processPegoutsIndividually_before_RSKIP271_activation() throws IOException { + ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); List utxos = new ArrayList<>(); - utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(3), genesisFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(3), activeFederation.getAddress())); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, irisActivations)).thenReturn(utxos); BridgeStorageProvider bridgeStorageProvider = mock(BridgeStorageProvider.class); when(bridgeStorageProvider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.COIN), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.COIN)) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.COIN), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.COIN)) )); when(bridgeStorageProvider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(bridgeStorageProvider) - .withActivations(activationMock) + .withActivations(irisActivations) .build(); Transaction rskTx = buildUpdateTx(); @@ -677,22 +703,18 @@ void test_processPegoutsIndividually_before_RSKIP271_activation() throws IOExcep } @Test - void test_processPegoutsInBatch_after_RSKIP271() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); + void processPegoutsInBatch_after_RSKIP271() throws IOException { List utxos = new ArrayList<>(); - utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), genesisFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), activeFederation.getAddress())); ReleaseRequestQueue pegoutRequests = new ReleaseRequestQueue(Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.MILLICOIN), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.MILLICOIN), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "three"), Coin.MILLICOIN) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.MILLICOIN), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.MILLICOIN), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "three"), Coin.MILLICOIN) )); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(pegoutRequests); @@ -709,8 +731,8 @@ void test_processPegoutsInBatch_after_RSKIP271() throws IOException { .collect(Collectors.toList()); bridgeSupport = bridgeSupportBuilder - .withActivations(activationMock) - .withBridgeConstants(bridgeConstants) + .withActivations(ACTIVATIONS_ALL) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) .withEventLogger(eventLogger) .build(); @@ -731,28 +753,25 @@ void test_processPegoutsInBatch_after_RSKIP271() throws IOException { } @Test - void test_processPegoutsInBatch_after_RSKIP271_activation_next_pegout_height_not_reached() throws IOException { - - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - + void processPegoutsInBatch_after_RSKIP271_activation_next_pegout_height_not_reached() throws IOException { Block executionBlock = mock(Block.class); when(executionBlock.getNumber()).thenReturn(100L); long executionBlockNumber = executionBlock.getNumber(); provider = mock(BridgeStorageProvider.class); - when(provider.getNextPegoutHeight()).thenReturn(Optional.of(executionBlockNumber + bridgeConstants.getNumberOfBlocksBetweenPegouts() - 1)); + when(provider.getNextPegoutHeight()).thenReturn(Optional.of(executionBlockNumber + BRIDGE_CONSTANTS.getNumberOfBlocksBetweenPegouts() - 1)); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.MILLICOIN), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.MILLICOIN) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.MILLICOIN), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.MILLICOIN) ))); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) .withExecutionBlock(executionBlock) - .withActivations(activationMock) + .withActivations(ACTIVATIONS_ALL) .build(); Transaction rskTx = buildUpdateTx(); @@ -766,9 +785,7 @@ void test_processPegoutsInBatch_after_RSKIP271_activation_next_pegout_height_not } @Test - void test_processPegoutsInBatch_after_RSKIP271_activation_no_requests_in_queue_updates_next_pegout_height() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - + void processPegoutsInBatch_after_RSKIP271_activation_no_requests_in_queue_updates_next_pegout_height() throws IOException { provider = mock(BridgeStorageProvider.class); when(provider.getNextPegoutHeight()).thenReturn(Optional.of(100L)); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Collections.emptyList())); @@ -778,8 +795,8 @@ void test_processPegoutsInBatch_after_RSKIP271_activation_no_requests_in_queue_u when(executionBlock.getNumber()).thenReturn(100L); bridgeSupport = bridgeSupportBuilder - .withActivations(activationMock) - .withBridgeConstants(bridgeConstants) + .withActivations(ACTIVATIONS_ALL) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) .withExecutionBlock(executionBlock) .build(); @@ -787,37 +804,34 @@ void test_processPegoutsInBatch_after_RSKIP271_activation_no_requests_in_queue_u Transaction rskTx = buildUpdateTx(); bridgeSupport.updateCollections(rskTx); - long nextPegoutHeight = executionBlock.getNumber() + bridgeConstants.getNumberOfBlocksBetweenPegouts(); + long nextPegoutHeight = executionBlock.getNumber() + BRIDGE_CONSTANTS.getNumberOfBlocksBetweenPegouts(); verify(provider, times(1)).getNextPegoutHeight(); verify(provider, times(1)).setNextPegoutHeight(nextPegoutHeight); } @Test - void test_processPegoutsInBatch_after_rskip_271_Insufficient_Money() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); + void processPegoutsInBatch_after_rskip_271_Insufficient_Money() throws IOException { List utxos = new ArrayList<>(); - utxos.add(PegTestUtils.createUTXO(2, 0, Coin.COIN.multiply(4), genesisFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(2, 0, Coin.COIN.multiply(4), activeFederation.getAddress())); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.COIN), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.COIN), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "three"), Coin.COIN), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "four"), Coin.COIN), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "five"), Coin.COIN) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.COIN), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.COIN), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "three"), Coin.COIN), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "four"), Coin.COIN), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "five"), Coin.COIN) ))); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withActivations(activationMock) - .withBridgeConstants(bridgeConstants) + .withActivations(ACTIVATIONS_ALL) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) .build(); @@ -831,27 +845,25 @@ void test_processPegoutsInBatch_after_rskip_271_Insufficient_Money() throws IOEx } @Test - void test_processPegoutsInBatch_after_rskip_271_divide_transaction_when_max_size_exceeded() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); - List utxos = PegTestUtils.createUTXOs(610, genesisFederation.getAddress()); + void processPegoutsInBatch_after_rskip_271_divide_transaction_when_max_size_exceeded() throws IOException { + List utxos = PegTestUtils.createUTXOs(310, activeFederation.getAddress()); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); + when(federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, ACTIVATIONS_ALL)).thenReturn(activeFederation); FederationSupport federationSupport = FederationSupportBuilder.builder() - .withFederationConstants(federationConstants) + .withFederationConstants(FEDERATION_CONSTANTS) .withFederationStorageProvider(federationStorageProvider) - .withActivations(activationMock) + .withActivations(ACTIVATIONS_ALL) .build(); provider = mock(BridgeStorageProvider.class); - when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(PegTestUtils.createReleaseRequestQueueEntries(600))); + when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(PegTestUtils.createReleaseRequestQueueEntries(300))); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withActivations(activationMock) - .withBridgeConstants(bridgeConstants) + .withActivations(ACTIVATIONS_ALL) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) .withFederationSupport(federationSupport) .build(); @@ -859,37 +871,34 @@ void test_processPegoutsInBatch_after_rskip_271_divide_transaction_when_max_size Transaction rskTx = buildUpdateTx(); bridgeSupport.updateCollections(rskTx); - // First Half of the PegoutRequests 600 / 2 = 300 Is Batched For The First Time - assertEquals(300, provider.getReleaseRequestQueue().getEntries().size()); + // First Half of the PegoutRequests 300 / 2 = 150 Is Batched For The First Time + assertEquals(150, provider.getReleaseRequestQueue().getEntries().size()); assertEquals(1, provider.getPegoutsWaitingForConfirmations().getEntries().size()); rskTx = buildUpdateTx(); bridgeSupport.updateCollections(rskTx); - // The Rest PegoutRequests 600 / 2 = 300 Is Batched The 2nd Time updateCollections Is Called + // The Rest PegoutRequests 300 / 2 = 150 Is Batched The 2nd Time updateCollections Is Called assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); assertEquals(2, provider.getPegoutsWaitingForConfirmations().getEntries().size()); } @Test - void test_processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_one_pegout() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); - List utxos = PegTestUtils.createUTXOs(700, genesisFederation.getAddress()); + void processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_one_pegout() throws IOException { + List utxos = PegTestUtils.createUTXOs(700, activeFederation.getAddress()); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Collections.singletonList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.COIN.multiply(700)) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.COIN.multiply(700)) ))); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withActivations(activationMock) - .withBridgeConstants(bridgeConstants) + .withActivations(ACTIVATIONS_ALL) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) .build(); @@ -901,25 +910,22 @@ void test_processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_one_p } @Test - void test_processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_two_pegout() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); - List utxos = PegTestUtils.createUTXOs(1400, genesisFederation.getAddress()); + void processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_two_pegout() throws IOException { + List utxos = PegTestUtils.createUTXOs(1400, activeFederation.getAddress()); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.COIN.multiply(700)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.COIN.multiply(700)) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.COIN.multiply(700)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.COIN.multiply(700)) ))); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withActivations(activationMock) - .withBridgeConstants(bridgeConstants) + .withActivations(ACTIVATIONS_ALL) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) .build(); @@ -931,34 +937,33 @@ void test_processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_two_p } @Test - void test_processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_requests() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(false); + void processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_requests() throws IOException { + ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); List utxos = new ArrayList<>(); - utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN, genesisFederation.getAddress())); - utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN, genesisFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN, activeFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN, activeFederation.getAddress())); List entries = Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.COIN.multiply(5)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.COIN.multiply(4)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "three"), Coin.COIN.multiply(3)) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.COIN.multiply(5)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.COIN.multiply(4)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "three"), Coin.COIN.multiply(3)) ); ReleaseRequestQueue originalPegoutRequests = new ReleaseRequestQueue(entries); ReleaseRequestQueue pegoutRequests = new ReleaseRequestQueue(entries); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, irisActivations)).thenReturn(utxos); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(pegoutRequests); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) - .withActivations(activationMock) + .withActivations(irisActivations) .build(); Transaction rskTx = buildUpdateTx(); @@ -969,20 +974,19 @@ void test_processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_re } @Test - void test_processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_requests_order_changes_in_queue() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(false); + void processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_requests_order_changes_in_queue() throws IOException { + ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); List utxos = new ArrayList<>(); - utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN, genesisFederation.getAddress())); - utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN, genesisFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN, activeFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN, activeFederation.getAddress())); List entries = new ArrayList<>(); int entriesSizeAboveMaxIterations = BridgeSupport.MAX_RELEASE_ITERATIONS + 10; for (int i = 0; i < entriesSizeAboveMaxIterations; i++) { entries.add( new ReleaseRequestQueue.Entry( - BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), String.valueOf(i)), + BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), String.valueOf(i)), Coin.COIN.multiply(5) ) ); @@ -997,16 +1001,16 @@ void test_processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_re ReleaseRequestQueue pegoutRequests = new ReleaseRequestQueue(entries); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, irisActivations)).thenReturn(utxos); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(pegoutRequests); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) - .withActivations(activationMock) + .withActivations(irisActivations) .build(); Transaction rskTx = buildUpdateTx(); @@ -1018,28 +1022,27 @@ void test_processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_re } @Test - void test_check_wallet_balance_before_rskip_271_process_at_least_one_request() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(false); + void check_wallet_balance_before_rskip_271_process_at_least_one_request() throws IOException { + ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); List utxos = new ArrayList<>(); - utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(2), genesisFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(2), activeFederation.getAddress())); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, irisActivations)).thenReturn(utxos); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.COIN.multiply(4)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.COIN.multiply(3)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "three"), Coin.COIN.multiply(2)) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.COIN.multiply(4)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.COIN.multiply(3)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "three"), Coin.COIN.multiply(2)) ))); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) - .withActivations(activationMock) + .withActivations(irisActivations) .build(); Transaction rskTx = buildUpdateTx(); @@ -1051,30 +1054,27 @@ void test_check_wallet_balance_before_rskip_271_process_at_least_one_request() t } @Test - void test_check_wallet_balance_after_rskip_271_process_no_requests() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); + void check_wallet_balance_after_rskip_271_process_no_requests() throws IOException { List utxos = new ArrayList<>(); - utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), genesisFederation.getAddress())); - utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN.multiply(4), genesisFederation.getAddress())); - utxos.add(PegTestUtils.createUTXO(3, 2, Coin.COIN.multiply(3), genesisFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), activeFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN.multiply(4), activeFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(3, 2, Coin.COIN.multiply(3), activeFederation.getAddress())); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.COIN.multiply(5)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.COIN.multiply(4)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "three"), Coin.COIN.multiply(3)) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.COIN.multiply(5)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.COIN.multiply(4)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "three"), Coin.COIN.multiply(3)) ))); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) - .withActivations(activationMock) + .withActivations(ACTIVATIONS_ALL) .withEventLogger(eventLogger) .build(); @@ -1089,30 +1089,28 @@ void test_check_wallet_balance_after_rskip_271_process_no_requests() throws IOEx } @Test - void test_check_wallet_balance_after_rskip_271_process_all_requests_when_utxos_available() throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP271)).thenReturn(true); - - Federation genesisFederation = FederationTestUtils.getGenesisFederation(federationConstants); + void check_wallet_balance_after_rskip_271_process_all_requests_when_utxos_available() throws IOException { List utxos = new ArrayList<>(); - utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), genesisFederation.getAddress())); - utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN.multiply(4), genesisFederation.getAddress())); - utxos.add(PegTestUtils.createUTXO(3, 2, Coin.COIN.multiply(3), genesisFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), activeFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN.multiply(4), activeFederation.getAddress())); + utxos.add(PegTestUtils.createUTXO(3, 2, Coin.COIN.multiply(3), activeFederation.getAddress())); federationStorageProvider = mock(FederationStorageProvider.class); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); + when(federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, ACTIVATIONS_ALL)).thenReturn(activeFederation); provider = mock(BridgeStorageProvider.class); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Arrays.asList( - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "one"), Coin.COIN.multiply(5)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "two"), Coin.COIN.multiply(4)), - new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(bridgeConstants.getBtcParams(), "three"), Coin.COIN.multiply(3)) + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "one"), Coin.COIN.multiply(5)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "two"), Coin.COIN.multiply(4)), + new ReleaseRequestQueue.Entry(BitcoinTestUtils.createP2PKHAddress(BRIDGE_CONSTANTS.getBtcParams(), "three"), Coin.COIN.multiply(3)) ))); when(provider.getPegoutsWaitingForConfirmations()).thenReturn(new PegoutsWaitingForConfirmations(Collections.emptySet())); bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) - .withActivations(activationMock) + .withActivations(ACTIVATIONS_ALL) .withEventLogger(eventLogger) .build(); @@ -1126,18 +1124,18 @@ void test_check_wallet_balance_after_rskip_271_process_all_requests_when_utxos_a verify(eventLogger, never()).logBatchPegoutCreated(any(), any()); verify(provider, never()).setNextPegoutHeight(any(Long.class)); - utxos.add(PegTestUtils.createUTXO(4, 3, Coin.COIN.multiply(1), genesisFederation.getAddress())); - when(federationStorageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock)).thenReturn(utxos); + utxos.add(PegTestUtils.createUTXO(4, 3, Coin.COIN.multiply(1), activeFederation.getAddress())); + when(federationStorageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL)).thenReturn(utxos); FederationSupport federationSupport = FederationSupportBuilder.builder() - .withFederationConstants(federationConstants) + .withFederationConstants(FEDERATION_CONSTANTS) .withFederationStorageProvider(federationStorageProvider) - .withActivations(activationMock) + .withActivations(ACTIVATIONS_ALL) .build(); bridgeSupport = bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) - .withActivations(activationMock) + .withActivations(ACTIVATIONS_ALL) .withEventLogger(eventLogger) .withFederationSupport(federationSupport) .build(); @@ -1153,30 +1151,30 @@ void test_check_wallet_balance_after_rskip_271_process_all_requests_when_utxos_a verify(provider, times(1)).setNextPegoutHeight(any(Long.class)); } - private void testPegoutMinimumWithFeeVerificationPass(Coin feePerKB, Coin value) - throws IOException { - when(activationMock.isActive(ConsensusRule.RSKIP146)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP185)).thenReturn(true); - when(activationMock.isActive(ConsensusRule.RSKIP219)).thenReturn(true); - + private void testPegoutMinimumWithFeeVerificationPass(Coin feePerKB, co.rsk.core.Coin pegoutRequestedValue) throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( - bridgeConstants, - activationMock, + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, logInfo, signatureCache )); - bridgeSupport = initBridgeSupport(eventLogger, activationMock); + bridgeSupport = initBridgeSupport(eventLogger, ACTIVATIONS_ALL); when(feePerKbSupport.getFeePerKb()).thenReturn(feePerKB); - int pegoutSize = BridgeUtils.getRegularPegoutTxSize(activationMock, federationStorageProvider.getNewFederation(federationConstants, activationMock)); + int pegoutSize = BridgeUtils.getRegularPegoutTxSize( + ACTIVATIONS_ALL, + federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, ACTIVATIONS_ALL) + ); Coin minValueAccordingToFee = feePerKbSupport.getFeePerKb().div(1000).times(pegoutSize); - Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times(bridgeConstants.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100)); + Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times( + BRIDGE_CONSTANTS.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100)); - assertFalse(value.isLessThan(minValueWithGapAboveFee) || - value.isLessThan(bridgeConstants.getMinimumPegoutTxValue())); + Coin valueToRelease = pegoutRequestedValue.toBitcoin(); + assertFalse(valueToRelease.isLessThan(minValueWithGapAboveFee) || + valueToRelease.isLessThan(BRIDGE_CONSTANTS.getMinimumPegoutTxValue())); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestedValue)); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); @@ -1190,95 +1188,91 @@ private void testPegoutMinimumWithFeeVerificationPass(Coin feePerKB, Coin value) verify(eventLogger, never()).logReleaseBtcRequestRejected(any(), any(), any()); } - private void testPegoutMinimumWithFeeVerificationRejectedByLowAmount(Coin feePerKB, Coin value) throws IOException { - ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0); - + private void testPegoutMinimumWithFeeVerificationRejectedByLowAmount( + Coin feePerKB, + co.rsk.core.Coin pegoutRequestValue + ) throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( - bridgeConstants, - activationMock, + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, logInfo, signatureCache )); - bridgeSupport = initBridgeSupport(eventLogger, activationMock); + bridgeSupport = initBridgeSupport(eventLogger, ACTIVATIONS_ALL); when(feePerKbSupport.getFeePerKb()).thenReturn(feePerKB); int pegoutSize = BridgeUtils.getRegularPegoutTxSize( - irisActivations, - federationStorageProvider.getNewFederation(federationConstants, irisActivations) + ACTIVATIONS_ALL, + federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, ACTIVATIONS_ALL) ); Coin minValueAccordingToFee = feePerKbSupport.getFeePerKb().div(1000).times(pegoutSize); - Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times(bridgeConstants.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100)); + Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times( + BRIDGE_CONSTANTS.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100)); - assertTrue(value.isGreaterThan(minValueWithGapAboveFee)); + Coin valueToRelease = pegoutRequestValue.toBitcoin(); + assertTrue(valueToRelease.isGreaterThan(minValueWithGapAboveFee)); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); RskAddress senderAddress = new RskAddress(SENDER.getAddress()); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); - co.rsk.core.Coin coin = co.rsk.core.Coin.fromBitcoin(value); - - verify(repository, times(1)).transfer(BRIDGE_ADDRESS, senderAddress, coin); - + verify(repository, times(1)).transfer(BRIDGE_ADDRESS, senderAddress, pegoutRequestValue); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); - assertEquals(1, logInfo.size()); verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); - verify(eventLogger, times(1)).logReleaseBtcRequestRejected( senderAddress, - value, + pegoutRequestValue, RejectedPegoutReason.LOW_AMOUNT ); - } - private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(Coin feePerKB, Coin value) throws IOException { - ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0); - + private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue( + Coin feePerKB, + co.rsk.core.Coin pegoutRequestValue + ) throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( - bridgeConstants, - activationMock, + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, logInfo, signatureCache )); - bridgeSupport = initBridgeSupport(eventLogger, activationMock); + bridgeSupport = initBridgeSupport(eventLogger, ACTIVATIONS_ALL); when(feePerKbSupport.getFeePerKb()).thenReturn(feePerKB); int pegoutSize = BridgeUtils.getRegularPegoutTxSize( - irisActivations, - federationStorageProvider.getNewFederation(federationConstants, irisActivations) + ACTIVATIONS_ALL, + federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, ACTIVATIONS_ALL) ); Coin minValueAccordingToFee = feePerKbSupport.getFeePerKb().div(1000).times(pegoutSize); - Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times(bridgeConstants.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100)); + Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times( + BRIDGE_CONSTANTS.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100)); - assertTrue(value.isLessThan(minValueWithGapAboveFee)); + Coin valueToRelease = pegoutRequestValue.toBitcoin(); + assertTrue(valueToRelease.isLessThan(minValueWithGapAboveFee)); - bridgeSupport.releaseBtc(buildReleaseRskTx(value)); - - RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); - co.rsk.core.Coin coin = co.rsk.core.Coin.fromBitcoin(value); - - verify(repository, times(1)).transfer(BRIDGE_ADDRESS, senderAddress, coin); + RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + verify(repository, times(1)).transfer(BRIDGE_ADDRESS, senderAddress, pegoutRequestValue); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); - assertEquals(1, logInfo.size()); verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); verify(eventLogger, times(1)).logReleaseBtcRequestRejected( senderAddress, - value, + pegoutRequestValue, RejectedPegoutReason.FEE_ABOVE_VALUE ); } @@ -1288,85 +1282,111 @@ private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue(Coin fe *********************************/ private UTXO buildUTXO() { - return new UTXO(Sha256Hash.wrap(TestUtils.generateBytes("utxo",32)), 0, Coin.COIN.multiply(2), 1, false, activeFederation.getP2SHScript()); + return new UTXO( + Sha256Hash.wrap(TestUtils.generateBytes("utxo",32)), + 0, + Coin.COIN.multiply(2), + 1, + false, + activeFederation.getP2SHScript() + ); } private Transaction buildReleaseRskTx() { - return buildReleaseRskTx(Coin.COIN); + return buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(Coin.COIN)); } - private Transaction buildReleaseRskTx(Coin coin) { + private Transaction buildReleaseRskTx(co.rsk.core.Coin coin) { Transaction releaseTransaction = Transaction .builder() .nonce(NONCE) .gasPrice(GAS_PRICE) .gasLimit(GAS_LIMIT) - .destination(PrecompiledContracts.BRIDGE_ADDR.toHexString()) + .destination(BRIDGE_ADDRESS) .data(Hex.decode(DATA)) - .chainId(Constants.REGTEST_CHAIN_ID) - .value(co.rsk.core.Coin.fromBitcoin(coin).asBigInteger()) + .chainId(Constants.MAINNET_CHAIN_ID) + .value(coin) .build(); releaseTransaction.sign(SENDER.getPrivKeyBytes()); return releaseTransaction; } - private Transaction buildReleaseRskTx_fromContract(Coin coin) { + private Transaction buildReleaseRskTx_fromContract(co.rsk.core.Coin coin) { Transaction releaseTransaction = Transaction .builder() .nonce(NONCE) .gasPrice(GAS_PRICE) .gasLimit(GAS_LIMIT) - .destination(PrecompiledContracts.BRIDGE_ADDR.toHexString()) + .destination(BRIDGE_ADDRESS) .data(Hex.decode(DATA)) - .chainId(Constants.REGTEST_CHAIN_ID) - .value(co.rsk.core.Coin.fromBitcoin(coin).asBigInteger()) + .chainId(Constants.MAINNET_CHAIN_ID) + .value(coin) .build(); releaseTransaction.sign(SENDER.getPrivKeyBytes()); - return new InternalTransaction(releaseTransaction.getHash().getBytes(), 400, 0, NONCE.toByteArray(), - DataWord.valueOf(GAS_PRICE.intValue()), DataWord.valueOf(GAS_LIMIT.intValue()), SENDER.getAddress(), - PrecompiledContracts.BRIDGE_ADDR.getBytes(), co.rsk.core.Coin.fromBitcoin(Coin.COIN).getBytes(), - Hex.decode(DATA), "", new BlockTxSignatureCache(new ReceivedTxSignatureCache())); + + return new InternalTransaction( + releaseTransaction.getHash().getBytes(), + 400, + 0, + NONCE.toByteArray(), + DataWord.valueOf(GAS_PRICE.intValue()), + DataWord.valueOf(GAS_LIMIT.intValue()), + SENDER.getAddress(), + BRIDGE_ADDRESS.getBytes(), + co.rsk.core.Coin.fromBitcoin(Coin.COIN).getBytes(), + Hex.decode(DATA), + "", + new BlockTxSignatureCache(new ReceivedTxSignatureCache()) + ); } private Transaction buildUpdateTx() { + final BigInteger value = new BigInteger("1"); + return Transaction .builder() .nonce(NONCE) .gasPrice(GAS_PRICE) .gasLimit(GAS_LIMIT) - .destination(Hex.decode(TO_ADDRESS)) + .destination(BRIDGE_ADDRESS) .data(Hex.decode(DATA)) - .chainId(Constants.REGTEST_CHAIN_ID) - .value(DUST_AMOUNT) + .chainId(Constants.MAINNET_CHAIN_ID) + .value(value) .build(); } - private BridgeSupport initBridgeSupport(BridgeEventLogger eventLogger, ActivationConfig.ForBlock activationMock) { + private BridgeSupport initBridgeSupport(BridgeEventLogger eventLogger, ActivationConfig.ForBlock activations) { FederationSupport federationSupport = FederationSupportBuilder.builder() - .withFederationConstants(federationConstants) + .withFederationConstants(FEDERATION_CONSTANTS) .withFederationStorageProvider(federationStorageProvider) .build(); return bridgeSupportBuilder - .withBridgeConstants(bridgeConstants) + .withBridgeConstants(BRIDGE_CONSTANTS) .withProvider(provider) .withRepository(repository) .withEventLogger(eventLogger) - .withActivations(activationMock) + .withActivations(activations) .withSignatureCache(signatureCache) .withFederationSupport(federationSupport) .withFeePerKbSupport(feePerKbSupport) .build(); } - private BridgeStorageProvider initProvider(Repository repository, ActivationConfig.ForBlock activationMock) { - return new BridgeStorageProvider(repository, PrecompiledContracts.BRIDGE_ADDR, networkParameters, activationMock); + private BridgeStorageProvider initProvider() { + return new BridgeStorageProvider( + repository, + BRIDGE_ADDRESS, + NETWORK_PARAMETERS, + ACTIVATIONS_ALL + ); } - private FederationStorageProvider initFederationStorageProvider(Repository repository, ActivationConfig.ForBlock activationMock) { + private FederationStorageProvider initFederationStorageProvider() { + UTXO utxo = buildUTXO(); StorageAccessor bridgeStorageAccessor = new BridgeStorageAccessorImpl(repository); FederationStorageProvider storageProvider = new FederationStorageProviderImpl(bridgeStorageAccessor); - storageProvider.getNewFederationBtcUTXOs(networkParameters, activationMock).add(utxo); + storageProvider.getNewFederationBtcUTXOs(NETWORK_PARAMETERS, ACTIVATIONS_ALL).add(utxo); storageProvider.setNewFederation(activeFederation); return storageProvider; @@ -1375,12 +1395,4 @@ private FederationStorageProvider initFederationStorageProvider(Repository repos private static Repository createRepository() { return new MutableRepository(new MutableTrieCache(new MutableTrieImpl(null, new Trie()))); } - - private static Federation getFederation() { - FederationArgs federationArgs = new FederationArgs(FederationTestUtils.getFederationMembers(3), - Instant.ofEpochMilli(1000), - 0L, - NetworkParameters.fromID(NetworkParameters.ID_REGTEST)); - return FederationFactory.buildStandardMultiSigFederation(federationArgs); - } } From feab88ae6ea619f7976d53fa74fb8d100e3d2b58 Mon Sep 17 00:00:00 2001 From: Marcos Date: Thu, 19 Sep 2024 17:41:31 -0300 Subject: [PATCH 07/17] Add tests for release rejected pre and post rskip427 --- .../rsk/peg/BridgeSupportReleaseBtcTest.java | 289 +++++++++++++++++- 1 file changed, 281 insertions(+), 8 deletions(-) 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 00f40aa87e3..2e18c2462dd 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -1264,17 +1264,290 @@ private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue( RskAddress senderAddress = new RskAddress(SENDER.getAddress()); - verify(repository, times(1)).transfer(BRIDGE_ADDRESS, senderAddress, pegoutRequestValue); + verify(repository, times(1)).transfer( + BRIDGE_ADDRESS, + senderAddress, + pegoutRequestValue + ); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); assertEquals(1, logInfo.size()); verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); + verify(eventLogger, times(1)).logReleaseBtcRequestRejected( + senderAddress, + pegoutRequestValue, + RejectedPegoutReason.FEE_ABOVE_VALUE + ); + } + + @Test + void low_amount_release_request_rejected_before_rskip427_value_in_satoshis() throws IOException { + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); + + List logInfo = new ArrayList<>(); + eventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + arrowheadActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(eventLogger, arrowheadActivations); + + Coin belowPegoutMinimumValue = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().minus(Coin.SATOSHI); + co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(belowPegoutMinimumValue); + + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); + + RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + + verify(repository, times(1)).transfer( + BRIDGE_ADDRESS, + senderAddress, + pegoutRequestValue + ); + + assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); + + assertEquals(1, logInfo.size()); + verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); + verify(eventLogger, times(1)).logReleaseBtcRequestRejected( + senderAddress, + pegoutRequestValue, + RejectedPegoutReason.LOW_AMOUNT + ); + + LogInfo firstLog = logInfo.get(0); + CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; + assertEquals(pegoutRequestValue.toBitcoin().longValue(), amount.longValue()); + } + + @Test + void low_amount_release_request_rejected_after_rskip427_value_in_weis() throws IOException { + List logInfo = new ArrayList<>(); + eventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(eventLogger, ACTIVATIONS_ALL); + + Coin belowPegoutMinimumValue = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().minus(Coin.SATOSHI); + co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(belowPegoutMinimumValue); + + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); + + RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + + verify(repository, times(1)).transfer( + BRIDGE_ADDRESS, + senderAddress, + pegoutRequestValue + ); + + assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); + + assertEquals(1, logInfo.size()); + verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); + verify(eventLogger, times(1)).logReleaseBtcRequestRejected( + senderAddress, + pegoutRequestValue, + RejectedPegoutReason.LOW_AMOUNT + ); + + LogInfo firstLog = logInfo.get(0); + CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; + assertEquals(pegoutRequestValue.asBigInteger(), amount); + } + + @Test + void contract_caller_release_request_rejected_before_rskip427_value_in_satoshis() throws IOException { + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); + List logInfo = new ArrayList<>(); + eventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + arrowheadActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(eventLogger, arrowheadActivations); + + co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()); + + bridgeSupport.releaseBtc(buildReleaseRskTx_fromContract(pegoutRequestValue)); + + RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + + verify(repository, never()).transfer(any(), any(), any()); + + assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); + + assertEquals(1, logInfo.size()); + verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); + verify(eventLogger, times(1)).logReleaseBtcRequestRejected( + senderAddress, + pegoutRequestValue, + RejectedPegoutReason.CALLER_CONTRACT + ); + + LogInfo firstLog = logInfo.get(0); + CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; + assertEquals(pegoutRequestValue.toBitcoin().longValue(), amount.longValue()); + } + + @Test + void contract_caller_release_request_rejected_after_rskip427_value_in_weis() throws IOException { + List logInfo = new ArrayList<>(); + eventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(eventLogger, ACTIVATIONS_ALL); + + co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()); + + bridgeSupport.releaseBtc(buildReleaseRskTx_fromContract(pegoutRequestValue)); + + RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + + verify(repository, never()).transfer(any(), any(), any()); + + assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); + + assertEquals(1, logInfo.size()); + verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); + verify(eventLogger, times(1)).logReleaseBtcRequestRejected( + senderAddress, + pegoutRequestValue, + RejectedPegoutReason.CALLER_CONTRACT + ); + + LogInfo firstLog = logInfo.get(0); + CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; + assertEquals(pegoutRequestValue.asBigInteger(), amount); + } + + @Test + void fee_above_value_release_request_rejected_before_rskip427_value_in_satoshis() throws IOException { + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); + + List logInfo = new ArrayList<>(); + eventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + arrowheadActivations, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(eventLogger, arrowheadActivations); + // Set a high fee per kb to ensure the resulting pegout is above the min pegout value + when(feePerKbSupport.getFeePerKb()).thenReturn(Coin.COIN); + + int pegoutSize = BridgeUtils.getRegularPegoutTxSize( + ACTIVATIONS_ALL, + federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, arrowheadActivations) + ); + Coin minValueAccordingToFee = feePerKbSupport.getFeePerKb().div(1000).times(pegoutSize); + Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times( + BRIDGE_CONSTANTS.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100) + ); + + Coin pegoutRequestValueWithGapAboveFee = minValueWithGapAboveFee.minus(Coin.SATOSHI); + co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(pegoutRequestValueWithGapAboveFee); + + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); + + RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + + verify(repository, times(1)).transfer( + BRIDGE_ADDRESS, + senderAddress, + pegoutRequestValue + ); + + assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); + + assertEquals(1, logInfo.size()); + verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); + verify(eventLogger, times(1)).logReleaseBtcRequestRejected( + senderAddress, + pegoutRequestValue, + RejectedPegoutReason.FEE_ABOVE_VALUE + ); + + LogInfo firstLog = logInfo.get(0); + CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; + assertEquals(pegoutRequestValue.toBitcoin().longValue(), amount.longValue()); + } + + @Test + void fee_above_value_release_request_rejected_after_rskip427_value_in_weis() throws IOException { + List logInfo = new ArrayList<>(); + eventLogger = spy(new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + ACTIVATIONS_ALL, + logInfo, + signatureCache + )); + bridgeSupport = initBridgeSupport(eventLogger, ACTIVATIONS_ALL); + // Set a high fee per kb to ensure the resulting pegout is above the min pegout value + when(feePerKbSupport.getFeePerKb()).thenReturn(Coin.COIN); + + int pegoutSize = BridgeUtils.getRegularPegoutTxSize( + ACTIVATIONS_ALL, + federationStorageProvider.getNewFederation(FEDERATION_CONSTANTS, ACTIVATIONS_ALL) + ); + Coin minValueAccordingToFee = feePerKbSupport.getFeePerKb().div(1000).times(pegoutSize); + Coin minValueWithGapAboveFee = minValueAccordingToFee.add(minValueAccordingToFee.times( + BRIDGE_CONSTANTS.getMinimumPegoutValuePercentageToReceiveAfterFee()).div(100) + ); + + Coin pegoutRequestValueWithGapAboveFee = minValueWithGapAboveFee.minus(Coin.SATOSHI); + co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(pegoutRequestValueWithGapAboveFee); + + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); + + RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + + verify(repository, times(1)).transfer( + BRIDGE_ADDRESS, + senderAddress, + pegoutRequestValue + ); + + assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); + + assertEquals(1, logInfo.size()); + verify(eventLogger, never()).logReleaseBtcRequestReceived(any(), any(), any()); verify(eventLogger, times(1)).logReleaseBtcRequestRejected( senderAddress, pegoutRequestValue, RejectedPegoutReason.FEE_ABOVE_VALUE ); + + LogInfo firstLog = logInfo.get(0); + CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + + BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; + assertEquals(pegoutRequestValue.asBigInteger(), amount); } /********************************** @@ -1328,13 +1601,13 @@ private Transaction buildReleaseRskTx_fromContract(co.rsk.core.Coin coin) { releaseTransaction.getHash().getBytes(), 400, 0, - NONCE.toByteArray(), - DataWord.valueOf(GAS_PRICE.intValue()), - DataWord.valueOf(GAS_LIMIT.intValue()), - SENDER.getAddress(), - BRIDGE_ADDRESS.getBytes(), - co.rsk.core.Coin.fromBitcoin(Coin.COIN).getBytes(), - Hex.decode(DATA), + releaseTransaction.getNonce(), + DataWord.valueOf(releaseTransaction.getGasPrice().asBigInteger().longValue()), + DataWord.valueOf(releaseTransaction.getGasLimit()), + releaseTransaction.getSender().getBytes(), + releaseTransaction.getReceiveAddress().getBytes(), + releaseTransaction.getValue().getBytes(), + releaseTransaction.getData(), "", new BlockTxSignatureCache(new ReceivedTxSignatureCache()) ); From 36e11aa80221d049b67dacb89dde69c111a3131d Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 20 Sep 2024 13:43:12 -0300 Subject: [PATCH 08/17] Update variable and test names --- .../src/main/java/co/rsk/peg/BridgeSupport.java | 12 ++++++++---- .../java/co/rsk/peg/BridgeSupportReleaseBtcTest.java | 2 +- 2 files changed, 9 insertions(+), 5 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 de125926417..0a3145e25d0 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -839,19 +839,23 @@ public void releaseBtc(Transaction rskTx) throws IOException { requestRelease(btcDestinationAddress, pegoutValueInWeis, rskTx); } - private void refundAndEmitRejectEvent(co.rsk.core.Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { + private void refundAndEmitRejectEvent( + co.rsk.core.Coin releaseRequestedValue, + RskAddress senderAddress, + RejectedPegoutReason reason + ) { logger.trace( "[refundAndEmitRejectEvent] Executing a refund of {} to {}. Reason: {}", - value, + releaseRequestedValue, senderAddress, reason ); rskRepository.transfer( PrecompiledContracts.BRIDGE_ADDR, senderAddress, - value + releaseRequestedValue ); - emitRejectEvent(value, senderAddress, reason); + emitRejectEvent(releaseRequestedValue, senderAddress, reason); } private void emitRejectEvent(co.rsk.core.Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { 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 2e18c2462dd..66fb660b490 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -161,7 +161,7 @@ void eventLogger_logReleaseBtcRequested_release_before_papyrus_and_updateCollect } @Test - void handmade_release_before_rskip_146_185() throws IOException { + void handmade_release_before_rskip_146_185_no_events_emitted() throws IOException { ActivationConfig.ForBlock wasabiActivations = ActivationConfigsForTest.wasabi100().forBlock(0L); bridgeSupport = initBridgeSupport(eventLogger, wasabiActivations); From 3f5b3b9df71eeaecec6aa53d337a820b05d6e65f Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 20 Sep 2024 13:50:53 -0300 Subject: [PATCH 09/17] Refactor buildReleaseRskTx_fromContract method --- .../rsk/peg/BridgeSupportReleaseBtcTest.java | 31 ++++++------------- 1 file changed, 10 insertions(+), 21 deletions(-) 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 66fb660b490..5f3f5a60689 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -21,6 +21,7 @@ import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.*; +import co.rsk.RskTestUtils; import co.rsk.bitcoinj.core.*; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; @@ -1584,30 +1585,18 @@ private Transaction buildReleaseRskTx(co.rsk.core.Coin coin) { return releaseTransaction; } - private Transaction buildReleaseRskTx_fromContract(co.rsk.core.Coin coin) { - Transaction releaseTransaction = Transaction - .builder() - .nonce(NONCE) - .gasPrice(GAS_PRICE) - .gasLimit(GAS_LIMIT) - .destination(BRIDGE_ADDRESS) - .data(Hex.decode(DATA)) - .chainId(Constants.MAINNET_CHAIN_ID) - .value(coin) - .build(); - releaseTransaction.sign(SENDER.getPrivKeyBytes()); - + private Transaction buildReleaseRskTx_fromContract(co.rsk.core.Coin pegoutRequestValue) { return new InternalTransaction( - releaseTransaction.getHash().getBytes(), + RskTestUtils.createHash(4).getBytes(), 400, 0, - releaseTransaction.getNonce(), - DataWord.valueOf(releaseTransaction.getGasPrice().asBigInteger().longValue()), - DataWord.valueOf(releaseTransaction.getGasLimit()), - releaseTransaction.getSender().getBytes(), - releaseTransaction.getReceiveAddress().getBytes(), - releaseTransaction.getValue().getBytes(), - releaseTransaction.getData(), + NONCE.toByteArray(), + DataWord.valueOf(GAS_PRICE.longValue()), + DataWord.valueOf(GAS_LIMIT.longValue()), + SENDER.getAddress(), + BRIDGE_ADDRESS.getBytes(), + pegoutRequestValue.getBytes(), + Hex.decode(DATA), "", new BlockTxSignatureCache(new ReceivedTxSignatureCache()) ); From d644788c36fbb3a2d6a5e18df5056ac5ca90c022 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 20 Sep 2024 16:26:46 -0300 Subject: [PATCH 10/17] Refactor BridgeEvents --- .../main/java/co/rsk/peg/BridgeEvents.java | 175 ++++++++---------- 1 file changed, 73 insertions(+), 102 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeEvents.java b/rskj-core/src/main/java/co/rsk/peg/BridgeEvents.java index 6ea69bfb988..9202aebebfe 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeEvents.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeEvents.java @@ -5,110 +5,80 @@ public enum BridgeEvents { - LOCK_BTC("lock_btc", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.RECEIVER, SolidityType.getType(SolidityType.ADDRESS)), - new CallTransaction.Param(false, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, "senderBtcAddress", SolidityType.getType(SolidityType.STRING)), - new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.INT256)) - } - ), - PEGIN_BTC("pegin_btc", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.RECEIVER, SolidityType.getType(SolidityType.ADDRESS)), - new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.INT256)), - new CallTransaction.Param(false, "protocolVersion", SolidityType.getType(SolidityType.INT256)) - } - ), - REJECTED_PEGIN("rejected_pegin", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, Fields.REASON, SolidityType.getType(SolidityType.INT256)) - } - ), - UNREFUNDABLE_PEGIN("unrefundable_pegin", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, Fields.REASON, SolidityType.getType(SolidityType.INT256)) - } - ), - UPDATE_COLLECTIONS("update_collections", - new CallTransaction.Param[]{ - new CallTransaction.Param(false, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)) - } - ), - ADD_SIGNATURE("add_signature", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.RELEASE_RSK_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(true, "federatorRskAddress", SolidityType.getType(SolidityType.ADDRESS)), - new CallTransaction.Param(false, "federatorBtcPublicKey", SolidityType.getType(SolidityType.BYTES)) - } - ), - RELEASE_BTC("release_btc", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.RELEASE_RSK_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, "btcRawTransaction", SolidityType.getType(SolidityType.BYTES)) - } - ), - COMMIT_FEDERATION("commit_federation", - new CallTransaction.Param[]{ - new CallTransaction.Param(false, "oldFederationBtcPublicKeys", SolidityType.getType(SolidityType.BYTES)), - new CallTransaction.Param(false, "oldFederationBtcAddress", SolidityType.getType(SolidityType.STRING)), - new CallTransaction.Param(false, "newFederationBtcPublicKeys", SolidityType.getType(SolidityType.BYTES)), - new CallTransaction.Param(false, "newFederationBtcAddress", SolidityType.getType(SolidityType.STRING)), - new CallTransaction.Param(false, "activationHeight", SolidityType.getType(SolidityType.INT256)) - } - ), - RELEASE_REQUESTED("release_requested", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, "rskTxHash", SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)) - } - ), - RELEASE_REQUEST_RECEIVED_LEGACY("release_request_received", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)), - new CallTransaction.Param(false, "btcDestinationAddress", SolidityType.getType(SolidityType.BYTES)), - new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)) - } - ), - RELEASE_REQUEST_REJECTED("release_request_rejected", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)), - new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)), - new CallTransaction.Param(false, Fields.REASON, SolidityType.getType(SolidityType.INT256)) - } - ), - BATCH_PEGOUT_CREATED("batch_pegout_created", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, Fields.RELEASE_RSK_TX_HASHES, SolidityType.getType(SolidityType.BYTES)) - } - ), - RELEASE_REQUEST_RECEIVED("release_request_received", - new CallTransaction.Param[]{ + LOCK_BTC("lock_btc", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.RECEIVER, SolidityType.getType(SolidityType.ADDRESS)), + new CallTransaction.Param(false, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, "senderBtcAddress", SolidityType.getType(SolidityType.STRING)), + new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.INT256)) + }), + PEGIN_BTC("pegin_btc", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.RECEIVER, SolidityType.getType(SolidityType.ADDRESS)), + new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.INT256)), + new CallTransaction.Param(false, "protocolVersion", SolidityType.getType(SolidityType.INT256)) + }), + REJECTED_PEGIN("rejected_pegin", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, Fields.REASON, SolidityType.getType(SolidityType.INT256)) + }), + UNREFUNDABLE_PEGIN("unrefundable_pegin", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, Fields.REASON, SolidityType.getType(SolidityType.INT256)) + }), + UPDATE_COLLECTIONS("update_collections", new CallTransaction.Param[] { + new CallTransaction.Param(false, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)) + }), + ADD_SIGNATURE("add_signature", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.RELEASE_RSK_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(true, "federatorRskAddress", SolidityType.getType(SolidityType.ADDRESS)), + new CallTransaction.Param(false, "federatorBtcPublicKey", SolidityType.getType(SolidityType.BYTES)) + }), + RELEASE_BTC("release_btc", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.RELEASE_RSK_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, "btcRawTransaction", SolidityType.getType(SolidityType.BYTES)) + }), + COMMIT_FEDERATION("commit_federation", new CallTransaction.Param[] { + new CallTransaction.Param(false, "oldFederationBtcPublicKeys", SolidityType.getType(SolidityType.BYTES)), + new CallTransaction.Param(false, "oldFederationBtcAddress", SolidityType.getType(SolidityType.STRING)), + new CallTransaction.Param(false, "newFederationBtcPublicKeys", SolidityType.getType(SolidityType.BYTES)), + new CallTransaction.Param(false, "newFederationBtcAddress", SolidityType.getType(SolidityType.STRING)), + new CallTransaction.Param(false, "activationHeight", SolidityType.getType(SolidityType.INT256)) + }), + RELEASE_REQUESTED("release_requested", new CallTransaction.Param[] { + new CallTransaction.Param(true, "rskTxHash", SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)) + }), + RELEASE_REQUEST_RECEIVED_LEGACY("release_request_received", new CallTransaction.Param[] { new CallTransaction.Param(true, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)), - new CallTransaction.Param(false, "btcDestinationAddress", SolidityType.getType(SolidityType.STRING)), - new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)) - } - ), - PEGOUT_CONFIRMED("pegout_confirmed", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, "pegoutCreationRskBlockNumber", SolidityType.getType(SolidityType.UINT256)) - } - ), - PEGOUT_TRANSACTION_CREATED("pegout_transaction_created", - new CallTransaction.Param[]{ - new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), - new CallTransaction.Param(false, Fields.UTXO_OUTPOINT_VALUES, SolidityType.getType(SolidityType.BYTES)) - } - ); + new CallTransaction.Param(false, Fields.BTC_DESTINATION_ADDRESS, SolidityType.getType(SolidityType.BYTES)), + new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)) + }), + RELEASE_REQUEST_REJECTED("release_request_rejected", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)), + new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)), + new CallTransaction.Param(false, Fields.REASON, SolidityType.getType(SolidityType.INT256)) + }), + BATCH_PEGOUT_CREATED("batch_pegout_created", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, Fields.RELEASE_RSK_TX_HASHES, SolidityType.getType(SolidityType.BYTES)) + }), + RELEASE_REQUEST_RECEIVED("release_request_received", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.SENDER, SolidityType.getType(SolidityType.ADDRESS)), + new CallTransaction.Param(false, Fields.BTC_DESTINATION_ADDRESS, SolidityType.getType(SolidityType.STRING)), + new CallTransaction.Param(false, Fields.AMOUNT, SolidityType.getType(SolidityType.UINT256)) + }), + PEGOUT_CONFIRMED("pegout_confirmed", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, "pegoutCreationRskBlockNumber", SolidityType.getType(SolidityType.UINT256)) + }), + PEGOUT_TRANSACTION_CREATED("pegout_transaction_created", new CallTransaction.Param[] { + new CallTransaction.Param(true, Fields.BTC_TX_HASH, SolidityType.getType(SolidityType.BYTES32)), + new CallTransaction.Param(false, Fields.UTXO_OUTPOINT_VALUES, SolidityType.getType(SolidityType.BYTES)) + }); - private String eventName; - private CallTransaction.Param[] params; + private final String eventName; + private final CallTransaction.Param[] params; BridgeEvents(String eventName, CallTransaction.Param[] params) { this.eventName = eventName; @@ -128,5 +98,6 @@ private static class Fields { private static final String RELEASE_RSK_TX_HASH = "releaseRskTxHash"; private static final String RELEASE_RSK_TX_HASHES = "releaseRskTxHashes"; private static final String UTXO_OUTPOINT_VALUES = "utxoOutpointValues"; + private static final String BTC_DESTINATION_ADDRESS = "btcDestinationAddress"; } } From 66d495764ef22231649f003f91fea1739e3cfa8f Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 20 Sep 2024 16:59:57 -0300 Subject: [PATCH 11/17] Change logReleaseBtcRequestReceived signature to receive the value as weis --- .../co/rsk/peg/utils/BridgeEventLogger.java | 2 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 16 ++- .../peg/utils/BrigeEventLoggerLegacyImpl.java | 7 +- .../peg/utils/BridgeEventLoggerImplTest.java | 74 +++++++--- .../BridgeEventLoggerLegacyImplTest.java | 127 +++++++++--------- .../rsk/peg/utils/BridgeEventLoggerTest.java | 17 ++- 6 files changed, 150 insertions(+), 93 deletions(-) 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 3df8ef6c255..20df205ea00 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 @@ -63,7 +63,7 @@ default void logUnrefundablePegin(BtcTransaction btcTx, UnrefundablePeginReason throw new UnsupportedOperationException(); } - default void logReleaseBtcRequestReceived(String sender, Address btcDestinationAddress, Coin amount) { + default void logReleaseBtcRequestReceived(RskAddress sender, Address btcDestinationAddress, co.rsk.core.Coin amount) { throw new UnsupportedOperationException(); } 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 07c9621f4cf..f86d6c65d27 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 @@ -192,11 +192,11 @@ public void logUnrefundablePegin(BtcTransaction btcTx, UnrefundablePeginReason r } @Override - public void logReleaseBtcRequestReceived(String sender, Address btcDestinationAddress, Coin amount) { + public void logReleaseBtcRequestReceived(RskAddress sender, Address btcDestinationAddress, co.rsk.core.Coin amount) { if (activations.isActive(ConsensusRule.RSKIP326)) { - logReleaseBtcRequestReceived(sender, btcDestinationAddress.toString(), amount); + logReleaseBtcRequestReceived(sender.toHexString(), btcDestinationAddress.toString(), amount); } else { - logReleaseBtcRequestReceived(sender, btcDestinationAddress.getHash160(), amount); + logReleaseBtcRequestReceived(sender.toHexString(), btcDestinationAddress.getHash160(), amount.toBitcoin()); } } @@ -204,15 +204,20 @@ private void logReleaseBtcRequestReceived(String sender, byte[] btcDestinationAd CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(); byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender); List encodedTopics = LogInfo.byteArrayToList(encodedTopicsInBytes); + byte[] encodedData = event.encodeEventData(btcDestinationAddress, amount.getValue()); + this.logs.add(new LogInfo(BRIDGE_CONTRACT_ADDRESS, encodedTopics, encodedData)); } - private void logReleaseBtcRequestReceived(String sender, String btcDestinationAddress, Coin amount) { + private void logReleaseBtcRequestReceived(String sender, String btcDestinationAddress, co.rsk.core.Coin amount) { CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(); byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender); List encodedTopics = LogInfo.byteArrayToList(encodedTopicsInBytes); - byte[] encodedData = event.encodeEventData(btcDestinationAddress, amount.getValue()); + + byte[] encodedData = activations.isActive(ConsensusRule.RSKIP427) ? + event.encodeEventData(btcDestinationAddress, amount.asBigInteger()) : + event.encodeEventData(btcDestinationAddress, amount.toBitcoin().getValue()); this.logs.add(new LogInfo(BRIDGE_CONTRACT_ADDRESS, encodedTopics, encodedData)); } @@ -222,6 +227,7 @@ public void logReleaseBtcRequestRejected(RskAddress sender, co.rsk.core.Coin amo CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender.toHexString()); List encodedTopics = LogInfo.byteArrayToList(encodedTopicsInBytes); + byte[] encodedData = activations.isActive(ConsensusRule.RSKIP427) ? event.encodeEventData(amount.asBigInteger(), reason.getValue()) : event.encodeEventData(amount.toBitcoin().getValue(), reason.getValue()); 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 7f3b04ab9db..7d367aba716 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 @@ -56,7 +56,12 @@ public class BrigeEventLoggerLegacyImpl implements BridgeEventLogger { private final SignatureCache signatureCache; private final List logs; - public BrigeEventLoggerLegacyImpl(BridgeConstants bridgeConstants, ActivationConfig.ForBlock activations, List logs, SignatureCache signatureCache) { + public BrigeEventLoggerLegacyImpl( + BridgeConstants bridgeConstants, + ActivationConfig.ForBlock activations, + List logs, + SignatureCache signatureCache + ) { this.bridgeConstants = bridgeConstants; this.activations = activations; this.signatureCache = signatureCache; 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 c76b2a40464..5330ddeb65c 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 @@ -75,7 +75,12 @@ void setup() { signatureCache = new BlockTxSignatureCache(new ReceivedTxSignatureCache()); eventLogs = new LinkedList<>(); - eventLogger = new BridgeEventLoggerImpl(BRIDGE_CONSTANTS, activations, eventLogs, signatureCache); + eventLogger = new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + activations, + eventLogs, + signatureCache + ); } @Test @@ -411,18 +416,23 @@ void logUnrefundablePegin() { } @Test - void testLogReleaseBtcRequestReceivedBeforeRSKIP326HardFork() { - ActivationConfig.ForBlock hopActivations = ActivationConfigsForTest.hop400().forBlock(0); - eventLogger = new BridgeEventLoggerImpl(BRIDGE_CONSTANTS, hopActivations, eventLogs, signatureCache); + void logReleaseBtcRequestReceived_preRSKIP326_destinationAddressAsHash160() { + ActivationConfig.ForBlock hopActivations = ActivationConfigsForTest.hop400().forBlock(0L); + eventLogger = new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + hopActivations, + eventLogs, + signatureCache + ); Address btcRecipientAddress = new Address( NETWORK_PARAMETERS, NETWORK_PARAMETERS.getP2SHHeader(), Hex.decode("6bf06473af5f595cf97702229b007e50d6cfba83") ); - Coin amount = Coin.COIN; + co.rsk.core.Coin amount = co.rsk.core.Coin.fromBitcoin(Coin.COIN); - eventLogger.logReleaseBtcRequestReceived(RSK_ADDRESS.toString(), btcRecipientAddress, amount); + eventLogger.logReleaseBtcRequestReceived(RSK_ADDRESS, btcRecipientAddress, amount); commonAssertLogs(eventLogs); assertTopics(2, eventLogs); @@ -430,21 +440,29 @@ void testLogReleaseBtcRequestReceivedBeforeRSKIP326HardFork() { eventLogs, 0, BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(), - new Object[]{RSK_ADDRESS.toString()}, - new Object[]{btcRecipientAddress.getHash160(), amount.value} + new Object[]{RSK_ADDRESS.toHexString()}, + new Object[]{btcRecipientAddress.getHash160(), amount.toBitcoin().getValue()} ); } @Test - void testLogReleaseBtcRequestReceivedAfterRSKIP326HardFork() { + void logReleaseBtcRequestReceived_postRSKIP326_destinationAddressAsBase58() { + ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); + eventLogger = new BridgeEventLoggerImpl( + BRIDGE_CONSTANTS, + arrowheadActivations, + eventLogs, + signatureCache + ); + Address btcRecipientAddress = new Address( NETWORK_PARAMETERS, NETWORK_PARAMETERS.getP2SHHeader(), Hex.decode("6bf06473af5f595cf97702229b007e50d6cfba83") ); - Coin amount = Coin.COIN; + co.rsk.core.Coin amount = co.rsk.core.Coin.fromBitcoin(Coin.COIN); - eventLogger.logReleaseBtcRequestReceived(RSK_ADDRESS.toString(), btcRecipientAddress, amount); + eventLogger.logReleaseBtcRequestReceived(RSK_ADDRESS, btcRecipientAddress, amount); commonAssertLogs(eventLogs); assertTopics(2, eventLogs); @@ -452,13 +470,35 @@ void testLogReleaseBtcRequestReceivedAfterRSKIP326HardFork() { eventLogs, 0, BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(), - new Object[]{RSK_ADDRESS.toString()}, - new Object[]{btcRecipientAddress.toString(), amount.value} + new Object[]{RSK_ADDRESS.toHexString()}, + new Object[]{btcRecipientAddress.toString(), amount.toBitcoin().getValue()} + ); + } + + @Test + void logReleaseBtcRequestReceived_postRSKIP427_amountAsWeis() { + Address btcRecipientAddress = new Address( + NETWORK_PARAMETERS, + NETWORK_PARAMETERS.getP2SHHeader(), + Hex.decode("6bf06473af5f595cf97702229b007e50d6cfba83") + ); + co.rsk.core.Coin amount = co.rsk.core.Coin.fromBitcoin(Coin.COIN); + + eventLogger.logReleaseBtcRequestReceived(RSK_ADDRESS, btcRecipientAddress, amount); + + commonAssertLogs(eventLogs); + assertTopics(2, eventLogs); + assertEvent( + eventLogs, + 0, + BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(), + new Object[]{RSK_ADDRESS.toHexString()}, + new Object[]{btcRecipientAddress.toString(), amount.asBigInteger()} ); } @Test - void testLogReleaseBtcRequestRejected_preRSKIP427_logAmountAsSatoshis() { + void logReleaseBtcRequestRejected_preRSKIP427_logAmountAsSatoshis() { ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0); eventLogger = new BridgeEventLoggerImpl(BRIDGE_CONSTANTS, arrowheadActivations, eventLogs, signatureCache); @@ -473,13 +513,13 @@ void testLogReleaseBtcRequestRejected_preRSKIP427_logAmountAsSatoshis() { eventLogs, 0, BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(), - new Object[]{RSK_ADDRESS.toString()}, + new Object[]{RSK_ADDRESS.toHexString()}, new Object[]{amount.toBitcoin().getValue(), reason.getValue()} ); } @Test - void testLogReleaseBtcRequestRejected_postRSKIP427_logAmountAsWeis() { + void logReleaseBtcRequestRejected_postRSKIP427_logAmountAsWeis() { co.rsk.core.Coin amount = co.rsk.core.Coin.valueOf(100_000_000_000_000_000L); RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; @@ -491,7 +531,7 @@ void testLogReleaseBtcRequestRejected_postRSKIP427_logAmountAsWeis() { eventLogs, 0, BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(), - new Object[]{RSK_ADDRESS.toString()}, + new Object[]{RSK_ADDRESS.toHexString()}, new Object[]{amount.asBigInteger(), reason.getValue()} ); } 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 fa0e9d175ae..822f232f1ac 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 @@ -18,49 +18,39 @@ package co.rsk.peg.utils; +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 co.rsk.RskTestUtils; import co.rsk.bitcoinj.core.*; -import co.rsk.peg.constants.BridgeConstants; -import co.rsk.peg.constants.BridgeRegTestConstants; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; -import co.rsk.peg.*; +import co.rsk.peg.Bridge; +import co.rsk.peg.DeprecatedMethodCallException; +import co.rsk.peg.constants.BridgeConstants; +import co.rsk.peg.constants.BridgeRegTestConstants; import co.rsk.peg.federation.*; -import co.rsk.peg.PegTestUtils; import co.rsk.peg.federation.constants.FederationConstants; -import org.bouncycastle.util.encoders.Hex; -import org.ethereum.config.blockchain.upgrades.ActivationConfig; -import org.ethereum.config.blockchain.upgrades.ConsensusRule; -import org.ethereum.core.*; -import org.ethereum.util.RLP; -import org.ethereum.util.RLPElement; -import org.ethereum.util.RLPList; -import org.ethereum.vm.DataWord; -import org.ethereum.vm.LogInfo; -import org.ethereum.vm.PrecompiledContracts; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.time.Instant; import java.util.*; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.ArgumentMatchers.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import org.bouncycastle.util.encoders.Hex; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; +import org.ethereum.core.*; +import org.ethereum.util.*; +import org.ethereum.vm.*; +import org.junit.jupiter.api.*; /** * Test class for BridgeEventLoggerLegacyImpl. * * @author kelvin.isievwore */ - class BridgeEventLoggerLegacyImplTest { - private ActivationConfig.ForBlock activations; private List eventLogs; private BridgeEventLogger eventLogger; @@ -73,9 +63,14 @@ void setup() { activations = mock(ActivationConfig.ForBlock.class); eventLogs = new LinkedList<>(); constantsMock = mock(BridgeConstants.class); - eventLogger = new BrigeEventLoggerLegacyImpl(constantsMock, activations, eventLogs, new BlockTxSignatureCache(new ReceivedTxSignatureCache())); + eventLogger = new BrigeEventLoggerLegacyImpl( + constantsMock, + activations, + eventLogs, + new BlockTxSignatureCache(new ReceivedTxSignatureCache()) + ); btcTxMock = mock(BtcTransaction.class); - rskTxHash = PegTestUtils.createHash3(1); + rskTxHash = RskTestUtils.createHash(1); } @Test @@ -84,8 +79,7 @@ void testLogUpdateCollectionsBeforeRskip146() { // Setup Rsk transaction Transaction tx = mock(Transaction.class); - RskAddress sender = mock(RskAddress.class); - when(sender.toString()).thenReturn("0x0000000000000000000000000000000000000001"); + RskAddress sender = new RskAddress("0x0000000000000000000000000000000000000001"); when(tx.getSender(any(SignatureCache.class))).thenReturn(sender); // Act @@ -97,12 +91,12 @@ void testLogUpdateCollectionsBeforeRskip146() { LogInfo logResult = eventLogs.get(0); List topics = Collections.singletonList(Bridge.UPDATE_COLLECTIONS_TOPIC); for (int i = 0; i < topics.size(); i++) { - Assertions.assertEquals(topics.get(i), logResult.getTopics().get(i)); + assertEquals(topics.get(i), logResult.getTopics().get(i)); } // Assert log data byte[] encodedData = RLP.encodeElement(tx.getSender(new BlockTxSignatureCache(new ReceivedTxSignatureCache())).getBytes()); - Assertions.assertArrayEquals(encodedData, logResult.getData()); + assertArrayEquals(encodedData, logResult.getData()); } @Test @@ -130,21 +124,21 @@ void testLogAddSignatureBeforeRskip146() { LogInfo logResult = eventLogs.get(0); // Assert address that made the log - Assertions.assertEquals(PrecompiledContracts.BRIDGE_ADDR, new RskAddress(logResult.getAddress())); + assertEquals(PrecompiledContracts.BRIDGE_ADDR, new RskAddress(logResult.getAddress())); // Assert log topics - Assertions.assertEquals(1, logResult.getTopics().size()); - Assertions.assertEquals(Bridge.ADD_SIGNATURE_TOPIC, logResult.getTopics().get(0)); + assertEquals(1, logResult.getTopics().size()); + assertEquals(Bridge.ADD_SIGNATURE_TOPIC, logResult.getTopics().get(0)); // Assert log data - Assertions.assertNotNull(logResult.getData()); + assertNotNull(logResult.getData()); List rlpData = RLP.decode2(logResult.getData()); Assertions.assertEquals(1, rlpData.size()); RLPList dataList = (RLPList) rlpData.get(0); - Assertions.assertEquals(3, dataList.size()); - Assertions.assertArrayEquals(btcTxMock.getHashAsString().getBytes(), dataList.get(0).getRLPData()); - Assertions.assertArrayEquals(federatorPubKey.getPubKeyHash(), dataList.get(1).getRLPData()); - Assertions.assertArrayEquals(rskTxHash.getBytes(), dataList.get(2).getRLPData()); + assertEquals(3, dataList.size()); + assertArrayEquals(btcTxMock.getHashAsString().getBytes(), dataList.get(0).getRLPData()); + assertArrayEquals(federatorPubKey.getPubKeyHash(), dataList.get(1).getRLPData()); + assertArrayEquals(rskTxHash.getBytes(), dataList.get(2).getRLPData()); } @Test @@ -172,18 +166,18 @@ void testLogReleaseBtcBeforeRskip146() { LogInfo logResult = eventLogs.get(0); // Assert address that made the log - Assertions.assertEquals(PrecompiledContracts.BRIDGE_ADDR, new RskAddress(logResult.getAddress())); + assertEquals(PrecompiledContracts.BRIDGE_ADDR, new RskAddress(logResult.getAddress())); // Assert log topics - Assertions.assertEquals(1, logResult.getTopics().size()); + assertEquals(1, logResult.getTopics().size()); List topics = Collections.singletonList(Bridge.RELEASE_BTC_TOPIC); for (int i = 0; i < topics.size(); i++) { - Assertions.assertEquals(topics.get(i), logResult.getTopics().get(i)); + assertEquals(topics.get(i), logResult.getTopics().get(i)); } // Assert log data byte[] encodedData = RLP.encodeList(RLP.encodeString(btcTx.getHashAsString()), RLP.encodeElement(btcTx.bitcoinSerialize())); - Assertions.assertArrayEquals(encodedData, logResult.getData()); + assertArrayEquals(encodedData, logResult.getData()); } @Test @@ -233,49 +227,55 @@ void testLogCommitFederationBeforeRskip146() { eventLogger.logCommitFederation(executionBlock, oldFederation, newFederation); // Assert log size - Assertions.assertEquals(1, eventLogs.size()); + assertEquals(1, eventLogs.size()); LogInfo logResult = eventLogs.get(0); // Assert address that made the log - Assertions.assertEquals(PrecompiledContracts.BRIDGE_ADDR, new RskAddress(logResult.getAddress())); + assertEquals(PrecompiledContracts.BRIDGE_ADDR, new RskAddress(logResult.getAddress())); // Assert log topics - Assertions.assertEquals(1, logResult.getTopics().size()); - Assertions.assertEquals(Bridge.COMMIT_FEDERATION_TOPIC, logResult.getTopics().get(0)); + assertEquals(1, logResult.getTopics().size()); + assertEquals(Bridge.COMMIT_FEDERATION_TOPIC, logResult.getTopics().get(0)); // Assert log data - Assertions.assertNotNull(logResult.getData()); + assertNotNull(logResult.getData()); List rlpData = RLP.decode2(logResult.getData()); - Assertions.assertEquals(1, rlpData.size()); + assertEquals(1, rlpData.size()); RLPList dataList = (RLPList) rlpData.get(0); - Assertions.assertEquals(3, dataList.size()); + assertEquals(3, dataList.size()); // Assert old federation data RLPList oldFedData = (RLPList) dataList.get(0); - Assertions.assertEquals(2, oldFedData.size()); - Assertions.assertArrayEquals(oldFederation.getAddress().getHash160(), oldFedData.get(0).getRLPData()); + assertEquals(2, oldFedData.size()); + assertArrayEquals(oldFederation.getAddress().getHash160(), oldFedData.get(0).getRLPData()); RLPList oldFedPubKeys = (RLPList) oldFedData.get(1); - Assertions.assertEquals(4, oldFedPubKeys.size()); + assertEquals(4, oldFedPubKeys.size()); for (int i = 0; i < 4; i++) { - Assertions.assertEquals(oldFederation.getBtcPublicKeys().get(i), BtcECKey.fromPublicOnly(oldFedPubKeys.get(i).getRLPData())); + assertEquals(oldFederation.getBtcPublicKeys().get(i), BtcECKey.fromPublicOnly(oldFedPubKeys.get(i).getRLPData())); } // Assert new federation data RLPList newFedData = (RLPList) dataList.get(1); - Assertions.assertEquals(2, newFedData.size()); - Assertions.assertArrayEquals(newFederation.getAddress().getHash160(), newFedData.get(0).getRLPData()); + assertEquals(2, newFedData.size()); + assertArrayEquals(newFederation.getAddress().getHash160(), newFedData.get(0).getRLPData()); RLPList newFedPubKeys = (RLPList) newFedData.get(1); - Assertions.assertEquals(3, newFedPubKeys.size()); + assertEquals(3, newFedPubKeys.size()); for (int i = 0; i < 3; i++) { - Assertions.assertEquals(newFederation.getBtcPublicKeys().get(i), BtcECKey.fromPublicOnly(newFedPubKeys.get(i).getRLPData())); + assertEquals( + newFederation.getBtcPublicKeys().get(i), + BtcECKey.fromPublicOnly(newFedPubKeys.get(i).getRLPData()) + ); } // Assert new federation activation block number FederationConstants federationConstants = constantsMock.getFederationConstants(); - Assertions.assertEquals(15L + federationConstants.getFederationActivationAge(activations), Long.valueOf(new String(dataList.get(2).getRLPData(), StandardCharsets.UTF_8)).longValue()); + assertEquals( + 15L + federationConstants.getFederationActivationAge(activations), + Long.valueOf(new String(dataList.get(2).getRLPData(), StandardCharsets.UTF_8)).longValue() + ); } @Test @@ -284,7 +284,10 @@ void testLogCommitFederationAfterRskip146() { when(activations.isActive(ConsensusRule.RSKIP146)).thenReturn(true); // Act - assertThrows(DeprecatedMethodCallException.class, () -> eventLogger.logCommitFederation(mock(Block.class), mock(Federation.class), mock(Federation.class))); + assertThrows( + DeprecatedMethodCallException.class, + () -> eventLogger.logCommitFederation(mock(Block.class), mock(Federation.class), mock(Federation.class)) + ); } /********************************** diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java index 01f913e03e2..d2424935a6e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java @@ -4,6 +4,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; +import co.rsk.RskTestUtils; import co.rsk.bitcoinj.core.*; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; @@ -22,7 +23,7 @@ class BridgeEventLoggerTest { void setup() { eventLogger = spy(BridgeEventLogger.class); btcTxMock = mock(BtcTransaction.class); - rskTxHash = PegTestUtils.createHash3(1); + rskTxHash = RskTestUtils.createHash(1); } @Test @@ -73,11 +74,13 @@ void testLogUnrefundablePegin() { @Test void testLogReleaseBtcRequestReceived() { - String sender = "0x00000000000000000000000000000000000000"; - String base58Address = "mipcBbFg9gMiCh81Kj8tqqdgoZub1ZJRfn"; + RskAddress sender = new RskAddress("0x00000000000000000000000000000000001001"); + String base58Address = "16SL1Qsw1eyYWM58MFh9KwKYoxYmm3fM1Z"; Address btcDestinationAddress = Address.fromBase58( - NetworkParameters.fromID(NetworkParameters.ID_REGTEST), base58Address); - Coin amount = Coin.COIN; + NetworkParameters.fromID(NetworkParameters.ID_MAINNET), + base58Address + ); + co.rsk.core.Coin amount = co.rsk.core.Coin.fromBitcoin(Coin.COIN); assertThrows(UnsupportedOperationException.class, () -> eventLogger.logReleaseBtcRequestReceived( sender, btcDestinationAddress, @@ -87,8 +90,8 @@ void testLogReleaseBtcRequestReceived() { @Test void testLogReleaseBtcRequestRejected() { - RskAddress sender = new RskAddress("0x0000000000000000000000000000000000000000"); - co.rsk.core.Coin amount = co.rsk.core.Coin.valueOf(100_000_000_000_000_000L); + RskAddress sender = new RskAddress("0x0000000000000000000000000000000000020002"); + co.rsk.core.Coin amount = co.rsk.core.Coin.fromBitcoin(Coin.COIN); RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; // Any reason, just testing the call to the method assertThrows(UnsupportedOperationException.class, () -> eventLogger.logReleaseBtcRequestRejected( sender, From d2da16a2073a1c67346d410d7714166054d816af Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 20 Sep 2024 18:10:44 -0300 Subject: [PATCH 12/17] Pass value in weis to logReleaseBtcRequestReceived Update rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java Co-authored-by: julia zack <83707069+julia-zack@users.noreply.github.com> Update test names Co-authored-by: julia zack <83707069+julia-zack@users.noreply.github.com> Rename tests in BridgeSupportReleaseBtcTest --- .../main/java/co/rsk/peg/BridgeSupport.java | 14 +- .../rsk/peg/BridgeSupportReleaseBtcTest.java | 139 ++++++++---------- .../rsk/peg/utils/BridgeEventLoggerTest.java | 17 +-- 3 files changed, 79 insertions(+), 91 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 0a3145e25d0..457b156a819 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -930,10 +930,20 @@ private void requestRelease(Address destinationAddress, co.rsk.core.Coin release provider.getReleaseRequestQueue().add(destinationAddress, valueToRelease); } + RskAddress sender = rskTx.getSender(signatureCache); if (activations.isActive(ConsensusRule.RSKIP185)) { - eventLogger.logReleaseBtcRequestReceived(rskTx.getSender(signatureCache).toHexString(), destinationAddress, valueToRelease); + eventLogger.logReleaseBtcRequestReceived( + sender, + destinationAddress, + releaseRequestedValue + ); } - logger.info("[requestRelease] releaseBtc successful to {}. Tx {}. Value {}.", destinationAddress, rskTx, releaseRequestedValue); + logger.info( + "[requestRelease] releaseBtc successful to {}. Tx {}. Value {}.", + destinationAddress, + rskTx, + releaseRequestedValue + ); } } 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 5f3f5a60689..b69f7c18881 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -99,7 +99,7 @@ void setUpOnEachTest() { } @Test - void noLogEvents_before_rskip_146_185() throws IOException { + void noLogEvents_before_papyrus() throws IOException { ActivationConfig.ForBlock wasabiActivation = ActivationConfigsForTest.wasabi100().forBlock(0L); bridgeSupport = initBridgeSupport(eventLogger, wasabiActivation); @@ -115,7 +115,7 @@ void noLogEvents_before_rskip_146_185() throws IOException { } @Test - void eventLogger_logReleaseBtcRequested_after_rskip146_before_rskip185() throws IOException { + void eventLogger_logReleaseBtcRequested_after_papyrus_before_iris() throws IOException { ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); bridgeSupport = initBridgeSupport(eventLogger, papyrusActivations); @@ -131,7 +131,7 @@ void eventLogger_logReleaseBtcRequested_after_rskip146_before_rskip185() throws } @Test - void eventLogger_logReleaseBtcRequested_after_rskip_146_185() throws IOException { + void eventLogger_logReleaseBtcRequested_after_iris() throws IOException { bridgeSupport.releaseBtc(releaseTx); Transaction rskTx = buildUpdateTx(); @@ -162,7 +162,7 @@ void eventLogger_logReleaseBtcRequested_release_before_papyrus_and_updateCollect } @Test - void handmade_release_before_rskip_146_185_no_events_emitted() throws IOException { + void release_before_papyrus_no_events_emitted() throws IOException { ActivationConfig.ForBlock wasabiActivations = ActivationConfigsForTest.wasabi100().forBlock(0L); bridgeSupport = initBridgeSupport(eventLogger, wasabiActivations); @@ -182,7 +182,7 @@ void handmade_release_before_rskip_146_185_no_events_emitted() throws IOExceptio } @Test - void handmade_release_after_rskip146_before_rskip185() throws IOException { + void release_after_papyrus_before_iris() throws IOException { ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); bridgeSupport = initBridgeSupport(eventLogger, papyrusActivations); @@ -203,7 +203,7 @@ void handmade_release_after_rskip146_before_rskip185() throws IOException { } @Test - void handmade_release_after_rskip_146_185_before_rskip326() throws IOException { + void release_after_iris_before_fingerroot() throws IOException { ActivationConfig.ForBlock hopActivations = ActivationConfigsForTest.hop400().forBlock(0L); List logInfo = new ArrayList<>(); @@ -215,14 +215,20 @@ void handmade_release_after_rskip_146_185_before_rskip326() throws IOException { )); bridgeSupport = initBridgeSupport(bridgeEventLogger, hopActivations); - bridgeSupport.releaseBtc(releaseTx); + // Get a value between old and new minimum pegout values + Coin middle = BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue().subtract(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()).div(2); + Coin value = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().add(middle); + assertTrue(value.isLessThan(BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue())); + assertTrue(value.isGreaterThan(BRIDGE_CONSTANTS.getMinimumPegoutTxValue())); + bridgeSupport.releaseBtc(buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(value))); + + assertEquals(1, provider.getReleaseRequestQueue().getEntries().size()); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); bridgeSupport.updateCollections(rskTx); verify(repository, never()).transfer(any(), any(), any()); - assertEquals(1, provider.getPegoutsWaitingForConfirmations().getEntries().size()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); @@ -238,12 +244,14 @@ void handmade_release_after_rskip_146_185_before_rskip326() throws IOException { LogInfo firstLog = logInfo.get(0); CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(); + assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; assertInstanceOf(byte[].class, btcDestinationAddress); } @Test - void handmade_release_after_rskip_146_185_326_before_rskip428() throws IOException { + void logReleaseBtcRequestReceived_after_fingerroot_before_lovell_shouldLogValueInSatoshis() throws IOException { ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead600().forBlock(0L); List logInfo = new ArrayList<>(); @@ -255,7 +263,8 @@ void handmade_release_after_rskip_146_185_326_before_rskip428() throws IOExcepti )); bridgeSupport = initBridgeSupport(bridgeEventLogger, arrowheadActivations); - bridgeSupport.releaseBtc(releaseTx); + co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()); + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); @@ -279,11 +288,14 @@ void handmade_release_after_rskip_146_185_326_before_rskip428() throws IOExcepti LogInfo firstLog = logInfo.get(0); CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(); Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; + BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[1]; + assertInstanceOf(String.class, btcDestinationAddress); + assertEquals(pegoutRequestValue.toBitcoin().longValue(), amount.longValue()); } @Test - void handmade_release_after_rskip_146_185_326_428() throws IOException { + void release_after_lovell_logPegoutTransactionCreated_use_value_in_weis() throws IOException { List logInfo = new ArrayList<>(); BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -293,7 +305,8 @@ void handmade_release_after_rskip_146_185_326_428() throws IOException { )); bridgeSupport = initBridgeSupport(bridgeEventLogger, ACTIVATIONS_ALL); - bridgeSupport.releaseBtc(releaseTx); + co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()); + bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); Transaction rskTx = buildUpdateTx(); rskTx.sign(SENDER.getPrivKeyBytes()); @@ -318,11 +331,14 @@ void handmade_release_after_rskip_146_185_326_428() throws IOException { LogInfo firstLog = logInfo.get(0); CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(); Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; + BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[1]; + assertInstanceOf(String.class, btcDestinationAddress); + assertEquals(pegoutRequestValue.asBigInteger(), amount); } @Test - void handmade_release_after_rskip146_before_rskip185_rejected_lowAmount() throws IOException { + void release_after_papyrus_before_iris_rejected_lowAmount() throws IOException { ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); List logInfo = new ArrayList<>(); @@ -352,7 +368,7 @@ void handmade_release_after_rskip146_before_rskip185_rejected_lowAmount() throws } @Test - void handmade_release_after_rskip_146_185_rejected_lowAmount() throws IOException { + void release_after_iris_rejected_lowAmount() throws IOException { List logInfo = new ArrayList<>(); BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -385,7 +401,7 @@ void handmade_release_after_rskip_146_185_rejected_lowAmount() throws IOExceptio } @Test - void handmade_release_after_rskip146_before_rskip185_rejected_contractCaller_throws_exception() { + void release_after_papyrus_before_iris_rejected_contractCaller_throws_exception() { ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); bridgeSupport = initBridgeSupport(eventLogger, papyrusActivations); @@ -395,7 +411,7 @@ void handmade_release_after_rskip146_before_rskip185_rejected_contractCaller_thr } @Test - void handmade_release_after_rskip_146_185_rejected_contractCaller_emits_rejection_event() throws IOException { + void release_after_iris_rejected_contractCaller_emits_rejection_event() throws IOException { List logInfo = new ArrayList<>(); BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -426,45 +442,7 @@ void handmade_release_after_rskip_146_185_rejected_contractCaller_emits_rejectio } @Test - void release_after_rskip219_before_rskip326() throws IOException { - ActivationConfig.ForBlock hopActivations = ActivationConfigsForTest.hop400().forBlock(0L); - - List logInfo = new ArrayList<>(); - BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( - BRIDGE_CONSTANTS, - hopActivations, - logInfo, - signatureCache - )); - bridgeSupport = initBridgeSupport(bridgeEventLogger, hopActivations); - - // Get a value between old and new minimum pegout values - Coin middle = BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue().subtract(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()).div(2); - Coin value = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().add(middle); - assertTrue(value.isLessThan(BRIDGE_CONSTANTS.getLegacyMinimumPegoutTxValue())); - assertTrue(value.isGreaterThan(BRIDGE_CONSTANTS.getMinimumPegoutTxValue())); - bridgeSupport.releaseBtc(buildReleaseRskTx(co.rsk.core.Coin.fromBitcoin(value))); - - Transaction rskTx = buildUpdateTx(); - rskTx.sign(SENDER.getPrivKeyBytes()); - - verify(repository, never()).transfer(any(), any(), any()); - - assertEquals(1, provider.getReleaseRequestQueue().getEntries().size()); - - assertEquals(1, logInfo.size()); - verify(bridgeEventLogger, times(1)).logReleaseBtcRequestReceived(any(), any(), any()); - - LogInfo firstLog = logInfo.get(0); - CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(); - assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); - - Object btcDestinationAddress = event.decodeEventData(firstLog.getData())[0]; - assertInstanceOf(byte[].class, btcDestinationAddress); - } - - @Test - void release_after_rskip_219_326() throws IOException { + void release_after_fingerroot() throws IOException { List logInfo = new ArrayList<>(); BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -500,7 +478,7 @@ void release_after_rskip_219_326() throws IOException { } @Test - void release_before_rskip_219() throws IOException { + void release_before_iris() throws IOException { ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); List logInfo = new ArrayList<>(); @@ -530,7 +508,7 @@ void release_before_rskip_219() throws IOException { } @Test - void release_before_rskip_219_minimum_exclusive() throws IOException { + void release_before_iris_minimum_exclusive() throws IOException { ActivationConfig.ForBlock papyrusActivations = ActivationConfigsForTest.papyrus200().forBlock(0L); List logInfo = new ArrayList<>(); @@ -557,7 +535,7 @@ void release_before_rskip_219_minimum_exclusive() throws IOException { } @Test - void release_after_rskip219_before_rskip326_minimum_inclusive() throws IOException { + void release_after_iris_before_fingerroot_minimum_inclusive() throws IOException { ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); List logInfo = new ArrayList<>(); @@ -592,7 +570,7 @@ void release_after_rskip219_before_rskip326_minimum_inclusive() throws IOExcepti } @Test - void release_after_rskip_219_326_minimum_inclusive() throws IOException { + void release_after_fingerroot_minimum_inclusive() throws IOException { List logInfo = new ArrayList<>(); BridgeEventLoggerImpl bridgeEventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -631,7 +609,7 @@ void release_verify_fee_below_fee_is_rejected() throws IOException { } @Test - void release_verify_fee_above_fee_but_below_gap_is_rejected_before_rskip_271() throws IOException { + void release_verify_fee_above_fee_but_below_gap_is_rejected_before_hop() throws IOException { ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); Coin feePerKB = Coin.COIN; @@ -644,7 +622,7 @@ void release_verify_fee_above_fee_but_below_gap_is_rejected_before_rskip_271() t } @Test - void release_verify_fee_above_fee_but_below_gap_is_rejected_after_rskip_271() throws IOException { + void release_verify_fee_above_fee_but_below_gap_is_rejected_after_hop() throws IOException { Coin feePerKB = Coin.COIN; int pegoutSize = BridgeUtils.getRegularPegoutTxSize( @@ -670,7 +648,7 @@ void release_verify_fee_above_fee_and_minimum_is_accepted() throws IOException { } @Test - void processPegoutsIndividually_before_RSKIP271_activation() throws IOException { + void processPegoutsIndividually_before_hop() throws IOException { ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); List utxos = new ArrayList<>(); @@ -704,7 +682,7 @@ void processPegoutsIndividually_before_RSKIP271_activation() throws IOException } @Test - void processPegoutsInBatch_after_RSKIP271() throws IOException { + void processPegoutsInBatch_after_hop() throws IOException { List utxos = new ArrayList<>(); utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), activeFederation.getAddress())); @@ -754,7 +732,7 @@ void processPegoutsInBatch_after_RSKIP271() throws IOException { } @Test - void processPegoutsInBatch_after_RSKIP271_activation_next_pegout_height_not_reached() throws IOException { + void processPegoutsInBatch_after_hop_next_pegout_height_not_reached() throws IOException { Block executionBlock = mock(Block.class); when(executionBlock.getNumber()).thenReturn(100L); @@ -786,7 +764,7 @@ void processPegoutsInBatch_after_RSKIP271_activation_next_pegout_height_not_reac } @Test - void processPegoutsInBatch_after_RSKIP271_activation_no_requests_in_queue_updates_next_pegout_height() throws IOException { + void processPegoutsInBatch_hop_activation_no_requests_in_queue_updates_next_pegout_height() throws IOException { provider = mock(BridgeStorageProvider.class); when(provider.getNextPegoutHeight()).thenReturn(Optional.of(100L)); when(provider.getReleaseRequestQueue()).thenReturn(new ReleaseRequestQueue(Collections.emptyList())); @@ -812,7 +790,7 @@ void processPegoutsInBatch_after_RSKIP271_activation_no_requests_in_queue_update } @Test - void processPegoutsInBatch_after_rskip_271_Insufficient_Money() throws IOException { + void processPegoutsInBatch_after_hop_Insufficient_Money() throws IOException { List utxos = new ArrayList<>(); utxos.add(PegTestUtils.createUTXO(2, 0, Coin.COIN.multiply(4), activeFederation.getAddress())); @@ -846,7 +824,7 @@ void processPegoutsInBatch_after_rskip_271_Insufficient_Money() throws IOExcepti } @Test - void processPegoutsInBatch_after_rskip_271_divide_transaction_when_max_size_exceeded() throws IOException { + void processPegoutsInBatch_after_hop_divide_transaction_when_max_size_exceeded() throws IOException { List utxos = PegTestUtils.createUTXOs(310, activeFederation.getAddress()); federationStorageProvider = mock(FederationStorageProvider.class); @@ -885,7 +863,7 @@ void processPegoutsInBatch_after_rskip_271_divide_transaction_when_max_size_exce } @Test - void processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_one_pegout() throws IOException { + void processPegoutsInBatch_after_hop_when_max_size_exceeded_for_one_pegout() throws IOException { List utxos = PegTestUtils.createUTXOs(700, activeFederation.getAddress()); federationStorageProvider = mock(FederationStorageProvider.class); @@ -911,7 +889,7 @@ void processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_one_pegout } @Test - void processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_two_pegout() throws IOException { + void processPegoutsInBatch_after_hop_when_max_size_exceeded_for_two_pegout() throws IOException { List utxos = PegTestUtils.createUTXOs(1400, activeFederation.getAddress()); federationStorageProvider = mock(FederationStorageProvider.class); @@ -938,7 +916,7 @@ void processPegoutsInBatch_after_rskip_271_when_max_size_exceeded_for_two_pegout } @Test - void processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_requests() throws IOException { + void processPegoutsIndividually_before_hop_no_funds_to_process_any_requests() throws IOException { ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); List utxos = new ArrayList<>(); @@ -975,7 +953,7 @@ void processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_request } @Test - void processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_requests_order_changes_in_queue() throws IOException { + void processPegoutsIndividually_before_hop_no_funds_to_process_any_requests_order_changes_in_queue() throws IOException { ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); List utxos = new ArrayList<>(); @@ -1023,7 +1001,7 @@ void processPegoutsIndividually_before_rskip_271_no_funds_to_process_any_request } @Test - void check_wallet_balance_before_rskip_271_process_at_least_one_request() throws IOException { + void check_wallet_balance_before_hop_process_at_least_one_request() throws IOException { ActivationConfig.ForBlock irisActivations = ActivationConfigsForTest.iris300().forBlock(0L); List utxos = new ArrayList<>(); @@ -1055,7 +1033,7 @@ void check_wallet_balance_before_rskip_271_process_at_least_one_request() throws } @Test - void check_wallet_balance_after_rskip_271_process_no_requests() throws IOException { + void check_wallet_balance_after_hop_process_no_requests() throws IOException { List utxos = new ArrayList<>(); utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), activeFederation.getAddress())); utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN.multiply(4), activeFederation.getAddress())); @@ -1090,7 +1068,7 @@ void check_wallet_balance_after_rskip_271_process_no_requests() throws IOExcepti } @Test - void check_wallet_balance_after_rskip_271_process_all_requests_when_utxos_available() throws IOException { + void check_wallet_balance_after_hop_process_all_requests_when_utxos_available() throws IOException { List utxos = new ArrayList<>(); utxos.add(PegTestUtils.createUTXO(1, 0, Coin.COIN.multiply(4), activeFederation.getAddress())); utxos.add(PegTestUtils.createUTXO(2, 1, Coin.COIN.multiply(4), activeFederation.getAddress())); @@ -1282,7 +1260,7 @@ private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue( } @Test - void low_amount_release_request_rejected_before_rskip427_value_in_satoshis() throws IOException { + void low_amount_release_request_rejected_before_lovell_value_in_satoshis() throws IOException { ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); List logInfo = new ArrayList<>(); @@ -1326,7 +1304,7 @@ void low_amount_release_request_rejected_before_rskip427_value_in_satoshis() thr } @Test - void low_amount_release_request_rejected_after_rskip427_value_in_weis() throws IOException { + void low_amount_release_request_rejected_after_lovell_value_in_weis() throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -1368,7 +1346,7 @@ void low_amount_release_request_rejected_after_rskip427_value_in_weis() throws I } @Test - void contract_caller_release_request_rejected_before_rskip427_value_in_satoshis() throws IOException { + void contract_caller_release_request_rejected_before_lovell_value_in_satoshis() throws IOException { ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); List logInfo = new ArrayList<>(); @@ -1407,7 +1385,7 @@ void contract_caller_release_request_rejected_before_rskip427_value_in_satoshis( } @Test - void contract_caller_release_request_rejected_after_rskip427_value_in_weis() throws IOException { + void contract_caller_release_request_rejected_after_lovell_value_in_weis() throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -1444,7 +1422,7 @@ void contract_caller_release_request_rejected_after_rskip427_value_in_weis() thr } @Test - void fee_above_value_release_request_rejected_before_rskip427_value_in_satoshis() throws IOException { + void fee_above_value_release_request_rejected_before_lovell_value_in_satoshis() throws IOException { ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); List logInfo = new ArrayList<>(); @@ -1499,7 +1477,7 @@ void fee_above_value_release_request_rejected_before_rskip427_value_in_satoshis( } @Test - void fee_above_value_release_request_rejected_after_rskip427_value_in_weis() throws IOException { + void fee_above_value_release_request_rejected_after_lovell_value_in_weis() throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -1582,6 +1560,7 @@ private Transaction buildReleaseRskTx(co.rsk.core.Coin coin) { .value(coin) .build(); releaseTransaction.sign(SENDER.getPrivKeyBytes()); + return releaseTransaction; } diff --git a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java index d2424935a6e..598d233c48c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/utils/BridgeEventLoggerTest.java @@ -8,7 +8,6 @@ import co.rsk.bitcoinj.core.*; import co.rsk.core.RskAddress; import co.rsk.crypto.Keccak256; -import co.rsk.peg.PegTestUtils; import co.rsk.peg.pegin.RejectedPeginReason; import java.util.*; import org.junit.jupiter.api.BeforeEach; @@ -27,7 +26,7 @@ void setup() { } @Test - void testLogLockBtc() { + void logLockBtc() { assertThrows(UnsupportedOperationException.class, () -> eventLogger.logLockBtc( mock(RskAddress.class), btcTxMock, @@ -37,7 +36,7 @@ void testLogLockBtc() { } @Test - void testLogPeginBtc() { + void logPeginBtc() { assertThrows(UnsupportedOperationException.class, () -> eventLogger.logPeginBtc( mock(RskAddress.class), btcTxMock, @@ -47,7 +46,7 @@ void testLogPeginBtc() { } @Test - void testLogReleaseBtcRequested() { + void logReleaseBtcRequested() { byte[] rskTxHashBytes = rskTxHash.getBytes(); assertThrows(UnsupportedOperationException.class, () -> eventLogger.logReleaseBtcRequested( rskTxHashBytes, @@ -57,7 +56,7 @@ void testLogReleaseBtcRequested() { } @Test - void testLogRejectedPegin() { + void logRejectedPegin() { assertThrows(UnsupportedOperationException.class, () -> eventLogger.logRejectedPegin( btcTxMock, RejectedPeginReason.PEGIN_CAP_SURPASSED @@ -65,7 +64,7 @@ void testLogRejectedPegin() { } @Test - void testLogUnrefundablePegin() { + void logUnrefundablePegin() { assertThrows(UnsupportedOperationException.class, () -> eventLogger.logUnrefundablePegin( btcTxMock, UnrefundablePeginReason.LEGACY_PEGIN_UNDETERMINED_SENDER @@ -73,8 +72,8 @@ void testLogUnrefundablePegin() { } @Test - void testLogReleaseBtcRequestReceived() { - RskAddress sender = new RskAddress("0x00000000000000000000000000000000001001"); + void logReleaseBtcRequestReceived() { + RskAddress sender = new RskAddress("0x0000000000000000000000000000000000001101"); String base58Address = "16SL1Qsw1eyYWM58MFh9KwKYoxYmm3fM1Z"; Address btcDestinationAddress = Address.fromBase58( NetworkParameters.fromID(NetworkParameters.ID_MAINNET), @@ -89,7 +88,7 @@ void testLogReleaseBtcRequestReceived() { } @Test - void testLogReleaseBtcRequestRejected() { + void logReleaseBtcRequestRejected() { RskAddress sender = new RskAddress("0x0000000000000000000000000000000000020002"); co.rsk.core.Coin amount = co.rsk.core.Coin.fromBitcoin(Coin.COIN); RejectedPegoutReason reason = RejectedPegoutReason.LOW_AMOUNT; // Any reason, just testing the call to the method From 4aea6c0a1c40be91c4cf2a6032d837a820d4ff81 Mon Sep 17 00:00:00 2001 From: Marcos Date: Fri, 27 Sep 2024 09:52:11 -0300 Subject: [PATCH 13/17] When rejected pegout is refunded, post RSKIP427 refund the total value sent in weis --- .../main/java/co/rsk/peg/BridgeSupport.java | 9 ++- .../rsk/peg/BridgeSupportReleaseBtcTest.java | 67 ++++++++++++++++--- 2 files changed, 64 insertions(+), 12 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 457b156a819..3adcda2866c 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -850,10 +850,17 @@ private void refundAndEmitRejectEvent( senderAddress, reason ); + + // Prior to RSKIP427, the value was converted to BTC before doing the refund + // This could cause the original value to be rounded down to fit in satoshis value + co.rsk.core.Coin refundValue = activations.isActive(RSKIP427) ? + releaseRequestedValue : + co.rsk.core.Coin.fromBitcoin(releaseRequestedValue.toBitcoin()); + rskRepository.transfer( PrecompiledContracts.BRIDGE_ADDR, senderAddress, - releaseRequestedValue + refundValue ); emitRejectEvent(releaseRequestedValue, senderAddress, reason); } 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 b69f7c18881..be18b089d5e 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -58,6 +58,7 @@ import org.ethereum.vm.program.InternalTransaction; import org.ethereum.vm.program.Program; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; class BridgeSupportReleaseBtcTest { @@ -1260,7 +1261,8 @@ private void testPegoutMinimumWithFeeVerificationRejectedByFeeAboveValue( } @Test - void low_amount_release_request_rejected_before_lovell_value_in_satoshis() throws IOException { + @DisplayName("A rejected pegout due to low amount. Pre lovell, the value is rounded down to the nearest satoshi. Both in the emitted event and the value refunded.") + void low_amount_release_request_rejected_before_lovell() throws IOException { ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); List logInfo = new ArrayList<>(); @@ -1274,15 +1276,22 @@ void low_amount_release_request_rejected_before_lovell_value_in_satoshis() throw Coin belowPegoutMinimumValue = BRIDGE_CONSTANTS.getMinimumPegoutTxValue().minus(Coin.SATOSHI); co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(belowPegoutMinimumValue); + // Add some extra weis to the value, but less than 1 satoshi. + // To ensure that the pegout value is rounded down to fit in satoshis. + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + // Pre lovell, the refund should be rounded down to the nearest satoshi. + co.rsk.core.Coin expectedRefundValue = pegoutRequestValue.subtract(extraWeis); verify(repository, times(1)).transfer( BRIDGE_ADDRESS, senderAddress, - pegoutRequestValue + expectedRefundValue ); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); @@ -1299,12 +1308,15 @@ void low_amount_release_request_rejected_before_lovell_value_in_satoshis() throw CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + // Same case in the log, the value should be rounded down to the nearest satoshi. BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; - assertEquals(pegoutRequestValue.toBitcoin().longValue(), amount.longValue()); + long expectedAmountLogged = expectedRefundValue.toBitcoin().longValue(); + assertEquals(expectedAmountLogged, amount.longValue()); } @Test - void low_amount_release_request_rejected_after_lovell_value_in_weis() throws IOException { + @DisplayName("A rejected pegout due to low amount. Post lovell, the pegout value is preserved in weis. Both in the emitted event and the value refunded.") + void low_amount_release_request_rejected_after_lovell() throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -1346,7 +1358,8 @@ void low_amount_release_request_rejected_after_lovell_value_in_weis() throws IOE } @Test - void contract_caller_release_request_rejected_before_lovell_value_in_satoshis() throws IOException { + @DisplayName("A pegout from a contract is rejected. Pre lovell, the pegout value is rounded down to the nearest satoshi. Both in the emitted event and the value refunded.") + void contract_caller_release_request_rejected_before_lovell() throws IOException { ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); List logInfo = new ArrayList<>(); @@ -1359,11 +1372,17 @@ void contract_caller_release_request_rejected_before_lovell_value_in_satoshis() bridgeSupport = initBridgeSupport(eventLogger, arrowheadActivations); co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()); + // Add some extra weis to the value, but less than 1 satoshi. + // To ensure that the pegout value is rounded down to fit in satoshis. + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx_fromContract(pegoutRequestValue)); RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + // No refund is made to a contract verify(repository, never()).transfer(any(), any(), any()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); @@ -1381,11 +1400,15 @@ void contract_caller_release_request_rejected_before_lovell_value_in_satoshis() assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; - assertEquals(pegoutRequestValue.toBitcoin().longValue(), amount.longValue()); + // Pre lovell, the logged value should be rounded down to the nearest satoshi. + co.rsk.core.Coin expectedLoggedValue = pegoutRequestValue.subtract(extraWeis); + long expectedAmountLogged = expectedLoggedValue.toBitcoin().longValue(); + assertEquals(expectedAmountLogged, amount.longValue()); } @Test - void contract_caller_release_request_rejected_after_lovell_value_in_weis() throws IOException { + @DisplayName("A pegout from a contract is rejected. Post lovell, the pegout value is preserved in weis. Both in the emitted event and the value refunded.") + void contract_caller_release_request_rejected_after_lovell() throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -1396,11 +1419,17 @@ void contract_caller_release_request_rejected_after_lovell_value_in_weis() throw bridgeSupport = initBridgeSupport(eventLogger, ACTIVATIONS_ALL); co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()); + // Add some extra weis to the value, but less than 1 satoshi. + // To ensure that the pegout value is rounded down to fit in satoshis. + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx_fromContract(pegoutRequestValue)); RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + // No refund is made to a contract verify(repository, never()).transfer(any(), any(), any()); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); @@ -1422,7 +1451,8 @@ void contract_caller_release_request_rejected_after_lovell_value_in_weis() throw } @Test - void fee_above_value_release_request_rejected_before_lovell_value_in_satoshis() throws IOException { + @DisplayName("A pegout rejected due to high fees. Pre lovell, the pegout value is rounded down to the nearest satoshi. Both in the emitted event and the value refunded.") + void fee_above_value_release_request_rejected_before_lovell() throws IOException { ActivationConfig.ForBlock arrowheadActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); List logInfo = new ArrayList<>(); @@ -1447,15 +1477,22 @@ void fee_above_value_release_request_rejected_before_lovell_value_in_satoshis() Coin pegoutRequestValueWithGapAboveFee = minValueWithGapAboveFee.minus(Coin.SATOSHI); co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(pegoutRequestValueWithGapAboveFee); + // Add some extra weis to the value, but less than 1 satoshi. + // To ensure that the pegout value is rounded down to fit in satoshis. + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); RskAddress senderAddress = new RskAddress(SENDER.getAddress()); + // Pre lovell, the refund should be rounded down to the nearest satoshi. + co.rsk.core.Coin expectedRefundValue = pegoutRequestValue.subtract(extraWeis); verify(repository, times(1)).transfer( BRIDGE_ADDRESS, senderAddress, - pegoutRequestValue + expectedRefundValue ); assertEquals(0, provider.getReleaseRequestQueue().getEntries().size()); @@ -1472,12 +1509,15 @@ void fee_above_value_release_request_rejected_before_lovell_value_in_satoshis() CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); assertArrayEquals(event.encodeSignatureLong(), firstLog.getTopics().get(0).getData()); + // Same case in the log, the value should be rounded down to the nearest satoshi. BigInteger amount = (BigInteger) event.decodeEventData(firstLog.getData())[0]; - assertEquals(pegoutRequestValue.toBitcoin().longValue(), amount.longValue()); + long expectedAmountLogged = expectedRefundValue.toBitcoin().longValue(); + assertEquals(expectedAmountLogged, amount.longValue()); } @Test - void fee_above_value_release_request_rejected_after_lovell_value_in_weis() throws IOException { + @DisplayName("A pegout rejected due to high fees. Post lovell, the pegout value is preserved in weis. Both in the emitted event and the value refunded.") + void fee_above_value_release_request_rejected_after_lovell() throws IOException { List logInfo = new ArrayList<>(); eventLogger = spy(new BridgeEventLoggerImpl( BRIDGE_CONSTANTS, @@ -1500,6 +1540,11 @@ void fee_above_value_release_request_rejected_after_lovell_value_in_weis() throw Coin pegoutRequestValueWithGapAboveFee = minValueWithGapAboveFee.minus(Coin.SATOSHI); co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(pegoutRequestValueWithGapAboveFee); + // Add some extra weis to the value, but less than 1 satoshi. + // To ensure that the pegout value is rounded down to fit in satoshis. + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); From 434da88cd892619a890c05c0d14f2451c94128b0 Mon Sep 17 00:00:00 2001 From: Marcos Date: Mon, 14 Oct 2024 17:04:01 -0300 Subject: [PATCH 14/17] Update and simplify releaseBtc tests --- .../java/co/rsk/peg/BridgeSupportReleaseBtcTest.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 be18b089d5e..0fc3d506b38 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -1278,7 +1278,7 @@ void low_amount_release_request_rejected_before_lovell() throws IOException { co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(belowPegoutMinimumValue); // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. - co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); pegoutRequestValue = pegoutRequestValue.add(extraWeis); @@ -1374,7 +1374,7 @@ void contract_caller_release_request_rejected_before_lovell() throws IOException co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()); // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. - co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); pegoutRequestValue = pegoutRequestValue.add(extraWeis); @@ -1421,7 +1421,7 @@ void contract_caller_release_request_rejected_after_lovell() throws IOException co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(BRIDGE_CONSTANTS.getMinimumPegoutTxValue()); // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. - co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); pegoutRequestValue = pegoutRequestValue.add(extraWeis); @@ -1479,7 +1479,7 @@ void fee_above_value_release_request_rejected_before_lovell() throws IOException co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(pegoutRequestValueWithGapAboveFee); // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. - co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); pegoutRequestValue = pegoutRequestValue.add(extraWeis); @@ -1542,7 +1542,7 @@ void fee_above_value_release_request_rejected_after_lovell() throws IOException co.rsk.core.Coin pegoutRequestValue = co.rsk.core.Coin.fromBitcoin(pegoutRequestValueWithGapAboveFee); // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. - co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.valueOf(Denomination.satoshisToWeis(1).longValue()); + co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); pegoutRequestValue = pegoutRequestValue.add(extraWeis); From 1825e5b0e286e656e614a1c343c08d6e65e43988 Mon Sep 17 00:00:00 2001 From: Marcos Date: Tue, 15 Oct 2024 10:28:25 -0300 Subject: [PATCH 15/17] Rename variables in releaseBtc tests --- .../co/rsk/peg/BridgeSupportReleaseBtcTest.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) 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 0fc3d506b38..141a792e5d6 100644 --- a/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/BridgeSupportReleaseBtcTest.java @@ -1279,7 +1279,8 @@ void low_amount_release_request_rejected_before_lovell() throws IOException { // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); - co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + co.rsk.core.Coin oneWei = co.rsk.core.Coin.valueOf(Denomination.WEI.longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(oneWei); pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); @@ -1375,7 +1376,8 @@ void contract_caller_release_request_rejected_before_lovell() throws IOException // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); - co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + co.rsk.core.Coin oneWei = co.rsk.core.Coin.valueOf(Denomination.WEI.longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(oneWei); pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx_fromContract(pegoutRequestValue)); @@ -1422,7 +1424,8 @@ void contract_caller_release_request_rejected_after_lovell() throws IOException // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); - co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + co.rsk.core.Coin oneWei = co.rsk.core.Coin.valueOf(Denomination.WEI.longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(oneWei); pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx_fromContract(pegoutRequestValue)); @@ -1480,7 +1483,8 @@ void fee_above_value_release_request_rejected_before_lovell() throws IOException // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); - co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + co.rsk.core.Coin oneWei = co.rsk.core.Coin.valueOf(Denomination.WEI.longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(oneWei); pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); @@ -1543,7 +1547,8 @@ void fee_above_value_release_request_rejected_after_lovell() throws IOException // Add some extra weis to the value, but less than 1 satoshi. // To ensure that the pegout value is rounded down to fit in satoshis. co.rsk.core.Coin oneSatoshiInWeis = co.rsk.core.Coin.fromBitcoin(Coin.SATOSHI); - co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(co.rsk.core.Coin.valueOf(1)); + co.rsk.core.Coin oneWei = co.rsk.core.Coin.valueOf(Denomination.WEI.longValue()); + co.rsk.core.Coin extraWeis = oneSatoshiInWeis.subtract(oneWei); pegoutRequestValue = pegoutRequestValue.add(extraWeis); bridgeSupport.releaseBtc(buildReleaseRskTx(pegoutRequestValue)); From f46ba47c5841e7b45f76026d170d1ad3490118f4 Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 16 Oct 2024 15:47:47 -0300 Subject: [PATCH 16/17] Rename variables related to release amounts. Indicate satoshis or weis --- .../main/java/co/rsk/peg/BridgeSupport.java | 38 +++++++++---------- .../co/rsk/peg/utils/BridgeEventLogger.java | 4 +- .../rsk/peg/utils/BridgeEventLoggerImpl.java | 22 +++++------ 3 files changed, 32 insertions(+), 32 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 3adcda2866c..8f3e6cc5ef5 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -840,13 +840,13 @@ public void releaseBtc(Transaction rskTx) throws IOException { } private void refundAndEmitRejectEvent( - co.rsk.core.Coin releaseRequestedValue, + co.rsk.core.Coin releaseRequestedValueInWeis, RskAddress senderAddress, RejectedPegoutReason reason ) { logger.trace( "[refundAndEmitRejectEvent] Executing a refund of {} to {}. Reason: {}", - releaseRequestedValue, + releaseRequestedValueInWeis, senderAddress, reason ); @@ -854,19 +854,19 @@ private void refundAndEmitRejectEvent( // Prior to RSKIP427, the value was converted to BTC before doing the refund // This could cause the original value to be rounded down to fit in satoshis value co.rsk.core.Coin refundValue = activations.isActive(RSKIP427) ? - releaseRequestedValue : - co.rsk.core.Coin.fromBitcoin(releaseRequestedValue.toBitcoin()); + releaseRequestedValueInWeis : + co.rsk.core.Coin.fromBitcoin(releaseRequestedValueInWeis.toBitcoin()); rskRepository.transfer( PrecompiledContracts.BRIDGE_ADDR, senderAddress, refundValue ); - emitRejectEvent(releaseRequestedValue, senderAddress, reason); + emitRejectEvent(releaseRequestedValueInWeis, senderAddress, reason); } - private void emitRejectEvent(co.rsk.core.Coin value, RskAddress senderAddress, RejectedPegoutReason reason) { - eventLogger.logReleaseBtcRequestRejected(senderAddress, value, reason); + private void emitRejectEvent(co.rsk.core.Coin releaseRequestedValueInWeis, RskAddress senderAddress, RejectedPegoutReason reason) { + eventLogger.logReleaseBtcRequestRejected(senderAddress, releaseRequestedValueInWeis, reason); } /** @@ -875,11 +875,11 @@ private void emitRejectEvent(co.rsk.core.Coin value, RskAddress senderAddress, R * to be processed later. * * @param destinationAddress the destination BTC address. - * @param releaseRequestedValue the amount of RBTC requested to be released. + * @param releaseRequestedValueInWeis the amount of RBTC requested to be released, represented in weis * @throws IOException if there is an error getting the release request queue from storage */ - private void requestRelease(Address destinationAddress, co.rsk.core.Coin releaseRequestedValue, Transaction rskTx) throws IOException { - Coin valueToRelease = releaseRequestedValue.toBitcoin(); + private void requestRelease(Address destinationAddress, co.rsk.core.Coin releaseRequestedValueInWeis, Transaction rskTx) throws IOException { + Coin valueToReleaseInSatoshis = releaseRequestedValueInWeis.toBitcoin(); Optional optionalRejectedPegoutReason = Optional.empty(); if (activations.isActive(RSKIP219)) { int pegoutSize = getRegularPegoutTxSize(activations, getActiveFederation()); @@ -897,11 +897,11 @@ private void requestRelease(Address destinationAddress, co.rsk.core.Coin release .divide(100) ); // add the gap - // The pegout releaseRequestedValue should be greater or equals than the max of these two values + // The pegout releaseRequestedValueInWeis should be greater or equals than the max of these two values Coin minValue = Coin.valueOf(Math.max(bridgeConstants.getMinimumPegoutTxValue().value, requireFundsForFee.value)); // Since Iris the peg-out the rule is that the minimum is inclusive - if (valueToRelease.isLessThan(minValue)) { + if (valueToReleaseInSatoshis.isLessThan(minValue)) { optionalRejectedPegoutReason = Optional.of( Objects.equals(minValue, requireFundsForFee) ? RejectedPegoutReason.FEE_ABOVE_VALUE: @@ -910,7 +910,7 @@ private void requestRelease(Address destinationAddress, co.rsk.core.Coin release } } else { // For legacy peg-outs the rule stated that the minimum was exclusive - if (!valueToRelease.isGreaterThan(bridgeConstants.getLegacyMinimumPegoutTxValue())) { + if (!valueToReleaseInSatoshis.isGreaterThan(bridgeConstants.getLegacyMinimumPegoutTxValue())) { optionalRejectedPegoutReason = Optional.of(RejectedPegoutReason.LOW_AMOUNT); } } @@ -920,21 +920,21 @@ private void requestRelease(Address destinationAddress, co.rsk.core.Coin release "[requestRelease] releaseBtc ignored. To {}. Tx {}. Value {}. Reason: {}", destinationAddress, rskTx, - releaseRequestedValue, + releaseRequestedValueInWeis, optionalRejectedPegoutReason.get() ); if (activations.isActive(ConsensusRule.RSKIP185)) { refundAndEmitRejectEvent( - releaseRequestedValue, + releaseRequestedValueInWeis, rskTx.getSender(signatureCache), optionalRejectedPegoutReason.get() ); } } else { if (activations.isActive(ConsensusRule.RSKIP146)) { - provider.getReleaseRequestQueue().add(destinationAddress, valueToRelease, rskTx.getHash()); + provider.getReleaseRequestQueue().add(destinationAddress, valueToReleaseInSatoshis, rskTx.getHash()); } else { - provider.getReleaseRequestQueue().add(destinationAddress, valueToRelease); + provider.getReleaseRequestQueue().add(destinationAddress, valueToReleaseInSatoshis); } RskAddress sender = rskTx.getSender(signatureCache); @@ -942,14 +942,14 @@ private void requestRelease(Address destinationAddress, co.rsk.core.Coin release eventLogger.logReleaseBtcRequestReceived( sender, destinationAddress, - releaseRequestedValue + releaseRequestedValueInWeis ); } logger.info( "[requestRelease] releaseBtc successful to {}. Tx {}. Value {}.", destinationAddress, rskTx, - releaseRequestedValue + releaseRequestedValueInWeis ); } } 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 20df205ea00..25fd8f3b16e 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 @@ -63,11 +63,11 @@ default void logUnrefundablePegin(BtcTransaction btcTx, UnrefundablePeginReason throw new UnsupportedOperationException(); } - default void logReleaseBtcRequestReceived(RskAddress sender, Address btcDestinationAddress, co.rsk.core.Coin amount) { + default void logReleaseBtcRequestReceived(RskAddress sender, Address btcDestinationAddress, co.rsk.core.Coin amountInWeis) { throw new UnsupportedOperationException(); } - default void logReleaseBtcRequestRejected(RskAddress sender, co.rsk.core.Coin amount, RejectedPegoutReason reason) { + default void logReleaseBtcRequestRejected(RskAddress sender, co.rsk.core.Coin amountInWeis, RejectedPegoutReason reason) { throw new UnsupportedOperationException(); } 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 f86d6c65d27..6b7242b47f5 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 @@ -192,45 +192,45 @@ public void logUnrefundablePegin(BtcTransaction btcTx, UnrefundablePeginReason r } @Override - public void logReleaseBtcRequestReceived(RskAddress sender, Address btcDestinationAddress, co.rsk.core.Coin amount) { + public void logReleaseBtcRequestReceived(RskAddress sender, Address btcDestinationAddress, co.rsk.core.Coin amountInWeis) { if (activations.isActive(ConsensusRule.RSKIP326)) { - logReleaseBtcRequestReceived(sender.toHexString(), btcDestinationAddress.toString(), amount); + logReleaseBtcRequestReceived(sender.toHexString(), btcDestinationAddress.toString(), amountInWeis); } else { - logReleaseBtcRequestReceived(sender.toHexString(), btcDestinationAddress.getHash160(), amount.toBitcoin()); + logReleaseBtcRequestReceived(sender.toHexString(), btcDestinationAddress.getHash160(), amountInWeis.toBitcoin()); } } - private void logReleaseBtcRequestReceived(String sender, byte[] btcDestinationAddress, Coin amount) { + private void logReleaseBtcRequestReceived(String sender, byte[] btcDestinationAddress, Coin amountInSatoshis) { CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED_LEGACY.getEvent(); byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender); List encodedTopics = LogInfo.byteArrayToList(encodedTopicsInBytes); - byte[] encodedData = event.encodeEventData(btcDestinationAddress, amount.getValue()); + byte[] encodedData = event.encodeEventData(btcDestinationAddress, amountInSatoshis.getValue()); this.logs.add(new LogInfo(BRIDGE_CONTRACT_ADDRESS, encodedTopics, encodedData)); } - private void logReleaseBtcRequestReceived(String sender, String btcDestinationAddress, co.rsk.core.Coin amount) { + private void logReleaseBtcRequestReceived(String sender, String btcDestinationAddress, co.rsk.core.Coin amountInWeis) { CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_RECEIVED.getEvent(); byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender); List encodedTopics = LogInfo.byteArrayToList(encodedTopicsInBytes); byte[] encodedData = activations.isActive(ConsensusRule.RSKIP427) ? - event.encodeEventData(btcDestinationAddress, amount.asBigInteger()) : - event.encodeEventData(btcDestinationAddress, amount.toBitcoin().getValue()); + event.encodeEventData(btcDestinationAddress, amountInWeis.asBigInteger()) : + event.encodeEventData(btcDestinationAddress, amountInWeis.toBitcoin().getValue()); this.logs.add(new LogInfo(BRIDGE_CONTRACT_ADDRESS, encodedTopics, encodedData)); } @Override - public void logReleaseBtcRequestRejected(RskAddress sender, co.rsk.core.Coin amount, RejectedPegoutReason reason) { + public void logReleaseBtcRequestRejected(RskAddress sender, co.rsk.core.Coin amountInWeis, RejectedPegoutReason reason) { CallTransaction.Function event = BridgeEvents.RELEASE_REQUEST_REJECTED.getEvent(); byte[][] encodedTopicsInBytes = event.encodeEventTopics(sender.toHexString()); List encodedTopics = LogInfo.byteArrayToList(encodedTopicsInBytes); byte[] encodedData = activations.isActive(ConsensusRule.RSKIP427) ? - event.encodeEventData(amount.asBigInteger(), reason.getValue()) : - event.encodeEventData(amount.toBitcoin().getValue(), reason.getValue()); + event.encodeEventData(amountInWeis.asBigInteger(), reason.getValue()) : + event.encodeEventData(amountInWeis.toBitcoin().getValue(), reason.getValue()); this.logs.add(new LogInfo(BRIDGE_CONTRACT_ADDRESS, encodedTopics, encodedData)); } From 8220d123db03376d90b1357ada2d11f65c93de89 Mon Sep 17 00:00:00 2001 From: Marcos Date: Wed, 16 Oct 2024 16:12:21 -0300 Subject: [PATCH 17/17] Add unit to log messages --- rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java | 6 +++--- 1 file changed, 3 insertions(+), 3 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 8f3e6cc5ef5..342d13cdd43 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -845,7 +845,7 @@ private void refundAndEmitRejectEvent( RejectedPegoutReason reason ) { logger.trace( - "[refundAndEmitRejectEvent] Executing a refund of {} to {}. Reason: {}", + "[refundAndEmitRejectEvent] Executing a refund of {} weis to {}. Reason: {}", releaseRequestedValueInWeis, senderAddress, reason @@ -917,7 +917,7 @@ private void requestRelease(Address destinationAddress, co.rsk.core.Coin release if (optionalRejectedPegoutReason.isPresent()) { logger.warn( - "[requestRelease] releaseBtc ignored. To {}. Tx {}. Value {}. Reason: {}", + "[requestRelease] releaseBtc ignored. To {}. Tx {}. Value {} weis. Reason: {}", destinationAddress, rskTx, releaseRequestedValueInWeis, @@ -946,7 +946,7 @@ private void requestRelease(Address destinationAddress, co.rsk.core.Coin release ); } logger.info( - "[requestRelease] releaseBtc successful to {}. Tx {}. Value {}.", + "[requestRelease] releaseBtc successful to {}. Tx {}. Value {} weis.", destinationAddress, rskTx, releaseRequestedValueInWeis