From 7a3d37ff10675c4121814114de429f62be700706 Mon Sep 17 00:00:00 2001 From: julia-zack Date: Thu, 18 Jul 2024 11:19:22 -0300 Subject: [PATCH 001/223] Add rskip419 config to lovell Reorder rskip --- .../blockchain/upgrades/ConsensusRule.java | 1 + rskj-core/src/main/resources/expected.conf | 168 +++++++++--------- rskj-core/src/main/resources/reference.conf | 1 + .../upgrades/ActivationConfigTest.java | 1 + .../upgrades/ActivationConfigsForTest.java | 1 + 5 files changed, 88 insertions(+), 84 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 b2a6ce9b0b..5a14eaa3d0 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,6 +95,7 @@ public enum ConsensusRule { RSKIP412("rskip412"), // From EIP-3198 BASEFEE opcode RSKIP415("rskip415"), RSKIP417("rskip417"), + RSKIP419("rskip419"), RSKIP427("rskip427"), RSKIP428("rskip428"), RSKIP434("rskip434"), diff --git a/rskj-core/src/main/resources/expected.conf b/rskj-core/src/main/resources/expected.conf index 21d2159e71..8406ca5c80 100644 --- a/rskj-core/src/main/resources/expected.conf +++ b/rskj-core/src/main/resources/expected.conf @@ -20,90 +20,90 @@ blockchain = { lovell700 = } consensusRules = { - areBridgeTxsPaid = - rskip85 = - rskip87 = - rskip88 = - rskip89 = - rskip90 = - rskip91 = - rskip92 = - rskip97 = - rskip98 = - rskip103 = - rskip106 = - rskip110 = - rskip119 = - rskip120 = - rskip122 = - rskip123 = - rskip124 = - rskip125 = - rskip126 = - rskip132 = - rskip134 = - rskip136 = - rskip137 = - rskip140 = - rskip143 = - rskip146 = - rskip150 = - rskip151 = - rskip152 = - rskip156 = - rskipUMM = - rskip153 = - rskip169 = - rskip170 = - rskip171 = - rskip174 = - rskip176 = - rskip179 = - rskip180 = - rskip181 = - rskip185 = - rskip186 = - rskip191 = - rskip197 = - rskip199 = - rskip200 = - rskip201 = - rskip203 = - rskip218 = - rskip219 = - rskip220 = - rskip252 = - rskip271 = - rskip284 = - rskip290 = - rskip293 = - rskip294 = - rskip297 = - rskip351 = - rskip144 = - rskip326 = - rskip353 = - rskip357 = - rskip374 = - rskip375 = - rskip376 = - rskip377 = - rskip379 = - rskip383 = - rskip385 = - rskip398 = - rskip400 = - rskip412 = - rskip415 = - rskip417 = - rskip427 = - rskip428 = - rskip434 = - rskip438 = - rskip445 = - rskip446 = - rskip453 = - rskip454 = + areBridgeTxsPaid = + rskip85 = + rskip87 = + rskip88 = + rskip89 = + rskip90 = + rskip91 = + rskip92 = + rskip97 = + rskip98 = + rskip103 = + rskip106 = + rskip110 = + rskip119 = + rskip120 = + rskip122 = + rskip123 = + rskip124 = + rskip125 = + rskip126 = + rskip132 = + rskip134 = + rskip136 = + rskip137 = + rskip140 = + rskip143 = + rskip146 = + rskip150 = + rskip151 = + rskip152 = + rskip156 = + rskipUMM = + rskip153 = + rskip169 = + rskip170 = + rskip171 = + rskip174 = + rskip176 = + rskip179 = + rskip180 = + rskip181 = + rskip185 = + rskip186 = + rskip191 = + rskip197 = + rskip199 = + rskip200 = + rskip201 = + rskip203 = + rskip218 = + rskip219 = + rskip220 = + rskip252 = + rskip271 = + rskip284 = + rskip290 = + rskip293 = + rskip294 = + rskip297 = + rskip351 = + rskip144 = + rskip326 = + rskip353 = + rskip357 = + rskip374 = + rskip375 = + rskip376 = + rskip377 = + rskip379 = + rskip383 = + rskip385 = + rskip398 = + rskip400 = + rskip412 = + rskip415 = + rskip417 = + rskip427 = + rskip428 = + rskip434 = + rskip438 = + rskip445 = + rskip446 = + rskip453 = + rskip454 = } } gc = { diff --git a/rskj-core/src/main/resources/reference.conf b/rskj-core/src/main/resources/reference.conf index d35f0988b7..511d906be9 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 + rskip419 = lovell700 rskip427 = lovell700 rskip428 = lovell700 rskip434 = arrowhead631 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 b90d7f849e..ecdd42f150 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 @@ -122,6 +122,7 @@ class ActivationConfigTest { " rskip412: arrowhead600", " rskip415: arrowhead600", " rskip417: arrowhead600", + " rskip419: lovell700", " rskip427: lovell700", " rskip428: lovell700", " rskip434: arrowhead631", 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 ac85887cfb..e0dc663f34 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 @@ -176,6 +176,7 @@ private static List getArrowhead631Rskips() { private static List getLovell700Rskips() { return new ArrayList<>(Arrays.asList( + ConsensusRule.RSKIP419, ConsensusRule.RSKIP427, ConsensusRule.RSKIP428, ConsensusRule.RSKIP438, From fdcbff100441bc9b0da7885b2b50b4c02686b6e1 Mon Sep 17 00:00:00 2001 From: julia-zack Date: Thu, 18 Jul 2024 15:11:03 -0300 Subject: [PATCH 002/223] Add validation period duration to federation constants Add tests Refactor Rename variable --- .../federation/constants/FederationConstants.java | 3 +++ .../constants/FederationMainNetConstants.java | 2 ++ .../constants/FederationRegTestConstants.java | 2 ++ .../constants/FederationTestNetConstants.java | 2 ++ .../constants/FederationConstantsTest.java | 14 ++++++++++++++ 5 files changed, 23 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationConstants.java b/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationConstants.java index f74f8fa2be..92d739c7dc 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationConstants.java @@ -18,6 +18,7 @@ public class FederationConstants { protected AddressBasedAuthorizer federationChangeAuthorizer; protected String oldFederationAddress; + protected long validationPeriodDurationInBlocks; protected long federationActivationAge; protected long federationActivationAgeLegacy; protected long fundsMigrationAgeSinceActivationBegin; @@ -37,6 +38,8 @@ public Instant getGenesisFederationCreationTime() { return genesisFederationCreationTime; } + public long getValidationPeriodDurationInBlocks() { return validationPeriodDurationInBlocks; } + public long getFederationActivationAge(ActivationConfig.ForBlock activations) { return activations.isActive(ConsensusRule.RSKIP383) ? federationActivationAge : federationActivationAgeLegacy; } diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationMainNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationMainNetConstants.java index 670d7c7a26..4b4431de8a 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationMainNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationMainNetConstants.java @@ -45,6 +45,8 @@ private FederationMainNetConstants() { ).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList())); federationChangeAuthorizer = new AddressBasedAuthorizer(federationChangeAuthorizedKeys, AddressBasedAuthorizer.MinimumRequiredCalculation.MAJORITY); + validationPeriodDurationInBlocks = 16000L; + federationActivationAgeLegacy = 18500L; federationActivationAge = 40320L; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationRegTestConstants.java b/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationRegTestConstants.java index 5c51a43cb7..8e21b4fb28 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationRegTestConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationRegTestConstants.java @@ -31,6 +31,8 @@ public FederationRegTestConstants(List federationPublicKeys) { ).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList())); federationChangeAuthorizer = new AddressBasedAuthorizer(federationChangeAuthorizedKeys, AddressBasedAuthorizer.MinimumRequiredCalculation.MAJORITY); + validationPeriodDurationInBlocks = 15L; + federationActivationAgeLegacy = 10L; federationActivationAge = 20L; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationTestNetConstants.java b/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationTestNetConstants.java index be84987b15..35e711755b 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationTestNetConstants.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/constants/FederationTestNetConstants.java @@ -35,6 +35,8 @@ private FederationTestNetConstants() { ).map(hex -> ECKey.fromPublicOnly(Hex.decode(hex))).collect(Collectors.toList())); federationChangeAuthorizer = new AddressBasedAuthorizer(federationChangeAuthorizedKeys, AddressBasedAuthorizer.MinimumRequiredCalculation.MAJORITY); + validationPeriodDurationInBlocks = 80L; + federationActivationAgeLegacy = 60L; federationActivationAge = 120L; diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/constants/FederationConstantsTest.java b/rskj-core/src/test/java/co/rsk/peg/federation/constants/FederationConstantsTest.java index 8082d74145..aee593e858 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/constants/FederationConstantsTest.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/constants/FederationConstantsTest.java @@ -106,6 +106,20 @@ private static Stream genesisFedCreationTimeArgs() { ); } + @ParameterizedTest + @MethodSource("validationPeriodDurationArgs") + void getValidationPeriodDuration(FederationConstants constants, long expectedDuration) { + assertEquals(expectedDuration, constants.getValidationPeriodDurationInBlocks()); + } + + private static Stream validationPeriodDurationArgs() { + return Stream.of( + Arguments.of(mainnet, 16000L), + Arguments.of(testnet, 80L), + Arguments.of(regtest, 15L) + ); + } + @ParameterizedTest @MethodSource("fedActivationAgeAndActivationArgs") void getFederationActivationAge(FederationConstants constants, ActivationConfig.ForBlock activations, long expectedActivationAge) { From c8c397468406dd54a5c86d427d1bd4c7a36be0c4 Mon Sep 17 00:00:00 2001 From: julia-zack Date: Thu, 18 Jul 2024 15:25:38 -0300 Subject: [PATCH 003/223] Add proposedFederation and validationFundTxHashUnsigned Change name --- .../co/rsk/peg/federation/FederationStorageProviderImpl.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java index a4c4405883..051f195805 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java @@ -1,6 +1,7 @@ package co.rsk.peg.federation; import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.bitcoinj.core.Sha256Hash; import co.rsk.bitcoinj.core.UTXO; import co.rsk.bitcoinj.script.Script; import co.rsk.peg.BridgeSerializationUtils; @@ -30,6 +31,7 @@ public class FederationStorageProviderImpl implements FederationStorageProvider private Federation oldFederation; private boolean shouldSaveOldFederation = false; + private Federation proposedFederation; private PendingFederation pendingFederation; private boolean shouldSavePendingFederation = false; @@ -39,6 +41,7 @@ public class FederationStorageProviderImpl implements FederationStorageProvider private Long nextFederationCreationBlockHeight; // if -1, then clear value private Script lastRetiredFederationP2SHScript; + private Sha256Hash svpFundTxHashUnsigned; public FederationStorageProviderImpl(StorageAccessor bridgeStorageAccessor) { this.bridgeStorageAccessor = bridgeStorageAccessor; From 02c7a9ed8462c858da312bfb7b959e37fa50ed72 Mon Sep 17 00:00:00 2001 From: julia-zack Date: Thu, 18 Jul 2024 15:54:26 -0300 Subject: [PATCH 004/223] Add keys to storage index Add key to storage index Remove declaration of svp fund tx hash since it is not being used yet. Remove _KEY suffix --- .../java/co/rsk/peg/federation/FederationStorageIndexKey.java | 4 +++- .../co/rsk/peg/federation/FederationStorageProviderImpl.java | 2 -- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageIndexKey.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageIndexKey.java index a947e90e50..9e8a5853b6 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageIndexKey.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageIndexKey.java @@ -12,6 +12,7 @@ public enum FederationStorageIndexKey { NEW_FEDERATION_KEY("newFederation"), OLD_FEDERATION_KEY("oldFederation"), PENDING_FEDERATION_KEY("pendingFederation"), + PROPOSED_FEDERATION("proposedFederation"), FEDERATION_ELECTION_KEY("federationElection"), @@ -23,7 +24,8 @@ public enum FederationStorageIndexKey { // Format version keys NEW_FEDERATION_FORMAT_VERSION("newFederationFormatVersion"), OLD_FEDERATION_FORMAT_VERSION("oldFederationFormatVersion"), - PENDING_FEDERATION_FORMAT_VERSION("pendingFederationFormatVersion") + PENDING_FEDERATION_FORMAT_VERSION("pendingFederationFormatVersion"), + PROPOSED_FEDERATION_FORMAT_VERSION("proposedFederationFormatVersion") ; private final String key; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java index 051f195805..80e575cb65 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java @@ -1,7 +1,6 @@ package co.rsk.peg.federation; import co.rsk.bitcoinj.core.NetworkParameters; -import co.rsk.bitcoinj.core.Sha256Hash; import co.rsk.bitcoinj.core.UTXO; import co.rsk.bitcoinj.script.Script; import co.rsk.peg.BridgeSerializationUtils; @@ -41,7 +40,6 @@ public class FederationStorageProviderImpl implements FederationStorageProvider private Long nextFederationCreationBlockHeight; // if -1, then clear value private Script lastRetiredFederationP2SHScript; - private Sha256Hash svpFundTxHashUnsigned; public FederationStorageProviderImpl(StorageAccessor bridgeStorageAccessor) { this.bridgeStorageAccessor = bridgeStorageAccessor; From 321077aff75c961fa7386852ef4ff2b6feb10f2f Mon Sep 17 00:00:00 2001 From: julia-zack Date: Thu, 18 Jul 2024 16:19:35 -0300 Subject: [PATCH 005/223] Add set and save methods for the proposed federation Remove _KEY suffix. Save proposed federation the same way as pending one --- .../rsk/peg/federation/FederationStorageProvider.java | 2 ++ .../peg/federation/FederationStorageProviderImpl.java | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java index 35aba04ee7..d7d4ac1e3f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java @@ -25,6 +25,8 @@ public interface FederationStorageProvider { PendingFederation getPendingFederation(); void setPendingFederation(PendingFederation federation); + void setProposedFederation(Federation proposedFederation); + ABICallElection getFederationElection(AddressBasedAuthorizer authorizer); Optional getActiveFederationCreationBlockHeight(ActivationConfig.ForBlock activations); diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java index 80e575cb65..c5eb53bc6f 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java @@ -207,6 +207,11 @@ public void setPendingFederation(PendingFederation federation) { pendingFederation = federation; } + @Override + public void setProposedFederation(Federation proposedFederation) { + this.proposedFederation = proposedFederation; + } + @Override public ABICallElection getFederationElection(AddressBasedAuthorizer authorizer) { if (federationElection != null) { @@ -368,6 +373,12 @@ private void savePendingFederation(ActivationConfig.ForBlock activations) { bridgeStorageAccessor.saveToRepository(PENDING_FEDERATION_KEY.getKey(), serializedPendingFederation); } + private void saveProposedFederation(Federation proposedFederation) { + // we only need to save the standard part of the fed since the emergency part is constant + saveFederationFormatVersion(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), STANDARD_MULTISIG_FEDERATION.getFormatVersion()); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), proposedFederation, BridgeSerializationUtils::serializeFederation); + } + @Nullable private byte[] serializePendingFederation(ActivationConfig.ForBlock activations) { if (pendingFederation == null) { From 1f49b15014001b5c9694bb84e1f232fe70cda185 Mon Sep 17 00:00:00 2001 From: julia-zack Date: Mon, 22 Jul 2024 11:47:42 -0300 Subject: [PATCH 006/223] Save proposed federation with its own format version Add proposedFederationIsSet logic Getting rid of proposedFederationIsSet logic. Add isProposedFederationSet logic. Add rskip419 check in saveProposedFederation method Save null version when proposed federation is null Remove unnecessary private method Refactor Removes null activations from tests --- .../federation/FederationStorageProviderImpl.java | 15 +++++++++++---- .../FederationStorageProviderImplTests.java | 8 ++++---- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java index c5eb53bc6f..d3d03f70cb 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java @@ -30,10 +30,12 @@ public class FederationStorageProviderImpl implements FederationStorageProvider private Federation oldFederation; private boolean shouldSaveOldFederation = false; - private Federation proposedFederation; private PendingFederation pendingFederation; private boolean shouldSavePendingFederation = false; + private Federation proposedFederation; + private boolean isProposedFederationSet = false; + private ABICallElection federationElection; private Long activeFederationCreationBlockHeight; @@ -210,6 +212,7 @@ public void setPendingFederation(PendingFederation federation) { @Override public void setProposedFederation(Federation proposedFederation) { this.proposedFederation = proposedFederation; + isProposedFederationSet = true; } @Override @@ -373,9 +376,13 @@ private void savePendingFederation(ActivationConfig.ForBlock activations) { bridgeStorageAccessor.saveToRepository(PENDING_FEDERATION_KEY.getKey(), serializedPendingFederation); } - private void saveProposedFederation(Federation proposedFederation) { - // we only need to save the standard part of the fed since the emergency part is constant - saveFederationFormatVersion(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), STANDARD_MULTISIG_FEDERATION.getFormatVersion()); + private void saveProposedFederation(ActivationConfig.ForBlock activations) { + if (!activations.isActive(RSKIP419) || !isProposedFederationSet) { + return; + } + + Integer formatVersion = Optional.of(proposedFederation.getFormatVersion()).orElse(null); + saveFederationFormatVersion(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), formatVersion); bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), proposedFederation, BridgeSerializationUtils::serializeFederation); } diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java index e1f67898e7..630eb6b3d0 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java @@ -410,12 +410,12 @@ private static Stream provideFederationBtcUTXOsTestArguments() { return Stream.of( Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, testnetNetworkParams, activationsWithRskip284Inactive), - Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, mainnetNetworkParams, null), + Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, mainnetNetworkParams, activationsWithRskip284Inactive), Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY_FOR_TESTNET_PRE_HOP, testnetNetworkParams, activationsWithRskip284ActiveAnd293Inactive), - Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, mainnetNetworkParams, null), - Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, mainnetNetworkParams, null), + Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, mainnetNetworkParams, activationsWithRskip284ActiveAnd293Inactive), + Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, mainnetNetworkParams, activationsWithRskip284ActiveAnd293Inactive), Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY_FOR_TESTNET_POST_HOP, testnetNetworkParams, activationsWithRskip284And293Active), - Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, mainnetNetworkParams, null) + Arguments.of(NEW_FEDERATION_BTC_UTXOS_KEY, mainnetNetworkParams, activationsWithRskip284And293Active) ); } From d3c5b6a7f7e220dd6c304f083416cbbcd774b2d6 Mon Sep 17 00:00:00 2001 From: julia-zack Date: Wed, 31 Jul 2024 12:30:09 -0300 Subject: [PATCH 007/223] Add tests for saveProposedFederation method Make variable final Improve test name Use all activations instead of lovell Improve null handling --- .../FederationStorageProviderImpl.java | 8 +- .../FederationStorageProviderImplTests.java | 78 ++++++++++++++++++- 2 files changed, 80 insertions(+), 6 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java index d3d03f70cb..8da84cd0a4 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java @@ -296,6 +296,7 @@ public void save(NetworkParameters networkParameters, ActivationConfig.ForBlock saveOldFederation(activations); savePendingFederation(activations); + saveProposedFederation(activations); saveFederationElection(); @@ -381,7 +382,10 @@ private void saveProposedFederation(ActivationConfig.ForBlock activations) { return; } - Integer formatVersion = Optional.of(proposedFederation.getFormatVersion()).orElse(null); + Integer formatVersion = Optional.ofNullable(proposedFederation) + .map(Federation::getFormatVersion) + .orElse(null); + saveFederationFormatVersion(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), formatVersion); bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), proposedFederation, BridgeSerializationUtils::serializeFederation); } @@ -397,7 +401,7 @@ private byte[] serializePendingFederation(ActivationConfig.ForBlock activations) private void saveFederationFormatVersion(DataWord versionKey, Integer version) { bridgeStorageAccessor.saveToRepository(versionKey, version, BridgeSerializationUtils::serializeInteger); - storageVersionEntries.put(versionKey, Optional.of(version)); + storageVersionEntries.put(versionKey, Optional.ofNullable(version)); } private void saveFederationElection() { diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java index 630eb6b3d0..948fd345f8 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java @@ -18,9 +18,13 @@ import co.rsk.peg.BridgeSerializationUtils; import co.rsk.peg.PegTestUtils; import co.rsk.peg.bitcoin.BitcoinTestUtils; -import co.rsk.peg.constants.*; +import co.rsk.peg.constants.BridgeConstants; +import co.rsk.peg.constants.BridgeMainNetConstants; +import co.rsk.peg.constants.BridgeRegTestConstants; import co.rsk.peg.federation.constants.FederationConstants; -import co.rsk.peg.storage.*; +import co.rsk.peg.storage.BridgeStorageAccessorImpl; +import co.rsk.peg.storage.InMemoryStorage; +import co.rsk.peg.storage.StorageAccessor; import co.rsk.peg.vote.ABICallElection; import co.rsk.peg.vote.ABICallSpec; import co.rsk.peg.vote.AddressBasedAuthorizer; @@ -35,8 +39,7 @@ import org.ethereum.util.RLP; import org.ethereum.vm.DataWord; import org.ethereum.vm.PrecompiledContracts; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.*; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -908,6 +911,73 @@ void saveFederationElection_shouldSaveInStorage() { assertArrayEquals(federationElectionSerializedWithVote, actualAbiCallElectionSerialized); } + @Nested + @Tag("proposed federation tests") + @TestInstance(TestInstance.Lifecycle.PER_CLASS) + class ProposedFederationTests { + private final ActivationConfig.ForBlock preLovellActivations = ActivationConfigsForTest.arrowhead631().forBlock(0L); + private final ActivationConfig.ForBlock allActivations = ActivationConfigsForTest.all().forBlock(0L); + private final Federation proposedFederation = new P2shErpFederationBuilder().build(); + private StorageAccessor bridgeStorageAccessor; + private FederationStorageProvider federationStorageProvider; + + @BeforeEach + void setUp() { + bridgeStorageAccessor = new InMemoryStorage(); + federationStorageProvider = new FederationStorageProviderImpl(bridgeStorageAccessor); + } + + @Test + void saveProposedFederation_whenProposedFederationIsNotSet_shouldNotSave() { + federationStorageProvider.save(networkParameters, allActivations); + + assertNull(getProposedFederationFromRepository()); + } + + @Test + void saveProposedFederation_preRSKIP419_whenProposedFederationIsSet_shouldNotSave() { + federationStorageProvider.setProposedFederation(proposedFederation); + federationStorageProvider.save(networkParameters, preLovellActivations); + + assertNull(getProposedFederationFromRepository()); + } + + @Test + void saveProposedFederation_whenProposedFederationIsSet_shouldSave() { + federationStorageProvider.setProposedFederation(proposedFederation); + federationStorageProvider.save(networkParameters, allActivations); + + assertEquals(proposedFederation, getProposedFederationFromRepository()); + } + + @Test + void saveProposedFederation_whenProposedFederationIsSetToNull_shouldSave() { + // first save a non-null value to make sure saving a null one is actually happening + federationStorageProvider.setProposedFederation(proposedFederation); + federationStorageProvider.save(networkParameters, allActivations); + + federationStorageProvider.setProposedFederation(null); + federationStorageProvider.save(networkParameters, allActivations); + + assertNull(getProposedFederationFromRepository()); + } + + private Federation getProposedFederationFromRepository() { + return bridgeStorageAccessor.getFromRepository( + PROPOSED_FEDERATION.getKey(), + data -> { + if (data == null) { + return null; + } + + // storage version should be always present for non-null proposed federation + Integer storageVersion = bridgeStorageAccessor.getFromRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), BridgeSerializationUtils::deserializeInteger); + return BridgeSerializationUtils.deserializeFederationAccordingToVersion(data, storageVersion, federationConstants, allActivations); + } + ); + } + } + private static Federation createNonStandardErpFederation() { List members = FederationMember.getFederationMembersFromKeys( PegTestUtils.createRandomBtcECKeys(7) From 3e43647ff67cdf7925680c19dca2db063bcaff06 Mon Sep 17 00:00:00 2001 From: julia-zack Date: Wed, 31 Jul 2024 15:23:36 -0300 Subject: [PATCH 008/223] Add format version assertion to tests --- .../FederationStorageProviderImpl.java | 1 + .../FederationStorageProviderImplTests.java | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java index 8da84cd0a4..72a9d710cb 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java @@ -382,6 +382,7 @@ private void saveProposedFederation(ActivationConfig.ForBlock activations) { return; } + // format version is always non-null in a non-null federation Integer formatVersion = Optional.ofNullable(proposedFederation) .map(Federation::getFormatVersion) .orElse(null); diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java index 948fd345f8..8f5e32c41c 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java @@ -932,6 +932,7 @@ void saveProposedFederation_whenProposedFederationIsNotSet_shouldNotSave() { federationStorageProvider.save(networkParameters, allActivations); assertNull(getProposedFederationFromRepository()); + assertNull(getProposedFederationFormatVersionFromRepository()); } @Test @@ -940,6 +941,7 @@ void saveProposedFederation_preRSKIP419_whenProposedFederationIsSet_shouldNotSav federationStorageProvider.save(networkParameters, preLovellActivations); assertNull(getProposedFederationFromRepository()); + assertNull(getProposedFederationFormatVersionFromRepository()); } @Test @@ -948,6 +950,7 @@ void saveProposedFederation_whenProposedFederationIsSet_shouldSave() { federationStorageProvider.save(networkParameters, allActivations); assertEquals(proposedFederation, getProposedFederationFromRepository()); + assertEquals(proposedFederation.getFormatVersion(), getProposedFederationFormatVersionFromRepository()); } @Test @@ -960,6 +963,7 @@ void saveProposedFederation_whenProposedFederationIsSetToNull_shouldSave() { federationStorageProvider.save(networkParameters, allActivations); assertNull(getProposedFederationFromRepository()); + assertNull(getProposedFederationFormatVersionFromRepository()); } private Federation getProposedFederationFromRepository() { @@ -970,12 +974,18 @@ private Federation getProposedFederationFromRepository() { return null; } - // storage version should be always present for non-null proposed federation - Integer storageVersion = bridgeStorageAccessor.getFromRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), BridgeSerializationUtils::deserializeInteger); - return BridgeSerializationUtils.deserializeFederationAccordingToVersion(data, storageVersion, federationConstants, allActivations); + return BridgeSerializationUtils.deserializeFederationAccordingToVersion(data, getProposedFederationFormatVersionFromRepository(), federationConstants, allActivations); } ); } + + private Integer getProposedFederationFormatVersionFromRepository() { + byte[] versionSerialized = bridgeStorageAccessor.getFromRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), data -> data); + + return Optional.ofNullable(versionSerialized) + .map(BridgeSerializationUtils::deserializeInteger) + .orElse(null); + } } private static Federation createNonStandardErpFederation() { From baaba6fb2e365223129a977b1170f99761f0684e Mon Sep 17 00:00:00 2001 From: julia-zack Date: Wed, 31 Jul 2024 10:04:38 -0300 Subject: [PATCH 009/223] Add getProposedFederation method Add get proposed federation tests Minor fix after rebase Improve comment Minor refactor Minor refactor Improve comment Add test case Throw exception when there is no storage version for non-null proposed federation Add test cases Add log. Add test case and refactor Remove unused import --- .../federation/FederationStorageProvider.java | 2 + .../FederationStorageProviderImpl.java | 38 +++++++ .../FederationStorageProviderImplTests.java | 104 ++++++++++++++++++ 3 files changed, 144 insertions(+) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java index d7d4ac1e3f..cd57967f44 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java @@ -27,6 +27,8 @@ public interface FederationStorageProvider { void setProposedFederation(Federation proposedFederation); + Optional getProposedFederation(FederationConstants federationConstants, ActivationConfig.ForBlock activations); + ABICallElection getFederationElection(AddressBasedAuthorizer authorizer); Optional getActiveFederationCreationBlockHeight(ActivationConfig.ForBlock activations); diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java index 72a9d710cb..f7190ebf06 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProviderImpl.java @@ -10,6 +10,8 @@ import co.rsk.peg.vote.AddressBasedAuthorizer; import org.ethereum.config.blockchain.upgrades.ActivationConfig; import org.ethereum.vm.DataWord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import javax.annotation.Nullable; import java.util.HashMap; @@ -21,6 +23,7 @@ import static org.ethereum.config.blockchain.upgrades.ConsensusRule.*; public class FederationStorageProviderImpl implements FederationStorageProvider { + private static final Logger logger = LoggerFactory.getLogger(FederationStorageProviderImpl.class); private final StorageAccessor bridgeStorageAccessor; private final HashMap> storageVersionEntries; @@ -215,6 +218,41 @@ public void setProposedFederation(Federation proposedFederation) { isProposedFederationSet = true; } + @Override + public Optional getProposedFederation(FederationConstants federationConstants, ActivationConfig.ForBlock activations) { + if (!activations.isActive(RSKIP419)) { + return Optional.empty(); + } + + if (proposedFederation != null) { + return Optional.of(proposedFederation); + } + + // reaching this point means the proposed federation was set to null + if (isProposedFederationSet) { + return Optional.empty(); + } + + proposedFederation = bridgeStorageAccessor.getFromRepository( + PROPOSED_FEDERATION.getKey(), + data -> { + if (data == null) { + return null; + } + + Optional storageVersion = getStorageVersion(PROPOSED_FEDERATION_FORMAT_VERSION.getKey()); + if (!storageVersion.isPresent()) { + String message = "Storage version should be present for non-null proposed federation"; + logger.warn("[getProposedFederation] {}", message); + throw new IllegalStateException(message); + } + return BridgeSerializationUtils.deserializeFederationAccordingToVersion(data, storageVersion.get(), federationConstants, activations); + } + ); + + return Optional.ofNullable(proposedFederation); + } + @Override public ABICallElection getFederationElection(AddressBasedAuthorizer authorizer) { if (federationElection != null) { diff --git a/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java b/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java index 8f5e32c41c..8c18fc5b36 100644 --- a/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java +++ b/rskj-core/src/test/java/co/rsk/peg/federation/FederationStorageProviderImplTests.java @@ -986,6 +986,110 @@ private Integer getProposedFederationFormatVersionFromRepository() { .map(BridgeSerializationUtils::deserializeInteger) .orElse(null); } + + @Test + void getProposedFederation_whenThereIsNoProposedFederationSavedNorSet_shouldReturnEmpty() { + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, allActivations); + assertFalse(actualProposedFederation.isPresent()); + } + + @Test + void getProposedFederation_preRSKIP419_whenProposedFederationIsSet_shouldReturnEmpty() { + federationStorageProvider.setProposedFederation(proposedFederation); + + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, preLovellActivations); + assertFalse(actualProposedFederation.isPresent()); + } + + @Test + void getProposedFederation_whenProposedFederationIsSet_shouldReturnFederationSet() { + federationStorageProvider.setProposedFederation(proposedFederation); + + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, allActivations); + assertEquals(Optional.of(proposedFederation), actualProposedFederation); + } + + @Test + void getProposedFederation_whenProposedFederationIsSetToNull_shouldReturnEmpty() { + federationStorageProvider.setProposedFederation(null); + + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, allActivations); + assertFalse(actualProposedFederation.isPresent()); + } + + @Test + void getProposedFederation_whenStorageIsNotEmptyAndProposedFederationIsSet_shouldReturnFederationSet() { + // first we have to save the another proposed fed so the repo is not empty + Federation savedFederation = FederationTestUtils.getErpFederation(federationConstants.getBtcParams()); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), savedFederation.getFormatVersion(), BridgeSerializationUtils::serializeInteger); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), savedFederation, BridgeSerializationUtils::serializeFederation); + + federationStorageProvider.setProposedFederation(proposedFederation); + + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, allActivations); + assertEquals(Optional.of(proposedFederation), actualProposedFederation); + } + + @Test + void getProposedFederation_whenStorageIsNotEmptyAndProposedFederationIsSetToNull_shouldReturnEmpty() { + // first we have to save the another proposed fed so the repo is not empty + Federation savedFederation = FederationTestUtils.getErpFederation(federationConstants.getBtcParams()); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), savedFederation.getFormatVersion(), BridgeSerializationUtils::serializeInteger); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), savedFederation, BridgeSerializationUtils::serializeFederation); + + federationStorageProvider.setProposedFederation(null); + + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, allActivations); + assertFalse(actualProposedFederation.isPresent()); + } + + @Test + void getProposedFederation_whenProposedFederationIsSaved_shouldReturnSavedFederation() { + // first we have to save the proposed fed so the repo is not empty + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), proposedFederation.getFormatVersion(), BridgeSerializationUtils::serializeInteger); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), proposedFederation, BridgeSerializationUtils::serializeFederation); + + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, allActivations); + assertEquals(Optional.of(proposedFederation), actualProposedFederation); + } + + @Test + void getProposedFederation_whenNullProposedFederationIsSaved_shouldReturnEmpty() { + // first save a non-null value to make sure saving a null one is actually happening + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), proposedFederation.getFormatVersion(), BridgeSerializationUtils::serializeInteger); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), proposedFederation, BridgeSerializationUtils::serializeFederation); + + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), null, BridgeSerializationUtils::serializeInteger); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), null, BridgeSerializationUtils::serializeFederation); + + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, allActivations); + assertFalse(actualProposedFederation.isPresent()); + } + + @Test + void getProposedFederation_whenProposedFederationIsSavedWithoutStorageVersion_shouldThrowIllegalStateException() { + // save a proposed federation without storage version + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), proposedFederation, BridgeSerializationUtils::serializeFederation); + + assertThrows(IllegalStateException.class, () -> federationStorageProvider.getProposedFederation(federationConstants, allActivations)); + } + + @Test + void getProposedFederation_whenProposedFederationIsCached_shouldReturnCachedFederation() { + // first we have to save the proposed fed so the repo is not empty + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), proposedFederation.getFormatVersion(), BridgeSerializationUtils::serializeInteger); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), proposedFederation, BridgeSerializationUtils::serializeFederation); + // this should set the proposed fed in proposedFederation field + federationStorageProvider.getProposedFederation(federationConstants, allActivations); + + // saving in the repo another fed to make sure the cached value is the one being returned + Federation anotherFederation = FederationTestUtils.getErpFederation(federationConstants.getBtcParams());; + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION_FORMAT_VERSION.getKey(), anotherFederation.getFormatVersion(), BridgeSerializationUtils::serializeInteger); + bridgeStorageAccessor.saveToRepository(PROPOSED_FEDERATION.getKey(), anotherFederation, BridgeSerializationUtils::serializeFederation); + + Optional actualProposedFederation = federationStorageProvider.getProposedFederation(federationConstants, allActivations); + assertEquals(Optional.of(proposedFederation), actualProposedFederation); + } } private static Federation createNonStandardErpFederation() { From ffacf62027c5e6f95b293c139486e6ccc9d97e4e Mon Sep 17 00:00:00 2001 From: jeremy-then Date: Mon, 29 Jul 2024 00:59:11 -0400 Subject: [PATCH 010/223] Adds setFundTransactionUnsignedHash and saveFundTransactionUnsignedHash methods and tests Rebases Reorders and renames tests Rebases Appends SVP prefix to FUND_TX_HASH_UNSIGNED and refactors tests Rebases Moves repeated arrange code to setup. Using Optional. Rebases Removes _ from the key Using arrowhead631 Rebases Rebases Renames saveFundTransactionUnsignedHash to saveSvpFundTransactionUnsignedHash Renames FundTransactionUnsignedHash instance fields --- .../federation/FederationStorageIndexKey.java | 3 +- .../federation/FederationStorageProvider.java | 4 + .../FederationStorageProviderImpl.java | 26 ++++++ .../FederationStorageProviderImplTests.java | 88 ++++++++++++++++++- 4 files changed, 119 insertions(+), 2 deletions(-) diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageIndexKey.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageIndexKey.java index 9e8a5853b6..a7b907ad42 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageIndexKey.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageIndexKey.java @@ -25,7 +25,8 @@ public enum FederationStorageIndexKey { NEW_FEDERATION_FORMAT_VERSION("newFederationFormatVersion"), OLD_FEDERATION_FORMAT_VERSION("oldFederationFormatVersion"), PENDING_FEDERATION_FORMAT_VERSION("pendingFederationFormatVersion"), - PROPOSED_FEDERATION_FORMAT_VERSION("proposedFederationFormatVersion") + PROPOSED_FEDERATION_FORMAT_VERSION("proposedFederationFormatVersion"), + SVP_FUND_TX_HASH_UNSIGNED("svpFundTxHashUnsigned") ; private final String key; diff --git a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java index cd57967f44..43cd160ede 100644 --- a/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java +++ b/rskj-core/src/main/java/co/rsk/peg/federation/FederationStorageProvider.java @@ -1,6 +1,7 @@ package co.rsk.peg.federation; import co.rsk.bitcoinj.core.NetworkParameters; +import co.rsk.bitcoinj.core.Sha256Hash; import co.rsk.bitcoinj.core.UTXO; import co.rsk.bitcoinj.script.Script; import co.rsk.peg.federation.constants.FederationConstants; @@ -41,5 +42,8 @@ public interface FederationStorageProvider { Optional