Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/powpeg validation protocol integration #374

Merged
merged 112 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
0773d28
refactor(fed): federation watcher tests
apancorb Sep 30, 2024
0c3db4f
feat(federate): change access modifier for federation watcher listerner
apancorb Oct 2, 2024
d2e77e8
fix(btcreleaseclient): remove signature cache dependency from BridgeE…
apancorb Oct 23, 2024
2e7f3bc
feat(federate): implement getProposedFederationAddress in federation …
apancorb Oct 23, 2024
a8d1ba2
feat(bitcoin): add bitcoin test util methods
apancorb Oct 24, 2024
5642827
refactor(watcher): refactor federation watcher to its own package
apancorb Oct 21, 2024
b921125
refactor(watcher): simplify FederationWatcherListener interface and a…
apancorb Oct 22, 2024
97f513a
refactor(watcher): organize and remove some comments for FederationWa…
apancorb Oct 23, 2024
e0c3084
feat(btcreleaseclient): federator should be part of the federation wh…
apancorb Oct 24, 2024
e7ae5f6
feat(federate): throw an exception if federator is not a member of th…
apancorb Oct 24, 2024
6b5417b
feat(watcher): change stop and starting logic when active and retirin…
apancorb Oct 24, 2024
961375e
refactor(watcher): rename interface variables to be more explicit and…
apancorb Oct 25, 2024
c2eb011
fix(federate): solve unit tests since was using a member not part of …
apancorb Oct 25, 2024
ac0ce1c
refactor(watcher): change updateActiveFederation to use the original …
apancorb Oct 29, 2024
f34d32d
refactor(watcher): small code structure change and better logging
apancorb Oct 29, 2024
1daa5bf
feat(watcher): make the active federation be required to be non-null
apancorb Oct 29, 2024
4ada44f
refactor(btcreleaseclient): make better log statements for start and …
apancorb Oct 30, 2024
e39a073
fix(btcreleaseclient): if the member running the node is not part of …
apancorb Oct 30, 2024
11d8d7b
feat(btcreleaseclient): add unit test for federation member is not pa…
apancorb Oct 30, 2024
2445b49
feat(watcher): add unit tests for FederationWatcherListenerImpl
apancorb Oct 30, 2024
bc20093
feat(config): add description for isPegoutEnabled parameter
apancorb Nov 7, 2024
df04df7
refactor(federate): remove unused method getLiveFederations
apancorb Nov 7, 2024
4dbc601
refactor(federate): remove unused unit tests for getLiveFederations m…
apancorb Nov 7, 2024
4013dc7
refactor(btcreleaseclient): enhance javadoc for class
apancorb Oct 28, 2024
8dab2bd
refactor(btcreleaseclient): small refactor to include proper spaces a…
apancorb Oct 28, 2024
2c043f2
feat(federate): add bridge call to retrieve svp spend tx waiting for …
apancorb Oct 28, 2024
d1b620a
refactor(federate): remove unnecessary blank lines in FederateSupport…
apancorb Oct 28, 2024
4cdfb83
feat(btcreleaseclient): add call to getStateForProposedFederator when…
apancorb Oct 28, 2024
f12988a
refactor(btcreleaseclient): small change to code structure for rsk tx…
apancorb Oct 29, 2024
b39aff5
feat(btcreleaseclient): add unit tests for svp tx waiting for signatu…
apancorb Oct 29, 2024
ea4c9fe
refactor(btcreleaseclient): reword svp spend comment
apancorb Nov 1, 2024
c1e5fb4
refactor(btcreleaseclient): propper code formatting
apancorb Nov 1, 2024
98afa80
feat(btcreleaseclient): add receipt store logic to find the block has…
apancorb Nov 1, 2024
2002d39
feat(federate): add receipt store dependency to BtcReleaseClient class
apancorb Nov 1, 2024
a9d98cd
feat(btcreleaseclient): add confirmation diff logic using the receipt…
apancorb Nov 1, 2024
965ee9d
fix(btcreleaseclient): avoid shadowing receipt store instance variable
apancorb Nov 1, 2024
fd7fba4
feat(btcreleaseclient): include is ready to sign method only for the …
apancorb Nov 4, 2024
dda4367
refactor(btcreleaseclient): update log statement
apancorb Nov 4, 2024
ad72dab
feat(btcreleaseclient): use mainnet params for unit tests
apancorb Nov 5, 2024
aa45698
feat(btcreleaseclient): add better naming for unit tests vars
apancorb Nov 5, 2024
acc5cea
feat(btcreleaseclient): add both svp spend tx and pegout unit test an…
apancorb Nov 5, 2024
3331dc4
refactor(btcreleaseclient): reuse fed key for unit test
apancorb Nov 5, 2024
130bfab
feat(btcreleaseclient) add unit test for when pegouts and svp spend t…
apancorb Nov 5, 2024
479faeb
feat(btcreleaseclient): update all fed ekys for unit tests
apancorb Nov 5, 2024
db11245
feat(btcreleaseclient): add warning log in case isPegoutEnabled is di…
apancorb Nov 8, 2024
64712e7
feat(federate): add unit tests for getStateForProposedFederator
apancorb Nov 8, 2024
90fc21a
feat(btcreleaseclient): use ReleaseCreationInformationGetter to retri…
apancorb Nov 8, 2024
223fe3e
feat(federate): add getProposedFederationSize to FederatorSupport
apancorb Oct 25, 2024
162f1bd
feat(federate): add getProposedFederatorPublicKeyOfType to FederatorS…
apancorb Oct 25, 2024
89ad3e4
feat(federate): add getProposedFederationCreationTime to FederatorSup…
apancorb Oct 25, 2024
ddced98
feat(federate): add getProposedFederationCreationBlockNumber to Feder…
apancorb Oct 25, 2024
affdc8d
feat(federate): add getProposedFederation to FederationProvider inter…
apancorb Oct 25, 2024
dbb459a
feat(federate): add implementation of getProposedFederation to Federa…
apancorb Oct 25, 2024
8d7cf68
refactor(federate): use FEDERATION_NON_EXISTENT enum code in conditio…
apancorb Oct 25, 2024
5631f96
feat(federate): add unit tests for getProposedFederationSize
apancorb Oct 25, 2024
77f793e
feat(federate): add unit tests for getProposedFederatorPublicKeyOfType
apancorb Oct 25, 2024
3dd1d2e
feat(federate): add unit tests for getProposedFederationCreationTime
apancorb Oct 25, 2024
80235a3
feat(federate): add unit tests for getProposedFederationCreationBlock…
apancorb Oct 25, 2024
f19d2a3
feat(federate): add unit tests for getProposedFederation
apancorb Oct 25, 2024
dba01d2
fix(federate): use proper activation rule for svp
apancorb Oct 25, 2024
37b0e79
refactor(federate): improve javadocs for FederationProvider interface
apancorb Oct 30, 2024
b9d51cb
refactor(federate): use isEmpty when checking if retiring federation …
apancorb Oct 30, 2024
b4fa710
feat(federate): throw exception if after proving that the proposed fe…
apancorb Oct 30, 2024
5a25e9a
refactor(federate): method call consistent with all the other propose…
apancorb Oct 30, 2024
a4794bc
feat(federate): after rskip419 the only possible type of federation i…
apancorb Oct 30, 2024
1db89c0
feat(federate): remove unit tests for proposed federation that are un…
apancorb Oct 30, 2024
a1f7a14
fix(federate): update var name to not shadow global federator support…
apancorb Oct 30, 2024
ae7ec27
refactor(federate): replace lambda with method reference 'IllegalStat…
apancorb Oct 30, 2024
8312e62
refactor(federate): improve sonar complaints of FederateSupport
apancorb Oct 30, 2024
1c2a53b
refactor(federate): make FederationProvider javadoc more concise
apancorb Oct 31, 2024
5fa4c90
feat(federate): remove checking the proposed federation addr to valid…
apancorb Oct 31, 2024
64f2d10
feat(federate): remove unit tests verifying if proposed fed addr is b…
apancorb Oct 31, 2024
6b96115
feat(federate): add try-catch block in case proposed federation is un…
apancorb Oct 31, 2024
727e6fd
feat(federate): add unit test when proposed federation cannot be buil…
apancorb Oct 31, 2024
d32fdb2
refactor(federate): rename unit tests
apancorb Nov 1, 2024
132594e
refactor(federate): use ECKey class to build pub key in unit tests
apancorb Nov 1, 2024
7861f58
feat(federate): change catch exception class to catch all possible ex…
apancorb Nov 4, 2024
f9638c6
refactor(federate): remove checking if RSKIP419 is activated for prop…
apancorb Nov 4, 2024
f9dad08
feat(federate): remove RSKIP419 reference for unit tests
apancorb Nov 4, 2024
237c478
feat(federate): remove unit tests related with proposed fed and rskip419
apancorb Nov 5, 2024
e074842
refactor(federate): remove Optional flat map to get the addr of the p…
apancorb Nov 5, 2024
e95285d
feat(federate): remove unnecessary use of mocking activations in unit…
apancorb Nov 6, 2024
a93b3f6
refactor(federate): removed checking if retiring fed addr is present …
apancorb Nov 8, 2024
c1d095b
feat(federate): Change getProposedFederationCreationTime to return In…
apancorb Nov 8, 2024
0305509
feat(federate): wrap logic for building the retiring fed in try-catch
apancorb Nov 12, 2024
035783d
refactor(federate): enhance javadoc for FederationProviderFromFederat…
apancorb Nov 12, 2024
58cda8a
feat(federate): add unit test when getting addr for retiring fed does…
apancorb Nov 12, 2024
de99418
feat(federate): allow exception to propagate in the listener if unabl…
apancorb Nov 13, 2024
2df6e6f
feat(watcher): add onProposedFederation method to interface
apancorb Nov 4, 2024
cdcad87
feat(watcher): intial implementation of onProposedFederationChange
apancorb Nov 4, 2024
2daf8f0
feat(watcher): enhance with try-catch and logging onProposedFederatio…
apancorb Nov 6, 2024
96e769d
feat(watcher): use javadoc annotation for comment in onProposedFedera…
apancorb Nov 6, 2024
5ecc6dd
feat(watcher): add unit tests for onProposedFederationChange
apancorb Nov 6, 2024
2329122
feat(watcher): implement onProposedFederationChange for anoymous clas…
apancorb Nov 6, 2024
c765066
feat(watcher): add logic for change in proposed fed in FederationWatc…
apancorb Nov 12, 2024
6f923bc
refactor(watcher): use mock of federation watcher listener instead of…
apancorb Nov 12, 2024
c100325
feat(watcher): accomdate existing unit tests for proposed fed logic
apancorb Nov 12, 2024
002cf09
feat(watcher): call updateProposedFederation before updateActiveFeder…
apancorb Nov 12, 2024
0a46349
feat(watcher): add unit test for proposed federation in FederationWat…
apancorb Nov 12, 2024
fcc6876
refactor(wathcer): log statement for onProposedFederationChange
apancorb Nov 12, 2024
9eba9ab
refactor(watcher): test naming and log statements
apancorb Nov 12, 2024
f91e5d4
fix(federate): add RSKIP419 check for proposed federation methods
apancorb Nov 19, 2024
6136d95
Adapt to time unit bridge method change
julia-zack Dec 5, 2024
5ba5138
Add tests pre rskip 419
julia-zack Dec 6, 2024
b3d9f37
fix(btcreleaseclient): place call to get svp spend tx wfs behind acti…
apancorb Nov 21, 2024
e54e1bc
fix(watcher): add correct log prefix
apancorb Nov 22, 2024
2b1df09
feat(bitcoin): add logic to detect when processing a svp spend tx
apancorb Dec 6, 2024
99e9d69
refactor(federate): add proper spacing between code segments
apancorb Dec 11, 2024
76e9dec
refactor(federate): move code segments in BtcToRskClient
apancorb Dec 11, 2024
64fa037
feat(bitcoin): remove svp spend tx handling in BitcoinWrapperImpl
apancorb Dec 11, 2024
f61785b
feat(watcher): add BitcoinWrapper to onProposedFederationChange so it…
apancorb Dec 11, 2024
d094673
feat(watcher): update unit tests to accomdate BitcoinWrapper listener…
apancorb Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 24 additions & 21 deletions src/main/java/co/rsk/federate/BtcToRskClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,24 +111,26 @@ public synchronized void setup(
public void start(Federation federation) {
logger.info("[start] Starting for Federation {}", federation.getAddress());
this.federation = federation;

FederationMember federator = federatorSupport.getFederationMember();
boolean isMember = federation.isMember(federator);

if (!isMember) {
logger.info("[start] member {} is no part of the federation {} ",
String message = String.format(
"Member %s is no part of the federation %s",
federator.getBtcPublicKey(),
federation.getAddress());
return;
logger.error("[start] {}", message);
throw new IllegalStateException(message);
}

logger.info("[start] {} is member of the federation {}",
federator.getBtcPublicKey(), federation.getAddress());
logger.info("[start] Watching federation {} since I belong to it",
federation.getAddress());
bitcoinWrapper.addFederationListener(federation, this);

Optional<Integer> federatorIndex = federation.getBtcPublicKeyIndex(
federatorSupport.getFederationMember().getBtcPublicKey()
);
federatorSupport.getFederationMember().getBtcPublicKey());
if (!federatorIndex.isPresent()) {
String message = String.format(
"Federator %s is a member of the federation %s but could not find the btcPublicKeyIndex",
Expand All @@ -138,34 +140,33 @@ public void start(Federation federation) {
logger.error("[start] {}", message);
throw new IllegalStateException(message);
}
TurnScheduler scheduler = new TurnScheduler(
bridgeConstants.getUpdateBridgeExecutionPeriod(),
federation.getSize()
);
long now = Clock.systemUTC().instant().toEpochMilli();

if (isUpdateBridgeTimerEnabled) {
updateBridgeTimer = Executors.newSingleThreadScheduledExecutor();
long now = Clock.systemUTC().instant().toEpochMilli();
TurnScheduler scheduler = new TurnScheduler(
bridgeConstants.getUpdateBridgeExecutionPeriod(),
federation.getSize());

this.updateBridgeTimer = Executors.newSingleThreadScheduledExecutor();

updateBridgeTimer.scheduleAtFixedRate(
this::updateBridge,
scheduler.getDelay(now, federatorIndex.get()),
scheduler.getInterval(),
TimeUnit.MILLISECONDS
);
}
else {
TimeUnit.MILLISECONDS);
} else {
logger.info("[start] updateBridgeTimer is disabled");
}
}

public void stop() {
logger.info("Stopping");

federation = null;
this.federation = null;

if (updateBridgeTimer != null) {
updateBridgeTimer.shutdown();
updateBridgeTimer = null;
this.updateBridgeTimer = null;
}
}

Expand All @@ -177,13 +178,15 @@ public void updateBridge() {
if (federation == null) {
logger.warn("[updateBridge] updateBridge skipped because no Federation is associated to this BtcToRskClient");
}

if (nodeBlockProcessor.hasBetterBlockToSync()) {
logger.warn("[updateBridge] updateBridge skipped because the node is syncing blocks");
return;
}

logger.debug("[updateBridge] Updating bridge");

if(shouldUpdateBridgeBtcBlockchain) {
if (shouldUpdateBridgeBtcBlockchain) {
// Call receiveHeaders
try {
int numberOfBlocksSent = updateBridgeBtcBlockchain();
Expand All @@ -194,7 +197,7 @@ public void updateBridge() {
}
}

if(shouldUpdateBridgeBtcCoinbaseTransactions) {
if (shouldUpdateBridgeBtcCoinbaseTransactions) {
// Call registerBtcCoinbaseTransaction
try {
logger.debug("[updateBridge] Updating transactions and sending update");
Expand All @@ -205,7 +208,7 @@ public void updateBridge() {
}
}

if(shouldUpdateBridgeBtcTransactions) {
if (shouldUpdateBridgeBtcTransactions) {
// Call registerBtcTransaction
try {
logger.debug("[updateBridge] Updating transactions and sending update");
Expand All @@ -216,7 +219,7 @@ public void updateBridge() {
}
}

if(shouldUpdateCollections) {
if (shouldUpdateCollections) {
// Call updateCollections
try {
logger.debug("[updateBridge] Sending updateCollections");
Expand Down
1 change: 1 addition & 0 deletions src/main/java/co/rsk/federate/FedNodeContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import co.rsk.federate.signing.hsm.advanceblockchain.HSMBookKeepingClientProvider;
import co.rsk.federate.signing.hsm.client.HSMClientProtocolFactory;
import co.rsk.federate.solidity.DummySolidityCompiler;
import co.rsk.federate.watcher.FederationWatcher;
import java.util.concurrent.TimeUnit;
import org.ethereum.rpc.Web3;
import org.ethereum.solidity.compiler.SolidityCompiler;
Expand Down
50 changes: 11 additions & 39 deletions src/main/java/co/rsk/federate/FedNodeRunner.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@
import co.rsk.federate.signing.hsm.message.SignerMessageBuilderFactory;
import co.rsk.federate.signing.hsm.requirements.AncestorBlockUpdater;
import co.rsk.federate.signing.hsm.requirements.ReleaseRequirementsEnforcer;
import co.rsk.peg.federation.Federation;
import co.rsk.federate.watcher.FederationWatcher;
import co.rsk.federate.watcher.FederationWatcherListener;
import co.rsk.federate.watcher.FederationWatcherListenerImpl;
import co.rsk.peg.federation.FederationMember;
import co.rsk.peg.btcLockSender.BtcLockSenderProvider;
import co.rsk.peg.pegininstructions.PeginInstructionsProvider;
Expand All @@ -65,7 +67,6 @@
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

/**
Expand Down Expand Up @@ -342,27 +343,14 @@ private void startFederate() throws Exception {
config.getBtcReleaseClientInitializationMaxDepth()
)
);
federationWatcher.setup(federationProvider);

federationWatcher.addListener(new FederationWatcher.Listener() {
@Override
public void onActiveFederationChange(Optional<Federation> oldFederation, Federation newFederation) {
String oldFederationAddress = oldFederation.map(f -> f.getAddress().toString()).orElse("NONE");
String newFederationAddress = newFederation.getAddress().toString();
logger.debug(String.format("[onActiveFederationChange] Active federation change: from %s to %s", oldFederationAddress, newFederationAddress));
triggerClientChange(btcToRskClientActive, Optional.of(newFederation));
}

@Override
public void onRetiringFederationChange(Optional<Federation> oldFederation, Optional<Federation> newFederation) {
String oldFederationAddress = oldFederation.map(f -> f.getAddress().toString()).orElse("NONE");
String newFederationAddress = newFederation.map(f -> f.getAddress().toString()).orElse("NONE");
logger.debug(String.format("[onRetiringFederationChange] Retiring federation change: from %s to %s", oldFederationAddress, newFederationAddress));
triggerClientChange(btcToRskClientRetiring, newFederation);
}
});
// Trigger the first events
federationWatcher.updateState();

FederationWatcherListener federationWatcherListener = new FederationWatcherListenerImpl(
btcToRskClientActive,
btcToRskClientRetiring,
btcReleaseClient,
bitcoinWrapper);

federationWatcher.start(federationProvider, federationWatcherListener);
}
}

Expand All @@ -384,22 +372,6 @@ private void shutdown() {
System.exit(-1);
}

// TODO: This this method (and this whole class)
private void triggerClientChange(BtcToRskClient client, Optional<Federation> federation) {
client.stop();
federation.ifPresent(btcReleaseClient::stop);
// Only start if this federator is part of the new federation
if (federation.isPresent() && federation.get().isMember(this.member)) {
String federationAddress = federation.get().getAddress().toString();
logger.debug("[triggerClientChange] Starting lock and release clients since I belong to federation {}", federationAddress);
logger.info("[triggerClientChange] Joined to {} federation", federationAddress);
client.start(federation.get());
btcReleaseClient.start(federation.get());
} else {
logger.warn("[triggerClientChange] This federator node is not part of the new federation. Check your configuration for signers BTC, RSK and MST keys");
}
}

@Override
public void stop() {
logger.info("[stop] Shutting down Federation node");
Expand Down
55 changes: 40 additions & 15 deletions src/main/java/co/rsk/federate/FederationProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,59 @@
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package co.rsk.federate;

import co.rsk.bitcoinj.core.Address;
import co.rsk.peg.federation.Federation;

import java.util.List;
import java.util.Optional;

/**
* Implementors of this interface must be able to provide
* federation instances.
*
* @author Ariel Mendelzon
* Provides access to various federation instances, including the active, retiring, and proposed federations.
* Implementations of this interface must define how to retrieve the federations and their respective addresses.
* These methods allow clients to manage and monitor federations in different lifecycle stages within the bridge.
*/
public interface FederationProvider {
// The currently "active" federation

/**
* Retrieves the currently active federation.
*
* @return the active {@link Federation} instance
*/
Federation getActiveFederation();
// The currently "active" federation's address

/**
* Retrieves the address of the currently active federation.
*
* @return the {@link Address} of the active federation
*/
Address getActiveFederationAddress();

// The currently "retiring" federation
/**
* Retrieves the currently retiring federation, if one exists. This federation is in transition
* and will soon be replaced by a new active federation.
*
* @return an {@link Optional} containing the retiring {@link Federation}, or {@link Optional#empty()} if none exists
*/
Optional<Federation> getRetiringFederation();
// The currently "retiring" federation's address

/**
* Retrieves the address of the currently retiring federation, if one exists.
*
* @return an {@link Optional} containing the {@link Address} of the retiring federation, or {@link Optional#empty()} if none exists
*/
Optional<Address> getRetiringFederationAddress();

// The federations that are "live", that is, are still
// operational. This should be the active federation
// plus the retiring federation, if one exists
List<Federation> getLiveFederations();
/**
* Retrieves the currently proposed federation, if one exists. This federation is awaiting validation.
*
* @return an {@link Optional} containing the proposed {@link Federation}, or {@link Optional#empty()} if none exists
*/
Optional<Federation> getProposedFederation();

/**
* Retrieves the address of the currently proposed federation, if one exists.
*
* @return an {@link Optional} containing the {@link Address} of the proposed federation, or {@link Optional#empty()} if none exists
*/
Optional<Address> getProposedFederationAddress();
}
Loading
Loading