From c6c88e1f2e7a67d24160ad645c61e1466db64dab Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Tue, 16 Jul 2024 02:08:17 -0400 Subject: [PATCH 01/40] LockingCapConstants Refactor Following with the Bridge refactors, it is now time to refactor and remove the locking cap business logic from the Bridge. Create its package lockingcap with a Support, StorageProvider, and Constants classes. Since it will have its classes should remove from the variable names, lockingCap, to avoid being redundant. --- .../co/rsk/peg/constants/BridgeConstants.java | 16 --------- .../peg/constants/BridgeDevNetConstants.java | 33 ------------------ .../peg/constants/BridgeMainNetConstants.java | 20 ----------- .../peg/constants/BridgeRegTestConstants.java | 17 ---------- .../peg/constants/BridgeTestNetConstants.java | 22 +----------- .../constants/LockingCapConstants.java | 23 +++++++++++++ .../constants/LockingCapMainNetConstants.java | 34 +++++++++++++++++++ .../constants/LockingCapRegTestConstants.java | 33 ++++++++++++++++++ .../constants/LockingCapTestNetConstants.java | 34 +++++++++++++++++++ 9 files changed, 125 insertions(+), 107 deletions(-) create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapConstants.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapMainNetConstants.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapRegTestConstants.java create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java index dacd9127a5c..cf6c5866c54 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java @@ -21,8 +21,6 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.federation.constants.FederationConstants; -import co.rsk.peg.vote.AddressBasedAuthorizer; - import co.rsk.peg.feeperkb.constants.FeePerKbConstants; import co.rsk.peg.whitelist.constants.WhitelistConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; @@ -48,14 +46,6 @@ public abstract class BridgeConstants { protected Coin legacyMinimumPegoutTxValue; protected Coin minimumPegoutTxValue; - protected AddressBasedAuthorizer federationChangeAuthorizer; - - protected AddressBasedAuthorizer increaseLockingCapAuthorizer; - - protected Coin initialLockingCap; - - protected int lockingCapIncrementsMultiplier; - protected int btcHeightWhenBlockIndexActivates; protected int maxDepthToSearchBlocksBelowIndexActivation; protected long minSecondsBetweenCallsReceiveHeader; @@ -110,12 +100,6 @@ public Coin getMinimumPeginTxValue(ActivationConfig.ForBlock activations) { public Coin getMinimumPegoutTxValue() { return minimumPegoutTxValue; } - public AddressBasedAuthorizer getIncreaseLockingCapAuthorizer() { return increaseLockingCapAuthorizer; } - - public int getLockingCapIncrementsMultiplier() { return lockingCapIncrementsMultiplier; } - - public Coin getInitialLockingCap() { return initialLockingCap; } - public Coin getMaxRbtc() { return Coin.valueOf(21_000_000, 0); } public int getBtcHeightWhenBlockIndexActivates() { return btcHeightWhenBlockIndexActivates; } diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeDevNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeDevNetConstants.java index 72182875a96..cb4743d7469 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeDevNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeDevNetConstants.java @@ -21,14 +21,10 @@ import co.rsk.bitcoinj.core.BtcECKey; import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.peg.vote.AddressBasedAuthorizer; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; - import org.bouncycastle.util.encoders.Hex; -import org.ethereum.crypto.ECKey; public class BridgeDevNetConstants extends BridgeConstants { // IMPORTANT: BTC, RSK and MST keys are the same. @@ -62,35 +58,6 @@ public BridgeDevNetConstants(List federationPublicKeys) { minimumPeginTxValue = Coin.valueOf(500_000); minimumPegoutTxValue = Coin.valueOf(250_000); - // Keys generated with GenNodeKey using generators 'auth-a' through 'auth-e' - List federationChangeAuthorizedKeys = Arrays.stream(new String[]{ - "04dde17c5fab31ffc53c91c2390136c325bb8690dc135b0840075dd7b86910d8ab9e88baad0c32f3eea8833446a6bc5ff1cd2efa99ecb17801bcb65fc16fc7d991", - "04af886c67231476807e2a8eee9193878b9d94e30aa2ee469a9611d20e1e1c1b438e5044148f65e6e61bf03e9d72e597cb9cdea96d6fc044001b22099f9ec403e2", - "045d4dedf9c69ab3ea139d0f0da0ad00160b7663d01ce7a6155cd44a3567d360112b0480ab6f31cac7345b5f64862205ea7ccf555fcf218f87fa0d801008fecb61", - "04709f002ac4642b6a87ea0a9dc76eeaa93f71b3185985817ec1827eae34b46b5d869320efb5c5cbe2a5c13f96463fe0210710b53352a4314188daffe07bd54154", -// "04aff62315e9c18004392a5d9e39496ff5794b2d9f43ab4e8ade64740d7fdfe896969be859b43f26ef5aa4b5a0d11808277b4abfa1a07cc39f2839b89cc2bc6b4c" - "0447b4aba974c61c6c4045893267346730ec965b308e7ca04a899cf06a901face3106e1eef1bdad04928cd8263522eda4872d20d3fe1ef5e551785c4a482656a6e" - }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); - - federationChangeAuthorizer = new AddressBasedAuthorizer( - federationChangeAuthorizedKeys, - AddressBasedAuthorizer.MinimumRequiredCalculation.MAJORITY - ); - - // Key generated with GenNodeKey using generator 'auth-increase_locking_cap' - List increaseLockingCapAuthorizedKeys = Arrays.stream(new String[]{ - "04450bbaab83ec48b3cb8fbb077c950ee079733041c039a8c4f1539e5181ca1a27589eeaf0fbf430e49d2909f14c767bf6909ad6845831f683416ee12b832e36ed" - }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); - - increaseLockingCapAuthorizer = new AddressBasedAuthorizer( - increaseLockingCapAuthorizedKeys, - AddressBasedAuthorizer.MinimumRequiredCalculation.ONE - ); - - initialLockingCap = Coin.COIN.multiply(1_000L); // 1_000 BTC - - lockingCapIncrementsMultiplier = 2; - btcHeightWhenBlockIndexActivates = 700_000; maxDepthToSearchBlocksBelowIndexActivation = 4_320; // 30 days in BTC blocks (considering 1 block every 10 minutes) diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeMainNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeMainNetConstants.java index 13200fd9ed7..97a74c7658e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeMainNetConstants.java @@ -4,13 +4,7 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.federation.constants.FederationMainNetConstants; import co.rsk.peg.feeperkb.constants.FeePerKbMainNetConstants; -import co.rsk.peg.vote.AddressBasedAuthorizer; import co.rsk.peg.whitelist.constants.WhitelistMainNetConstants; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; -import org.bouncycastle.util.encoders.Hex; -import org.ethereum.crypto.ECKey; public class BridgeMainNetConstants extends BridgeConstants { private static final BridgeMainNetConstants instance = new BridgeMainNetConstants(); @@ -34,20 +28,6 @@ private BridgeMainNetConstants() { minimumPeginTxValue = Coin.valueOf(500_000); minimumPegoutTxValue = Coin.valueOf(400_000); - List increaseLockingCapAuthorizedKeys = Arrays.stream(new String[]{ - "0448f51638348b034995b1fd934fe14c92afde783e69f120a46ee16eb6bdc2e4f6b5e37772094c68c0dea2b1be3d96ea9651a9eebda7304914c8047f4e3e251378", - "0484c66f75548baf93e322574adac4e4579b6a53f8d11fab640e14c90118e6983ef24b0de349a3e88f72e81e771ae1c897cef446fd7f4da71778c532aee3b6c41b", - "04bb6435dc1ea12da843ebe213893d136c1624acd681fff82551498ae00bf28e9323164b00daf925fa75177463b8254a2aae8a1713e4d851a84ea369c193e9ce51" - }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); - - increaseLockingCapAuthorizer = new AddressBasedAuthorizer( - increaseLockingCapAuthorizedKeys, - AddressBasedAuthorizer.MinimumRequiredCalculation.ONE - ); - - lockingCapIncrementsMultiplier = 2; - initialLockingCap = Coin.COIN.multiply(300); // 300 BTC - btcHeightWhenBlockIndexActivates = 696_022; maxDepthToSearchBlocksBelowIndexActivation = 4_320; // 30 days in BTC blocks (considering 1 block every 10 minutes) diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeRegTestConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeRegTestConstants.java index e22042cb48e..8ac89033936 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeRegTestConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeRegTestConstants.java @@ -23,15 +23,12 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.federation.constants.FederationRegTestConstants; import co.rsk.peg.feeperkb.constants.FeePerKbRegTestConstants; -import co.rsk.peg.vote.AddressBasedAuthorizer; import co.rsk.peg.whitelist.constants.WhitelistRegTestConstants; -import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; import org.bouncycastle.util.encoders.Hex; -import org.ethereum.crypto.ECKey; public class BridgeRegTestConstants extends BridgeConstants { @@ -64,24 +61,10 @@ public BridgeRegTestConstants(List federationPublicKeys) { minimumPeginTxValue = Coin.COIN.div(2); minimumPegoutTxValue = Coin.valueOf(250_000); - initialLockingCap = Coin.COIN.multiply(1_000L); // 1_000 BTC - - lockingCapIncrementsMultiplier = 2; - minSecondsBetweenCallsReceiveHeader = 300; // 5 minutes in seconds maxDepthBlockchainAccepted = 25; - // Key generated with GenNodeKey using generator 'auth-increase_locking_cap' - List increaseLockingCapAuthorizedKeys = Arrays.stream(new String[]{ - "04450bbaab83ec48b3cb8fbb077c950ee079733041c039a8c4f1539e5181ca1a27589eeaf0fbf430e49d2909f14c767bf6909ad6845831f683416ee12b832e36ed" - }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); - - increaseLockingCapAuthorizer = new AddressBasedAuthorizer( - increaseLockingCapAuthorizedKeys, - AddressBasedAuthorizer.MinimumRequiredCalculation.ONE - ); - btcHeightWhenBlockIndexActivates = 10; maxDepthToSearchBlocksBelowIndexActivation = 5; diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNetConstants.java index 040262d4922..bb50898cbad 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeTestNetConstants.java @@ -21,14 +21,8 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.federation.constants.FederationTestNetConstants; -import co.rsk.peg.vote.AddressBasedAuthorizer; -import co.rsk.peg.whitelist.constants.WhitelistTestNetConstants; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; import co.rsk.peg.feeperkb.constants.FeePerKbTestNetConstants; -import org.bouncycastle.util.encoders.Hex; -import org.ethereum.crypto.ECKey; +import co.rsk.peg.whitelist.constants.WhitelistTestNetConstants; public class BridgeTestNetConstants extends BridgeConstants { private static final BridgeTestNetConstants instance = new BridgeTestNetConstants(); @@ -52,20 +46,6 @@ public class BridgeTestNetConstants extends BridgeConstants { legacyMinimumPegoutTxValue = Coin.valueOf(500_000); minimumPegoutTxValue = Coin.valueOf(250_000); - List increaseLockingCapAuthorizedKeys = Arrays.stream(new String[]{ - "04701d1d27f8c2ae97912d96fb1f82f10c2395fd320e7a869049268c6b53d2060dfb2e22e3248955332d88cd2ae29a398f8f3858e48dd6d8ffbc37dfd6d1aa4934", - "045ef89e4a5645dc68895dbc33b4c966c3a0a52bb837ecdd2ba448604c4f47266456d1191420e1d32bbe8741f8315fde4d1440908d400e5998dbed6549d499559b", - "0455db9b3867c14e84a6f58bd2165f13bfdba0703cb84ea85788373a6a109f3717e40483aa1f8ef947f435ccdf10e530dd8b3025aa2d4a7014f12180ee3a301d27" - }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); - - increaseLockingCapAuthorizer = new AddressBasedAuthorizer( - increaseLockingCapAuthorizedKeys, - AddressBasedAuthorizer.MinimumRequiredCalculation.ONE - ); - - lockingCapIncrementsMultiplier = 2; - initialLockingCap = Coin.COIN.multiply(200); // 200 BTC - btcHeightWhenBlockIndexActivates = 2_039_594; maxDepthToSearchBlocksBelowIndexActivation = 4_320; // 30 days in BTC blocks (considering 1 block every 10 minutes) diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapConstants.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapConstants.java new file mode 100644 index 00000000000..8e138664e01 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapConstants.java @@ -0,0 +1,23 @@ +package co.rsk.peg.lockingcap.constants; + +import co.rsk.bitcoinj.core.Coin; +import co.rsk.peg.vote.AddressBasedAuthorizer; + +public class LockingCapConstants { + + protected AddressBasedAuthorizer increaseAuthorizer; + protected Coin initialValue; + protected int incrementsMultiplier; + + public AddressBasedAuthorizer getIncreaseAuthorizer() { + return increaseAuthorizer; + } + + public int getIncrementsMultiplier() { + return incrementsMultiplier; + } + + public Coin getInitialValue() { + return initialValue; + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapMainNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapMainNetConstants.java new file mode 100644 index 00000000000..c679b6c253f --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapMainNetConstants.java @@ -0,0 +1,34 @@ +package co.rsk.peg.lockingcap.constants; + +import co.rsk.bitcoinj.core.Coin; +import co.rsk.peg.vote.AddressBasedAuthorizer; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.bouncycastle.util.encoders.Hex; +import org.ethereum.crypto.ECKey; + +public class LockingCapMainNetConstants extends LockingCapConstants { + + private static final LockingCapMainNetConstants instance = new LockingCapMainNetConstants(); + + private LockingCapMainNetConstants() { + List increaseAuthorizedKeys = Arrays.stream(new String[]{ + "0448f51638348b034995b1fd934fe14c92afde783e69f120a46ee16eb6bdc2e4f6b5e37772094c68c0dea2b1be3d96ea9651a9eebda7304914c8047f4e3e251378", + "0484c66f75548baf93e322574adac4e4579b6a53f8d11fab640e14c90118e6983ef24b0de349a3e88f72e81e771ae1c897cef446fd7f4da71778c532aee3b6c41b", + "04bb6435dc1ea12da843ebe213893d136c1624acd681fff82551498ae00bf28e9323164b00daf925fa75177463b8254a2aae8a1713e4d851a84ea369c193e9ce51" + }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); + + increaseAuthorizer = new AddressBasedAuthorizer( + increaseAuthorizedKeys, + AddressBasedAuthorizer.MinimumRequiredCalculation.ONE + ); + + initialValue = Coin.COIN.multiply(300L); // 300 BTC + incrementsMultiplier = 2; + } + + public static LockingCapMainNetConstants getInstance() { + return instance; + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapRegTestConstants.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapRegTestConstants.java new file mode 100644 index 00000000000..2df976a04ff --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapRegTestConstants.java @@ -0,0 +1,33 @@ +package co.rsk.peg.lockingcap.constants; + +import co.rsk.bitcoinj.core.Coin; +import co.rsk.peg.vote.AddressBasedAuthorizer; +import java.util.Collections; +import java.util.List; +import org.bouncycastle.util.encoders.Hex; +import org.ethereum.crypto.ECKey; + +public class LockingCapRegTestConstants extends LockingCapConstants { + + private static final LockingCapRegTestConstants instance = new LockingCapRegTestConstants(); + + private LockingCapRegTestConstants() { + ECKey authorizerPublicKey = ECKey.fromPublicOnly(Hex.decode( + "04450bbaab83ec48b3cb8fbb077c950ee079733041c039a8c4f1539e5181ca1a27589eeaf0fbf430e49d2909f14c767bf6909ad6845831f683416ee12b832e36ed" + )); + + List increaseAuthorizedKeys = Collections.singletonList(authorizerPublicKey); + + increaseAuthorizer = new AddressBasedAuthorizer( + increaseAuthorizedKeys, + AddressBasedAuthorizer.MinimumRequiredCalculation.ONE + ); + + initialValue = Coin.COIN.multiply(1_000L); // 1000 BTC + incrementsMultiplier = 2; + } + + public static LockingCapRegTestConstants getInstance() { + return instance; + } +} diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java new file mode 100644 index 00000000000..52d8b39acf3 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java @@ -0,0 +1,34 @@ +package co.rsk.peg.lockingcap.constants; + +import co.rsk.bitcoinj.core.Coin; +import co.rsk.peg.vote.AddressBasedAuthorizer; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; +import org.bouncycastle.util.encoders.Hex; +import org.ethereum.crypto.ECKey; + +public class LockingCapTestNetConstants extends LockingCapConstants { + + private static final LockingCapTestNetConstants instance = new LockingCapTestNetConstants(); + + private LockingCapTestNetConstants() { + List increaseAuthorizedKeys = Arrays.stream(new String[]{ + "04701d1d27f8c2ae97912d96fb1f82f10c2395fd320e7a869049268c6b53d2060dfb2e22e3248955332d88cd2ae29a398f8f3858e48dd6d8ffbc37dfd6d1aa4934", + "045ef89e4a5645dc68895dbc33b4c966c3a0a52bb837ecdd2ba448604c4f47266456d1191420e1d32bbe8741f8315fde4d1440908d400e5998dbed6549d499559b", + "0455db9b3867c14e84a6f58bd2165f13bfdba0703cb84ea85788373a6a109f3717e40483aa1f8ef947f435ccdf10e530dd8b3025aa2d4a7014f12180ee3a301d27" + }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); + + increaseAuthorizer = new AddressBasedAuthorizer( + increaseAuthorizedKeys, + AddressBasedAuthorizer.MinimumRequiredCalculation.ONE + ); + + incrementsMultiplier = 2; + initialValue = Coin.COIN.multiply(200L); // 200 BTC + } + + public static LockingCapTestNetConstants getInstance() { + return instance; + } +} From 1c9b2bf43979432c9b4dc4f77f37235f8b1e5d4c Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Tue, 16 Jul 2024 02:31:48 -0400 Subject: [PATCH 02/40] Create LockingCapStorageIndexKey Enum Create the package lockingcap with an enum to hold the storage index key for locking cap value. Create a new enum LockingCapStorageIndexKey to contain the index key for the locking cap value in storage, remove it from BridgeStorageIndexKey, remove the. _KEY suffix, and rename to LOCKING_CAP. --- .../java/co/rsk/peg/BridgeStorageIndexKey.java | 1 - .../lockingcap/LockingCapStorageIndexKey.java | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageIndexKey.java diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageIndexKey.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageIndexKey.java index 47da68f3def..9c42f5952ed 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageIndexKey.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageIndexKey.java @@ -8,7 +8,6 @@ public enum BridgeStorageIndexKey { RELEASE_REQUEST_QUEUE("releaseRequestQueue"), PEGOUTS_WAITING_FOR_CONFIRMATIONS("releaseTransactionSet"), PEGOUTS_WAITING_FOR_SIGNATURES("rskTxsWaitingFS"), - LOCKING_CAP_KEY("lockingCap"), RELEASE_REQUEST_QUEUE_WITH_TXHASH("releaseRequestQueueWithTxHash"), PEGOUTS_WAITING_FOR_CONFIRMATIONS_WITH_TXHASH_KEY("releaseTransactionSetWithTxHash"), RECEIVE_HEADERS_TIMESTAMP("receiveHeadersLastTimestamp"), diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageIndexKey.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageIndexKey.java new file mode 100644 index 00000000000..38fed2b0cab --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageIndexKey.java @@ -0,0 +1,17 @@ +package co.rsk.peg.lockingcap; + +import org.ethereum.vm.DataWord; + +public enum LockingCapStorageIndexKey { + LOCKING_CAP("lockingCap"); + + private final String key; + + LockingCapStorageIndexKey(String key) { + this.key = key; + } + + public DataWord getKey() { + return DataWord.fromString(key); + } +} From 83c93bedf52a936cf84e6ef110fd2bce50c9b561 Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Tue, 16 Jul 2024 02:48:19 -0400 Subject: [PATCH 03/40] Locking Cap Storage Provider Interface Create an interface LockingCapStorageProvider under co.rsk.peg.lockingcap package. Include the signature of the methods mentioned above. Rename saveLockingCap to simply save --- .../peg/lockingcap/LockingCapStorageProvider.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java new file mode 100644 index 00000000000..89c94be1e62 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java @@ -0,0 +1,12 @@ +package co.rsk.peg.lockingcap; + +import co.rsk.bitcoinj.core.Coin; + +public interface LockingCapStorageProvider { + + Coin getLockingCap(); + + void setLockingCap(Coin lockingCap); + + void save(); +} From 06f541eabd43b1a0385abb3cb24e0879a3ae81cd Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Tue, 16 Jul 2024 03:06:25 -0400 Subject: [PATCH 04/40] LockingCapSupport Interface Create a new interface LockingCapSupport under the co.rsk.peg.lockingcap package. Copy the signature and javadoc for the methods: getLockingCap and increaseLockingCap. --- .../java/co/rsk/peg/lockingcap/LockingCapSupport.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java new file mode 100644 index 00000000000..58e7d620fb5 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java @@ -0,0 +1,11 @@ +package co.rsk.peg.lockingcap; + +import co.rsk.bitcoinj.core.Coin; +import org.ethereum.core.Transaction; + +public interface LockingCapSupport { + + Coin getLockingCap(); + + boolean increaseLockingCap(Transaction tx, Coin newCap); +} From 07901e6d8fc167c742f19459f56da6766e1f8e6c Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Tue, 16 Jul 2024 03:52:22 -0400 Subject: [PATCH 05/40] LockingCapConstants Test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Following the Bridge refactors, we already migrated the LockingCapConstants to their classes to break the high coupling LockingCap had with the Bridge objects, however, it’s missing add coverage, so we need to create Unit Tests to get reliability that your new code doesn't break existing functionality when a change is made to the application. Create Unit Tests for all methods in LockingCapConstants Create Test Cases for all Networks such as MainNet, TestNet, and RegTest. --- .../constants/LockingCapConstants.java | 8 +- .../constants/LockingCapTestNetConstants.java | 2 +- .../constants/LockingCapConstantsTest.java | 118 ++++++++++++++++++ 3 files changed, 123 insertions(+), 5 deletions(-) create mode 100644 rskj-core/src/test/java/co/rsk/peg/lockingcap/constants/LockingCapConstantsTest.java diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapConstants.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapConstants.java index 8e138664e01..b0a916dcb67 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapConstants.java @@ -13,11 +13,11 @@ public AddressBasedAuthorizer getIncreaseAuthorizer() { return increaseAuthorizer; } - public int getIncrementsMultiplier() { - return incrementsMultiplier; - } - public Coin getInitialValue() { return initialValue; } + + public int getIncrementsMultiplier() { + return incrementsMultiplier; + } } diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java index 52d8b39acf3..d6d43f6b51b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java @@ -24,8 +24,8 @@ private LockingCapTestNetConstants() { AddressBasedAuthorizer.MinimumRequiredCalculation.ONE ); - incrementsMultiplier = 2; initialValue = Coin.COIN.multiply(200L); // 200 BTC + incrementsMultiplier = 2; } public static LockingCapTestNetConstants getInstance() { diff --git a/rskj-core/src/test/java/co/rsk/peg/lockingcap/constants/LockingCapConstantsTest.java b/rskj-core/src/test/java/co/rsk/peg/lockingcap/constants/LockingCapConstantsTest.java new file mode 100644 index 00000000000..023d551326c --- /dev/null +++ b/rskj-core/src/test/java/co/rsk/peg/lockingcap/constants/LockingCapConstantsTest.java @@ -0,0 +1,118 @@ +package co.rsk.peg.lockingcap.constants; + +import static org.junit.jupiter.api.Assertions.*; + +import co.rsk.bitcoinj.core.Coin; +import co.rsk.peg.vote.AddressBasedAuthorizer; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.bouncycastle.util.encoders.Hex; +import org.ethereum.crypto.ECKey; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class LockingCapConstantsTest { + + @ParameterizedTest + @MethodSource("getIncreaseAuthorizerProvider") + void getIncreaseAuthorizer(LockingCapConstants lockingCapConstants, AddressBasedAuthorizer expectedIncreaseAuthorizer) { + AddressBasedAuthorizer actualIncreaseAuthorizer = lockingCapConstants.getIncreaseAuthorizer(); + assertEquals(expectedIncreaseAuthorizer, actualIncreaseAuthorizer); + } + + private static Stream getIncreaseAuthorizerProvider() { + // MainNet + List mainNetIncreaseAuthorizedKeys = Arrays.stream(new String[]{ + "0448f51638348b034995b1fd934fe14c92afde783e69f120a46ee16eb6bdc2e4f6b5e37772094c68c0dea2b1be3d96ea9651a9eebda7304914c8047f4e3e251378", + "0484c66f75548baf93e322574adac4e4579b6a53f8d11fab640e14c90118e6983ef24b0de349a3e88f72e81e771ae1c897cef446fd7f4da71778c532aee3b6c41b", + "04bb6435dc1ea12da843ebe213893d136c1624acd681fff82551498ae00bf28e9323164b00daf925fa75177463b8254a2aae8a1713e4d851a84ea369c193e9ce51" + }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); + + AddressBasedAuthorizer mainNetIncreaseAuthorizer = new AddressBasedAuthorizer( + mainNetIncreaseAuthorizedKeys, + AddressBasedAuthorizer.MinimumRequiredCalculation.ONE + ); + + // TestNet + List testNetIncreaseAuthorizedKeys = Arrays.stream(new String[]{ + "04701d1d27f8c2ae97912d96fb1f82f10c2395fd320e7a869049268c6b53d2060dfb2e22e3248955332d88cd2ae29a398f8f3858e48dd6d8ffbc37dfd6d1aa4934", + "045ef89e4a5645dc68895dbc33b4c966c3a0a52bb837ecdd2ba448604c4f47266456d1191420e1d32bbe8741f8315fde4d1440908d400e5998dbed6549d499559b", + "0455db9b3867c14e84a6f58bd2165f13bfdba0703cb84ea85788373a6a109f3717e40483aa1f8ef947f435ccdf10e530dd8b3025aa2d4a7014f12180ee3a301d27" + }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); + + AddressBasedAuthorizer testNetIncreaseAuthorizer = new AddressBasedAuthorizer( + testNetIncreaseAuthorizedKeys, + AddressBasedAuthorizer.MinimumRequiredCalculation.ONE + ); + + // RegTest + ECKey authorizerPublicKey = ECKey.fromPublicOnly(Hex.decode( + "04450bbaab83ec48b3cb8fbb077c950ee079733041c039a8c4f1539e5181ca1a27589eeaf0fbf430e49d2909f14c767bf6909ad6845831f683416ee12b832e36ed" + )); + + List regTestIncreaseAuthorizedKeys = Collections.singletonList(authorizerPublicKey); + + AddressBasedAuthorizer regTestIncreaseAuthorizer = new AddressBasedAuthorizer( + regTestIncreaseAuthorizedKeys, + AddressBasedAuthorizer.MinimumRequiredCalculation.ONE + ); + + return Stream.of( + Arguments.of(LockingCapMainNetConstants.getInstance(), mainNetIncreaseAuthorizer), + Arguments.of(LockingCapTestNetConstants.getInstance(), testNetIncreaseAuthorizer), + Arguments.of(LockingCapRegTestConstants.getInstance(), regTestIncreaseAuthorizer) + ); + } + + @ParameterizedTest + @MethodSource("getInitialValueProvider") + void getInitialValue(LockingCapConstants lockingCapConstants, Coin expectedInitialValue) { + Coin actualInitialValue = lockingCapConstants.getInitialValue(); + assertEquals(expectedInitialValue, actualInitialValue); + } + + private static Stream getInitialValueProvider() { + // MainNet + Coin mainNetInitialValue = Coin.COIN.multiply(300L); + + // TestNet + Coin testNetInitialValue = Coin.COIN.multiply(200L); + + // RegTest + Coin regTestInitialValue = Coin.COIN.multiply(1_000L); + + return Stream.of( + Arguments.of(LockingCapMainNetConstants.getInstance(), mainNetInitialValue), + Arguments.of(LockingCapTestNetConstants.getInstance(), testNetInitialValue), + Arguments.of(LockingCapRegTestConstants.getInstance(), regTestInitialValue) + ); + } + + @ParameterizedTest + @MethodSource("getIncrementsMultiplierProvider") + void getIncrementsMultiplier(LockingCapConstants lockingCapConstants, int expectedIncrementsMultiplier) { + int actualIncrementsMultiplier = lockingCapConstants.getIncrementsMultiplier(); + assertEquals(expectedIncrementsMultiplier, actualIncrementsMultiplier); + } + + private static Stream getIncrementsMultiplierProvider() { + // MainNet + int mainNetIncrementsMultiplier = 2; + + // TestNet + int testNetIncrementsMultiplier = 2; + + // RegTest + int regTestIncrementsMultiplier = 2; + + return Stream.of( + Arguments.of(LockingCapMainNetConstants.getInstance(), mainNetIncrementsMultiplier), + Arguments.of(LockingCapTestNetConstants.getInstance(), testNetIncrementsMultiplier), + Arguments.of(LockingCapRegTestConstants.getInstance(), regTestIncrementsMultiplier) + ); + } +} From de22bfd398adc98fead227062aaead49ffc56263 Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Tue, 16 Jul 2024 11:53:01 -0400 Subject: [PATCH 06/40] Adding An Optional To Return Value getLockingCap() Method Adding An Optional To Return Value getLockingCap() Method --- .../java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java | 3 ++- .../src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java index 89c94be1e62..afbbf9b7f61 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java @@ -1,10 +1,11 @@ package co.rsk.peg.lockingcap; import co.rsk.bitcoinj.core.Coin; +import java.util.Optional; public interface LockingCapStorageProvider { - Coin getLockingCap(); + Optional getLockingCap(); void setLockingCap(Coin lockingCap); diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java index 58e7d620fb5..31d35e8ce4e 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java @@ -1,11 +1,12 @@ package co.rsk.peg.lockingcap; import co.rsk.bitcoinj.core.Coin; +import java.util.Optional; import org.ethereum.core.Transaction; public interface LockingCapSupport { - Coin getLockingCap(); + Optional getLockingCap(); boolean increaseLockingCap(Transaction tx, Coin newCap); } From 86bd4902dd3549abeb01cd85ebb891a8c50a1be8 Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Tue, 16 Jul 2024 13:54:51 -0400 Subject: [PATCH 07/40] Removing Arrays.stream From increaseAuthorizedKeys Variable Removing Arrays.stream From increaseAuthorizedKeys Variable and replacing it with Collections.unmodifiableList(Stream.of() --- .../lockingcap/constants/LockingCapMainNetConstants.java | 7 ++++--- .../lockingcap/constants/LockingCapTestNetConstants.java | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapMainNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapMainNetConstants.java index c679b6c253f..01e0e2b37bf 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapMainNetConstants.java @@ -2,9 +2,10 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.peg.vote.AddressBasedAuthorizer; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.bouncycastle.util.encoders.Hex; import org.ethereum.crypto.ECKey; @@ -13,11 +14,11 @@ public class LockingCapMainNetConstants extends LockingCapConstants { private static final LockingCapMainNetConstants instance = new LockingCapMainNetConstants(); private LockingCapMainNetConstants() { - List increaseAuthorizedKeys = Arrays.stream(new String[]{ + List increaseAuthorizedKeys = Collections.unmodifiableList(Stream.of( "0448f51638348b034995b1fd934fe14c92afde783e69f120a46ee16eb6bdc2e4f6b5e37772094c68c0dea2b1be3d96ea9651a9eebda7304914c8047f4e3e251378", "0484c66f75548baf93e322574adac4e4579b6a53f8d11fab640e14c90118e6983ef24b0de349a3e88f72e81e771ae1c897cef446fd7f4da71778c532aee3b6c41b", "04bb6435dc1ea12da843ebe213893d136c1624acd681fff82551498ae00bf28e9323164b00daf925fa75177463b8254a2aae8a1713e4d851a84ea369c193e9ce51" - }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); + ).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList())); increaseAuthorizer = new AddressBasedAuthorizer( increaseAuthorizedKeys, diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java index d6d43f6b51b..1a8985907c5 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/constants/LockingCapTestNetConstants.java @@ -2,9 +2,10 @@ import co.rsk.bitcoinj.core.Coin; import co.rsk.peg.vote.AddressBasedAuthorizer; -import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.bouncycastle.util.encoders.Hex; import org.ethereum.crypto.ECKey; @@ -13,11 +14,11 @@ public class LockingCapTestNetConstants extends LockingCapConstants { private static final LockingCapTestNetConstants instance = new LockingCapTestNetConstants(); private LockingCapTestNetConstants() { - List increaseAuthorizedKeys = Arrays.stream(new String[]{ + List increaseAuthorizedKeys = Collections.unmodifiableList(Stream.of( "04701d1d27f8c2ae97912d96fb1f82f10c2395fd320e7a869049268c6b53d2060dfb2e22e3248955332d88cd2ae29a398f8f3858e48dd6d8ffbc37dfd6d1aa4934", "045ef89e4a5645dc68895dbc33b4c966c3a0a52bb837ecdd2ba448604c4f47266456d1191420e1d32bbe8741f8315fde4d1440908d400e5998dbed6549d499559b", "0455db9b3867c14e84a6f58bd2165f13bfdba0703cb84ea85788373a6a109f3717e40483aa1f8ef947f435ccdf10e530dd8b3025aa2d4a7014f12180ee3a301d27" - }).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList()); + ).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList())); increaseAuthorizer = new AddressBasedAuthorizer( increaseAuthorizedKeys, From bfe4e85251ef027a7a378c7b07cd81f099a9f776 Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Wed, 17 Jul 2024 23:44:32 -0400 Subject: [PATCH 08/40] Create LockingCapConstants in BridgeConstants Following with the Bridge refactors, it is now time to refactor and remove locking cap logic from BridgeSupport class. Create LockingCapConstants in BridgeConstants. --- .../src/main/java/co/rsk/peg/constants/BridgeConstants.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java index cf6c5866c54..165681b8770 100644 --- a/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/constants/BridgeConstants.java @@ -22,6 +22,7 @@ import co.rsk.bitcoinj.core.NetworkParameters; import co.rsk.peg.federation.constants.FederationConstants; import co.rsk.peg.feeperkb.constants.FeePerKbConstants; +import co.rsk.peg.lockingcap.constants.LockingCapConstants; import co.rsk.peg.whitelist.constants.WhitelistConstants; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.config.blockchain.upgrades.ConsensusRule; @@ -32,6 +33,7 @@ public abstract class BridgeConstants { protected FeePerKbConstants feePerKbConstants; protected WhitelistConstants whitelistConstants; protected FederationConstants federationConstants; + protected LockingCapConstants lockingCapConstants; protected int btc2RskMinimumAcceptableConfirmations; protected int btc2RskMinimumAcceptableConfirmationsOnRsk; @@ -72,6 +74,8 @@ public NetworkParameters getBtcParams() { public FederationConstants getFederationConstants() { return federationConstants; } + public LockingCapConstants getLockingCapConstants() { return lockingCapConstants; } + public String getBtcParamsString() { return btcParamsString; } From 686541af4ad06a91b3d4bbdfd3ccfb54d348b724 Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Thu, 18 Jul 2024 11:53:47 -0400 Subject: [PATCH 09/40] Add LockingCapSupport To BridgeSupportBuilder Following with the Bridge refactors, it is now time to refactor and remove locking cap logic from Bridge objects to LockingCap objects. This time we need to add Locking Cap logic to BridgeSupportBuilder class. Add WhitelistSupport to BridgeSupportBuilder business logic. Rebasing Changes With Integration Branch Rebasing Changes With Integration Branch --- .../co/rsk/peg/BridgeStorageProvider.java | 24 --------- .../main/java/co/rsk/peg/BridgeSupport.java | 5 ++ .../LockingCapStorageProviderImpl.java | 51 +++++++++++++++++++ .../test/builders/BridgeSupportBuilder.java | 9 ++++ 4 files changed, 65 insertions(+), 24 deletions(-) create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java index 38c821473cc..f7fe046e510 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeStorageProvider.java @@ -62,8 +62,6 @@ public class BridgeStorageProvider { private PegoutsWaitingForConfirmations pegoutsWaitingForConfirmations; private SortedMap pegoutsWaitingForSignatures; - private Coin lockingCap; - private HashMap btcTxHashesToSave; private Map coinbaseInformationMap; @@ -250,26 +248,6 @@ public void savePegoutsWaitingForSignatures() { safeSaveToRepository(PEGOUTS_WAITING_FOR_SIGNATURES, pegoutsWaitingForSignatures, BridgeSerializationUtils::serializeMap); } - public void saveLockingCap() { - if (activations.isActive(RSKIP134)) { - safeSaveToRepository(LOCKING_CAP_KEY, this.getLockingCap(), BridgeSerializationUtils::serializeCoin); - } - } - - public void setLockingCap(Coin lockingCap) { - this.lockingCap = lockingCap; - } - - public Coin getLockingCap() { - if (activations.isActive(RSKIP134)) { - if (this.lockingCap == null) { - this.lockingCap = safeGetFromRepository(LOCKING_CAP_KEY, BridgeSerializationUtils::deserializeCoin); - } - return this.lockingCap; - } - return null; - } - public CoinbaseInformation getCoinbaseInformation(Sha256Hash blockHash) { if (!activations.isActive(RSKIP143)) { return null; @@ -549,8 +527,6 @@ public void save() throws IOException { savePegoutsWaitingForConfirmations(); savePegoutsWaitingForSignatures(); - saveLockingCap(); - saveHeightBtcTxHashAlreadyProcessed(); saveCoinbaseInformations(); 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 6a864cff6e6..202241fb0b7 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -45,6 +45,7 @@ import co.rsk.peg.feeperkb.FeePerKbSupport; import co.rsk.peg.flyover.FlyoverFederationInformation; import co.rsk.peg.flyover.FlyoverTxResponseCodes; +import co.rsk.peg.lockingcap.LockingCapSupport; import co.rsk.peg.pegin.*; import co.rsk.peg.pegininstructions.PeginInstructionsException; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; @@ -116,6 +117,7 @@ public class BridgeSupport { private final FeePerKbSupport feePerKbSupport; private final WhitelistSupport whitelistSupport; private final FederationSupport federationSupport; + private final LockingCapSupport lockingCapSupport; private final Context btcContext; private final BtcBlockStoreWithCache.Factory btcBlockStoreFactory; @@ -138,6 +140,7 @@ public BridgeSupport( FeePerKbSupport feePerKbSupport, WhitelistSupport whitelistSupport, FederationSupport federationSupport, + LockingCapSupport lockingCapSupport, BtcBlockStoreWithCache.Factory btcBlockStoreFactory, ActivationConfig.ForBlock activations, SignatureCache signatureCache) { @@ -152,6 +155,7 @@ public BridgeSupport( this.feePerKbSupport = feePerKbSupport; this.whitelistSupport = whitelistSupport; this.federationSupport = federationSupport; + this.lockingCapSupport = lockingCapSupport; this.btcBlockStoreFactory = btcBlockStoreFactory; this.activations = activations; this.signatureCache = signatureCache; @@ -178,6 +182,7 @@ public void save() throws IOException { feePerKbSupport.save(); whitelistSupport.save(); federationSupport.save(); + // TODO: save lockingCapSupport.save(); } /** diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java new file mode 100644 index 00000000000..ff1ba1bacc1 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java @@ -0,0 +1,51 @@ +package co.rsk.peg.lockingcap; + +import static co.rsk.peg.lockingcap.LockingCapStorageIndexKey.LOCKING_CAP; +import static org.ethereum.config.blockchain.upgrades.ConsensusRule.RSKIP134; + +import co.rsk.bitcoinj.core.Coin; +import co.rsk.peg.BridgeSerializationUtils; +import co.rsk.peg.storage.StorageAccessor; +import java.util.Optional; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; + +public class LockingCapStorageProviderImpl implements LockingCapStorageProvider { + + private Coin lockingCap; + private final ActivationConfig.ForBlock activations; + private final StorageAccessor bridgeStorageAccessor; + + public LockingCapStorageProviderImpl( + ActivationConfig.ForBlock activations, + StorageAccessor bridgeStorageAccessor) { + this.activations = activations; + this.bridgeStorageAccessor = bridgeStorageAccessor; + } + + @Override + public Optional getLockingCap() { + if (activations.isActive(RSKIP134)) { + if (lockingCap == null) { + lockingCap = initializeLockingCap(); + } + return Optional.of(lockingCap); + } + return Optional.empty(); + } + + private synchronized Coin initializeLockingCap() { + return bridgeStorageAccessor.getFromRepository(LOCKING_CAP.getKey(), BridgeSerializationUtils::deserializeCoin); + } + + @Override + public void setLockingCap(Coin lockingCap) { + this.lockingCap = lockingCap; + } + + @Override + public void save() { + if (activations.isActive(RSKIP134)) { + bridgeStorageAccessor.saveToRepository(LOCKING_CAP.getKey(), getLockingCap().get(), BridgeSerializationUtils::serializeCoin); + } + } +} diff --git a/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java b/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java index d93d325e2d0..913d4ef13f5 100644 --- a/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java +++ b/rskj-core/src/test/java/co/rsk/test/builders/BridgeSupportBuilder.java @@ -10,6 +10,7 @@ import co.rsk.peg.constants.BridgeConstants; import co.rsk.peg.federation.FederationSupport; import co.rsk.peg.feeperkb.FeePerKbSupport; +import co.rsk.peg.lockingcap.LockingCapSupport; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.utils.BridgeEventLogger; import co.rsk.peg.whitelist.WhitelistSupport; @@ -27,6 +28,7 @@ public class BridgeSupportBuilder { private FeePerKbSupport feePerKbSupport; private WhitelistSupport whitelistSupport; private FederationSupport federationSupport; + private LockingCapSupport lockingCapSupport; private Factory btcBlockStoreFactory; private ActivationConfig.ForBlock activations; private SignatureCache signatureCache; @@ -42,6 +44,7 @@ public BridgeSupportBuilder() { this.feePerKbSupport = mock(FeePerKbSupport.class); this.whitelistSupport = mock(WhitelistSupport.class); this.federationSupport = mock(FederationSupport.class); + this.lockingCapSupport = mock(LockingCapSupport.class); this.btcBlockStoreFactory = mock(Factory.class); this.activations = mock(ActivationConfig.ForBlock.class); this.signatureCache = mock(BlockTxSignatureCache.class); @@ -97,6 +100,11 @@ public BridgeSupportBuilder withFederationSupport(FederationSupport federationSu return this; } + public BridgeSupportBuilder withLockingCapSupport(LockingCapSupport lockingCapSupport) { + this.lockingCapSupport = lockingCapSupport; + return this; + } + public BridgeSupportBuilder withBtcBlockStoreFactory(Factory btcBlockStoreFactory) { this.btcBlockStoreFactory = btcBlockStoreFactory; return this; @@ -127,6 +135,7 @@ public BridgeSupport build() { feePerKbSupport, whitelistSupport, federationSupport, + lockingCapSupport, btcBlockStoreFactory, activations, signatureCache From f78079dabd3d4b24f2fbc599cffe74e4179b5473 Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Wed, 17 Jul 2024 12:03:23 -0400 Subject: [PATCH 10/40] Removing activations as a Variable in the Provider --- .../lockingcap/LockingCapStorageProvider.java | 5 +++-- .../LockingCapStorageProviderImpl.java | 16 ++++++++-------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java index afbbf9b7f61..724777694ae 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProvider.java @@ -2,12 +2,13 @@ import co.rsk.bitcoinj.core.Coin; import java.util.Optional; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; public interface LockingCapStorageProvider { - Optional getLockingCap(); + Optional getLockingCap(ActivationConfig.ForBlock activations); void setLockingCap(Coin lockingCap); - void save(); + void save(ActivationConfig.ForBlock activations); } diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java index ff1ba1bacc1..6e884c339b7 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java @@ -12,18 +12,14 @@ public class LockingCapStorageProviderImpl implements LockingCapStorageProvider { private Coin lockingCap; - private final ActivationConfig.ForBlock activations; private final StorageAccessor bridgeStorageAccessor; - public LockingCapStorageProviderImpl( - ActivationConfig.ForBlock activations, - StorageAccessor bridgeStorageAccessor) { - this.activations = activations; + public LockingCapStorageProviderImpl(StorageAccessor bridgeStorageAccessor) { this.bridgeStorageAccessor = bridgeStorageAccessor; } @Override - public Optional getLockingCap() { + public Optional getLockingCap(ActivationConfig.ForBlock activations) { if (activations.isActive(RSKIP134)) { if (lockingCap == null) { lockingCap = initializeLockingCap(); @@ -43,9 +39,13 @@ public void setLockingCap(Coin lockingCap) { } @Override - public void save() { + public void save(ActivationConfig.ForBlock activations) { if (activations.isActive(RSKIP134)) { - bridgeStorageAccessor.saveToRepository(LOCKING_CAP.getKey(), getLockingCap().get(), BridgeSerializationUtils::serializeCoin); + bridgeStorageAccessor.saveToRepository( + LOCKING_CAP.getKey(), + getLockingCap(activations).get(), + BridgeSerializationUtils::serializeCoin + ); } } } From 82f85ba3d9440b398697732b3df90e0782f13e2f Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Wed, 17 Jul 2024 20:23:16 -0400 Subject: [PATCH 11/40] Fixing Issue When lockingCap Is Optional.empty() - To avoid an NoSuchElementException trying to get the value from Optional.get() when is Optional.empty(), use orElse(null) method. Assigning a value to an instance variable - Assigning a value to an instance variable instead of return and after that assign. Improving readiness, readability and maintainability - Instead of enclosing in an IF a block of code, we ensure we have the RSKIP134 to execute the rest of the code. --- .../LockingCapStorageProviderImpl.java | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java index 6e884c339b7..35557083c02 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapStorageProviderImpl.java @@ -22,15 +22,15 @@ public LockingCapStorageProviderImpl(StorageAccessor bridgeStorageAccessor) { public Optional getLockingCap(ActivationConfig.ForBlock activations) { if (activations.isActive(RSKIP134)) { if (lockingCap == null) { - lockingCap = initializeLockingCap(); + initializeLockingCap(); } return Optional.of(lockingCap); } return Optional.empty(); } - private synchronized Coin initializeLockingCap() { - return bridgeStorageAccessor.getFromRepository(LOCKING_CAP.getKey(), BridgeSerializationUtils::deserializeCoin); + private synchronized void initializeLockingCap() { + lockingCap = bridgeStorageAccessor.getFromRepository(LOCKING_CAP.getKey(), BridgeSerializationUtils::deserializeCoin); } @Override @@ -40,12 +40,15 @@ public void setLockingCap(Coin lockingCap) { @Override public void save(ActivationConfig.ForBlock activations) { - if (activations.isActive(RSKIP134)) { - bridgeStorageAccessor.saveToRepository( - LOCKING_CAP.getKey(), - getLockingCap(activations).get(), - BridgeSerializationUtils::serializeCoin - ); + if (!activations.isActive(RSKIP134)) { + return; } + + Coin currentLockingCap = getLockingCap(activations).orElse(null); + bridgeStorageAccessor.saveToRepository( + LOCKING_CAP.getKey(), + currentLockingCap, + BridgeSerializationUtils::serializeCoin + ); } } From 7baf0ed05aac597fe2f6a1f0d08524b56d7e36c3 Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Wed, 17 Jul 2024 15:14:33 -0400 Subject: [PATCH 12/40] LockingCapSupport Implementation After LockingCapSupport interface has been created, it is time to implement it. Create a new class LockingCapSupportImpl under co.rsk.peg.lockingcap package that implements the methods defined in LockingCapSupport interface. Take the implementation from BridgeSupport class, and move to this new class. Adapting implementation to stop using Optional and activation as an input at a Support level Getting back Optional since there's a case when we need to handle a null value Improving indentation Avoiding Null Pointer Exception - If it doesn't exist Locking Cap value, it must return false since RSKIP134 is not active. Assigning a value from an Optional to a new variable Rollback the changes on BridgeSupport --- .../rsk/peg/lockingcap/LockingCapSupport.java | 2 + .../peg/lockingcap/LockingCapSupportImpl.java | 87 +++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupportImpl.java diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java index 31d35e8ce4e..fb1d32c4448 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupport.java @@ -9,4 +9,6 @@ public interface LockingCapSupport { Optional getLockingCap(); boolean increaseLockingCap(Transaction tx, Coin newCap); + + void save(); } diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupportImpl.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupportImpl.java new file mode 100644 index 00000000000..18a1c16c186 --- /dev/null +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupportImpl.java @@ -0,0 +1,87 @@ +package co.rsk.peg.lockingcap; + +import co.rsk.bitcoinj.core.Coin; +import co.rsk.peg.lockingcap.constants.LockingCapConstants; +import co.rsk.peg.vote.AddressBasedAuthorizer; +import java.util.Optional; +import org.ethereum.config.blockchain.upgrades.ActivationConfig; +import org.ethereum.config.blockchain.upgrades.ActivationConfig.ForBlock; +import org.ethereum.config.blockchain.upgrades.ConsensusRule; +import org.ethereum.core.SignatureCache; +import org.ethereum.core.Transaction; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LockingCapSupportImpl implements LockingCapSupport { + + private static final Logger logger = LoggerFactory.getLogger(LockingCapSupportImpl.class); + private final LockingCapStorageProvider storageProvider; + private final ActivationConfig.ForBlock activations; + private final LockingCapConstants constants; + private final SignatureCache signatureCache; + + public LockingCapSupportImpl( + LockingCapStorageProvider storageProvider, + ForBlock activations, LockingCapConstants constants, + SignatureCache signatureCache + ) { + this.storageProvider = storageProvider; + this.activations = activations; + this.constants = constants; + this.signatureCache = signatureCache; + } + + @Override + public Optional getLockingCap() { + Optional lockingCap = storageProvider.getLockingCap(activations); + + // Before returning the locking cap, check if it was already set + if (!lockingCap.isPresent() && activations.isActive(ConsensusRule.RSKIP134)) { + // Set the initial Locking Cap value + logger.debug("[getLockingCap] {}", "Setting initial Locking Cap value"); + storageProvider.setLockingCap(constants.getInitialValue()); + } + return storageProvider.getLockingCap(activations); + } + + @Override + public boolean increaseLockingCap(Transaction tx, Coin newLockingCap) { + // Only pre-configured addresses can modify Locking Cap + AddressBasedAuthorizer authorizer = constants.getIncreaseAuthorizer(); + if (!authorizer.isAuthorized(tx, signatureCache)) { + logger.warn("[increaseLockingCap] {} {}", "Not authorized address tried to increase Locking Cap. Address: ", tx.getSender(signatureCache)); + return false; + } + + // New Locking Cap must be bigger than current Locking Cap + Optional currentLockingCap = getLockingCap(); + + if (!currentLockingCap.isPresent()) { + logger.warn("[increaseLockingCap] {}", "Current Locking Cap is not set since RSKIP134 is not active"); + return false; + } + + Coin lockingCap = currentLockingCap.get(); + + if (newLockingCap.compareTo(lockingCap) < 0) { + logger.warn("[increaseLockingCap] {} {}", "Attempted value doesn't increase Locking Cap. Value attempted: ", newLockingCap.value); + return false; + } + + Coin maxLockingCap = lockingCap.multiply(constants.getIncrementsMultiplier()); + if (newLockingCap.compareTo(maxLockingCap) > 0) { + logger.warn("[increaseLockingCap] {} {}", "Attempted value increases Locking Cap above its limit. Value attempted: ", newLockingCap.value); + return false; + } + + storageProvider.setLockingCap(newLockingCap); + logger.info("[increaseLockingCap] {} {}", "Increased locking cap: ", newLockingCap.value); + + return true; + } + + @Override + public void save() { + storageProvider.save(activations); + } +} From 04afe1063e1589ab3a72a64a38b8d2166fe1e25c Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Mon, 22 Jul 2024 16:07:38 -0400 Subject: [PATCH 13/40] Add LockingCapSupport Creation To BridgeSupportFactory Update BridgeSupportFactory to create an instance of LockingCapSupport and pass it to BridgeSupport constructor. Fix code smells --- .../java/co/rsk/peg/BridgeSupportFactory.java | 17 ++++++++++++++++- .../peg/lockingcap/LockingCapSupportImpl.java | 3 ++- .../rsk/peg/ReleaseTransactionBuilderTest.java | 2 +- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java index ab0d67c72a1..d6783f8e4ae 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupportFactory.java @@ -27,6 +27,8 @@ import co.rsk.peg.federation.constants.FederationConstants; import co.rsk.peg.feeperkb.*; import co.rsk.peg.feeperkb.constants.FeePerKbConstants; +import co.rsk.peg.lockingcap.*; +import co.rsk.peg.lockingcap.constants.LockingCapConstants; import co.rsk.peg.pegininstructions.PeginInstructionsProvider; import co.rsk.peg.storage.BridgeStorageAccessorImpl; import co.rsk.peg.storage.StorageAccessor; @@ -82,7 +84,12 @@ public BridgeSupport newInstance( FeePerKbSupport feePerKbSupport = getFeePerKbSupportInstance(bridgeStorageAccessor); WhitelistSupport whitelistSupport = getWhitelistSupportInstance(bridgeStorageAccessor, activations); - FederationSupport federationSupport = getFederationSupportInstance(bridgeStorageAccessor, executionBlock, activations); + FederationSupport federationSupport = getFederationSupportInstance( + bridgeStorageAccessor, + executionBlock, + activations + ); + LockingCapSupport lockingCapSupport = getLockingCapSupportInstance(bridgeStorageAccessor, activations); BridgeEventLogger eventLogger = null; if (logs != null) { @@ -108,6 +115,7 @@ public BridgeSupport newInstance( feePerKbSupport, whitelistSupport, federationSupport, + lockingCapSupport, btcBlockStoreFactory, activations, signatureCache @@ -138,4 +146,11 @@ private FederationSupport getFederationSupportInstance(StorageAccessor bridgeSto FederationStorageProvider federationStorageProvider = new FederationStorageProviderImpl(bridgeStorageAccessor); return new FederationSupportImpl(federationConstants, federationStorageProvider, rskExecutionBlock, activations); } + + private LockingCapSupport getLockingCapSupportInstance(StorageAccessor bridgeStorageAccessor, ActivationConfig.ForBlock activations) { + LockingCapConstants lockingCapConstants = bridgeConstants.getLockingCapConstants(); + LockingCapStorageProvider lockingCapStorageProvider = new LockingCapStorageProviderImpl(bridgeStorageAccessor); + + return new LockingCapSupportImpl(lockingCapStorageProvider, activations, lockingCapConstants, signatureCache); + } } diff --git a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupportImpl.java b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupportImpl.java index 18a1c16c186..4b13e96ffd4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupportImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/lockingcap/LockingCapSupportImpl.java @@ -22,7 +22,8 @@ public class LockingCapSupportImpl implements LockingCapSupport { public LockingCapSupportImpl( LockingCapStorageProvider storageProvider, - ForBlock activations, LockingCapConstants constants, + ActivationConfig.ForBlock activations, + LockingCapConstants constants, SignatureCache signatureCache ) { this.storageProvider = storageProvider; diff --git a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java index 9b162326b33..ed6d3d48489 100644 --- a/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/ReleaseTransactionBuilderTest.java @@ -144,7 +144,7 @@ void first_output_pay_fees() { assertEquals(standardMultisigFederation.getAddress(), changeOutput.getAddressFromP2SH(networkParameters)); // And if its value is the spent UTXOs summatory minus the requested pegout amount // we can ensure the Federation is not paying fees for pegouts - assertEquals(inputsValue.minus(pegoutAmount), changeOutput.getValue()); + Assertions.assertEquals(inputsValue.minus(pegoutAmount), changeOutput.getValue()); } @Test From 7b7001f3b0fe740daa17e3c9e3e21f134dedcc97 Mon Sep 17 00:00:00 2001 From: Wilmer Rondon Date: Wed, 17 Jul 2024 23:17:27 -0400 Subject: [PATCH 14/40] Adapt BridgeSupport Methods for LockingCap Refactor MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After LockingCapSupport interface has been created, we’re going to use it on BridgeSupport. Adapt LockingCap methods in BridgeSupport.Use new interface created, LockingCapSupport, under co.rsk.peg.lockingcap package to create LockingCap behavior. Rebase Code Smell Removing Optional from getLockingCap() Method at a LockingCapSupport Level --- .../main/java/co/rsk/peg/BridgeSupport.java | 36 +++---------------- .../peg/ReleaseTransactionBuilderTest.java | 2 +- 2 files changed, 5 insertions(+), 33 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 202241fb0b7..796b3073f31 100644 --- a/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java +++ b/rskj-core/src/main/java/co/rsk/peg/BridgeSupport.java @@ -182,7 +182,7 @@ public void save() throws IOException { feePerKbSupport.save(); whitelistSupport.save(); federationSupport.save(); - // TODO: save lockingCapSupport.save(); + lockingCapSupport.save(activations); } /** @@ -2108,14 +2108,7 @@ public Integer setLockWhitelistDisableBlockDelay(Transaction tx, BigInteger disa } public Coin getLockingCap() { - // Before returning the locking cap, check if it was already set - if (activations.isActive(ConsensusRule.RSKIP134) && this.provider.getLockingCap() == null) { - // Set the initial locking cap value - logger.debug("Setting initial locking cap value"); - this.provider.setLockingCap(bridgeConstants.getInitialLockingCap()); - } - - return this.provider.getLockingCap(); + return lockingCapSupport.getLockingCap(); } /** @@ -2127,29 +2120,8 @@ public Optional