Skip to content

Commit 60e98d5

Browse files
committed
Merge branch 'master' into fingerroot5300-master-merge
2 parents 297bf7b + 848a697 commit 60e98d5

File tree

11 files changed

+165
-49
lines changed

11 files changed

+165
-49
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ ext {
7373
junitVersion = '5.8.1'
7474
junitSuiteVersion = '1.9.0'
7575
mockitoVersion = '4.6.1'
76-
rskjcoreVersion = '5.3.0-FINGERROOT'
76+
rskjcoreVersion = '5.4.0-SNAPSHOT'
7777
}
7878

7979
dependencies {

gradle/verification-metadata.xml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1509,12 +1509,12 @@
15091509
<sha256 value="5b626a99e5734ba8d0c0c8c3fc6258afa0624f4ce61ae1192247d03c57463ded" origin="Generated by Gradle"/>
15101510
</artifact>
15111511
</component>
1512-
<component group="org.rocksdb" name="rocksdbjni" version="6.27.3">
1513-
<artifact name="rocksdbjni-6.27.3.jar">
1514-
<sha256 value="a1ce1d0f64e978e490a29ea3ad757372266739d89baa2e153b16e4231eae659d" origin="Generated by Gradle"/>
1512+
<component group="org.rocksdb" name="rocksdbjni" version="7.10.2">
1513+
<artifact name="rocksdbjni-7.10.2.jar">
1514+
<sha256 value="613b6a84a61b74d9b83778697f25ce5b1e159bd517a3b05ee408ae0738f547aa" origin="Generated by Gradle"/>
15151515
</artifact>
1516-
<artifact name="rocksdbjni-6.27.3.pom">
1517-
<sha256 value="42a868e107aeff1f15ec3e65e993c615ba87db736b8591a5b256cac4cbc2a3fc" origin="Generated by Gradle"/>
1516+
<artifact name="rocksdbjni-7.10.2.pom">
1517+
<sha256 value="edf496e83b697dbfb7d127a6c58f5951d4777b933ff8db252fbe8567f50206c1" origin="Generated by Gradle"/>
15181518
</artifact>
15191519
</component>
15201520
<component group="org.slf4j" name="log4j-over-slf4j" version="1.7.36">

src/main/java/co/rsk/federate/BtcToRskClient.java

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import co.rsk.panic.PanicProcessor;
1313
import co.rsk.peg.BridgeUtils;
1414
import co.rsk.peg.Federation;
15+
import co.rsk.peg.FederationMember;
1516
import co.rsk.peg.PeginInformation;
1617
import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType;
1718
import co.rsk.peg.pegininstructions.PeginInstructionsException;
@@ -115,25 +116,52 @@ public synchronized void setup(
115116
}
116117

117118
public void start(Federation federation) {
118-
logger.info("Starting for Federation {}", federation.getAddress().toString());
119+
logger.info("[start] Starting for Federation {}", federation.getAddress());
119120
this.federation = federation;
120-
if (federation.isMember(federatorSupport.getFederationMember())) {
121-
logger.info("Watching federation {} since I belong to it", federation.getAddress().toString());
122-
bitcoinWrapper.addFederationListener(federation, this);
123-
int federatorIndex = federation.getBtcPublicKeyIndex(federatorSupport.getFederationMember().getBtcPublicKey());
124-
TurnScheduler scheduler = new TurnScheduler(
125-
bridgeConstants.getUpdateBridgeExecutionPeriod(),
126-
federation.getSize()
127-
);
128-
long now = Clock.systemUTC().instant().toEpochMilli();
121+
FederationMember federator = federatorSupport.getFederationMember();
122+
boolean isMember = federation.isMember(federator);
129123

130-
if (isUpdateBridgeTimerEnabled) {
131-
updateBridgeTimer = Executors.newSingleThreadScheduledExecutor();
132-
updateBridgeTimer.scheduleAtFixedRate(this::updateBridge, scheduler.getDelay(now, federatorIndex), scheduler.getInterval(), TimeUnit.MILLISECONDS);
133-
}
134-
else {
135-
logger.info("updateBridgeTimer is disabled");
136-
}
124+
if (!isMember) {
125+
logger.info("[start] member {} is no part of the federation {} ",
126+
federator.getBtcPublicKey(),
127+
federation.getAddress());
128+
return;
129+
}
130+
131+
logger.info("[start] {} is member of the federation {}",
132+
federator.getBtcPublicKey(), federation.getAddress());
133+
logger.info("[start] Watching federation {} since I belong to it",
134+
federation.getAddress());
135+
bitcoinWrapper.addFederationListener(federation, this);
136+
Optional<Integer> federatorIndex = federation.getBtcPublicKeyIndex(
137+
federatorSupport.getFederationMember().getBtcPublicKey()
138+
);
139+
if (!federatorIndex.isPresent()) {
140+
String message = String.format(
141+
"Federator %s is a member of the federation %s but could not find the btcPublicKeyIndex",
142+
federator,
143+
federation.getAddress()
144+
);
145+
logger.error("[start] {}", message);
146+
throw new IllegalStateException(message);
147+
}
148+
TurnScheduler scheduler = new TurnScheduler(
149+
bridgeConstants.getUpdateBridgeExecutionPeriod(),
150+
federation.getSize()
151+
);
152+
long now = Clock.systemUTC().instant().toEpochMilli();
153+
154+
if (isUpdateBridgeTimerEnabled) {
155+
updateBridgeTimer = Executors.newSingleThreadScheduledExecutor();
156+
updateBridgeTimer.scheduleAtFixedRate(
157+
this::updateBridge,
158+
scheduler.getDelay(now, federatorIndex.get()),
159+
scheduler.getInterval(),
160+
TimeUnit.MILLISECONDS
161+
);
162+
}
163+
else {
164+
logger.info("[start] updateBridgeTimer is disabled");
137165
}
138166
}
139167

src/main/java/co/rsk/federate/FederationProviderFromFederatorSupport.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@
2121
import co.rsk.bitcoinj.core.Address;
2222
import co.rsk.bitcoinj.core.BtcECKey;
2323
import co.rsk.config.BridgeConstants;
24-
import co.rsk.peg.ErpFederation;
2524
import co.rsk.peg.Federation;
26-
import co.rsk.peg.FederationMember;
25+
import co.rsk.peg.StandardMultisigFederation;
26+
import co.rsk.peg.LegacyErpFederation;
2727
import co.rsk.peg.P2shErpFederation;
28+
import co.rsk.peg.FederationMember;
2829
import org.ethereum.crypto.ECKey;
2930

3031
import java.time.Instant;
@@ -76,7 +77,7 @@ public Federation getActiveFederation() {
7677
Instant creationTime = federatorSupport.getFederationCreationTime();
7778
long creationBlockNumber = federatorSupport.getFederationCreationBlockNumber();
7879

79-
Federation initialFederation = new Federation(
80+
Federation initialFederation = new StandardMultisigFederation(
8081
members,
8182
creationTime,
8283
creationBlockNumber,
@@ -126,7 +127,7 @@ public Optional<Federation> getRetiringFederation() {
126127
Instant creationTime = federatorSupport.getRetiringFederationCreationTime();
127128
long creationBlockNumber = federatorSupport.getRetiringFederationCreationBlockNumber();
128129

129-
Federation initialFederation = new Federation(
130+
Federation initialFederation = new StandardMultisigFederation(
130131
members,
131132
creationTime,
132133
creationBlockNumber,
@@ -159,7 +160,7 @@ private Federation getExpectedFederation(Federation initialFederation, Address e
159160
}
160161

161162
// If addresses do not match build an ERP federation
162-
Federation erpFederation = new ErpFederation(
163+
Federation erpFederation = new LegacyErpFederation(
163164
initialFederation.getMembers(),
164165
initialFederation.getCreationTime(),
165166
initialFederation.getCreationBlockNumber(),

src/main/java/co/rsk/federate/btcreleaseclient/BtcReleaseClient.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import co.rsk.peg.BridgeEvents;
3434
import co.rsk.peg.BridgeUtils;
3535
import co.rsk.peg.Federation;
36+
import co.rsk.peg.ErpFederation;
3637
import co.rsk.peg.StateForFederator;
3738
import java.util.ArrayList;
3839
import java.util.Arrays;
@@ -351,7 +352,7 @@ protected void validateTxCanBeSigned(BtcTransaction btcTx) throws FederatorAlrea
351352
observedFederations.stream()
352353
.forEach(f -> logger.trace("[validateTxCanBeSigned] federation p2sh redeem script {}", f.getRedeemScript()));
353354
List<Federation> spendingFedFilter = observedFederations.stream()
354-
.filter(f -> f.getStandardRedeemScript().equals(standardRedeemScript)).collect(Collectors.toList());
355+
.filter(f -> (f instanceof ErpFederation ? ((ErpFederation) f).getStandardRedeemScript() : f.getRedeemScript()).equals(standardRedeemScript)).collect(Collectors.toList());
355356
logger.debug("[validateTxCanBeSigned] spendingFedFilter size {}", spendingFedFilter.size());
356357
if (spendingFedFilter.isEmpty()) {
357358
String message = String.format(
@@ -463,7 +464,7 @@ protected Federation getSpendingFederation(BtcTransaction btcTx) {
463464
Script redeemScript = extractStandardRedeemScript(getRedeemScriptFromInput(firstInput));
464465

465466
List<Federation> spendingFedFilter = observedFederations.stream()
466-
.filter(f -> f.getStandardRedeemScript().equals(redeemScript)).collect(Collectors.toList());
467+
.filter(f -> (f instanceof ErpFederation ? ((ErpFederation) f).getStandardRedeemScript() : f.getRedeemScript()).equals(redeemScript)).collect(Collectors.toList());
467468

468469
return spendingFedFilter.get(0);
469470
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
versionNumber='5.3.0.0'
2-
modifier="FINGERROOT"
1+
versionNumber='5.4.0.0'
2+
modifier="SNAPSHOT"

src/test/java/co/rsk/federate/BtcToRskClientTest.java

Lines changed: 80 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import static org.junit.jupiter.api.Assertions.assertNull;
77
import static org.junit.jupiter.api.Assertions.assertSame;
88
import static org.junit.jupiter.api.Assertions.assertThrows;
9+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
910
import static org.junit.jupiter.api.Assertions.assertTrue;
1011
import static org.mockito.Mockito.any;
1112
import static org.mockito.Mockito.anyInt;
@@ -39,6 +40,7 @@
3940
import co.rsk.net.NodeBlockProcessor;
4041
import co.rsk.peg.BridgeUtils;
4142
import co.rsk.peg.Federation;
43+
import co.rsk.peg.FederationMember;
4244
import co.rsk.peg.btcLockSender.BtcLockSender;
4345
import co.rsk.peg.btcLockSender.BtcLockSender.TxSenderAddressType;
4446
import co.rsk.peg.btcLockSender.BtcLockSenderProvider;
@@ -47,6 +49,7 @@
4749
import co.rsk.peg.pegininstructions.PeginInstructionsProvider;
4850
import com.google.common.collect.Lists;
4951
import java.io.IOException;
52+
import java.nio.charset.StandardCharsets;
5053
import java.util.ArrayList;
5154
import java.util.Arrays;
5255
import java.util.Collections;
@@ -75,6 +78,7 @@
7578
import org.bitcoinj.store.BlockStoreException;
7679
import org.ethereum.config.blockchain.upgrades.ActivationConfig;
7780
import org.ethereum.config.blockchain.upgrades.ConsensusRule;
81+
import org.ethereum.crypto.HashUtil;
7882
import org.junit.jupiter.api.BeforeEach;
7983
import org.junit.jupiter.api.Test;
8084
import org.spongycastle.util.encoders.Hex;
@@ -89,6 +93,7 @@ class BtcToRskClientTest {
8993
private ActivationConfig activationConfig;
9094
private BridgeConstants bridgeRegTestConstants;
9195
private Federation genesisFederation;
96+
private FederationMember fakeMember;
9297
private BtcToRskClientBuilder btcToRskClientBuilder;
9398

9499
@BeforeEach
@@ -99,9 +104,50 @@ void setup() throws PeginInstructionsException, IOException {
99104

100105
bridgeRegTestConstants = BridgeRegTestConstants.getInstance();
101106
genesisFederation = bridgeRegTestConstants.getGenesisFederation();
107+
fakeMember = FederationMember.getFederationMemberFromKey(
108+
BtcECKey.fromPrivate(
109+
HashUtil.keccak256("00".getBytes(StandardCharsets.UTF_8))
110+
)
111+
);
102112
btcToRskClientBuilder = new BtcToRskClientBuilder();
103113
}
104114

115+
@Test
116+
void start_withExistingFederationMember_doesntThrowError() throws Exception {
117+
BitcoinWrapper bw = new SimpleBitcoinWrapper();
118+
SimpleFederatorSupport fh = new SimpleFederatorSupport();
119+
120+
FederationMember fedMember = genesisFederation.getMembers().get(0);
121+
fh.setMember(fedMember);
122+
BtcToRskClient client = createClientWithMocks(bw, fh);
123+
assertDoesNotThrow(() -> client.start(genesisFederation));
124+
}
125+
126+
@Test
127+
void start_withNoFederationMember_doesntThrowError() throws Exception {
128+
BitcoinWrapper bw = new SimpleBitcoinWrapper();
129+
SimpleFederatorSupport fh = new SimpleFederatorSupport();
130+
131+
fh.setMember(fakeMember);
132+
BtcToRskClient client = createClientWithMocks(bw, fh);
133+
assertDoesNotThrow(() -> client.start(genesisFederation));
134+
}
135+
136+
@Test
137+
void start_withFederationMember_withoutMemberPkIndex_throwsError() throws Exception {
138+
BitcoinWrapper bw = new SimpleBitcoinWrapper();
139+
SimpleFederatorSupport fh = new SimpleFederatorSupport();
140+
Federation federation = mock(Federation.class);
141+
FederationMember fedMember = genesisFederation.getMembers().get(0);
142+
143+
fh.setMember(fedMember);
144+
when(federation.isMember(fedMember)).thenReturn(true);
145+
when(federation.getBtcPublicKeyIndex(any())).thenReturn(Optional.empty());
146+
147+
BtcToRskClient client = createClientWithMocksCustomFederation(bw, fh, federation);
148+
assertThrows(IllegalStateException.class, () -> client.start(federation));
149+
}
150+
105151
@Test
106152
void getNoTransactions() {
107153
BtcToRskClient client = new BtcToRskClient();
@@ -148,6 +194,25 @@ private BtcToRskClient createClientWithMocks(
148194
.build();
149195
}
150196

197+
private BtcToRskClient createClientWithMocksCustomFederation(
198+
BitcoinWrapper bitcoinWrapper,
199+
FederatorSupport federatorSupport,
200+
Federation federation) throws Exception {
201+
202+
BtcLockSenderProvider btcLockSenderProvider = mockBtcLockSenderProvider(TxSenderAddressType.P2PKH);
203+
int amountOfHeadersToSend = 100;
204+
205+
return btcToRskClientBuilder
206+
.withActivationConfig(activationConfig)
207+
.withBitcoinWrapper(bitcoinWrapper)
208+
.withFederatorSupport(federatorSupport)
209+
.withBridgeConstants(bridgeRegTestConstants)
210+
.withBtcLockSenderProvider(btcLockSenderProvider)
211+
.withFederation(federation)
212+
.withAmountOfHeadersToSend(amountOfHeadersToSend)
213+
.build();
214+
}
215+
151216
private BtcToRskClient createClientWithMocksCustomStorageFiles(
152217
BitcoinWrapper bw,
153218
FederatorSupport fs,
@@ -446,8 +511,11 @@ void onBlock_including_segwit_tx_registers_coinbase() throws Exception {
446511
ActivationConfig mockedActivationConfig = mock(ActivationConfig.class);
447512
when(mockedActivationConfig.isActive(eq(ConsensusRule.RSKIP143), anyLong())).thenReturn(true);
448513

514+
FederatorSupport federatorSupport = mock(FederatorSupport.class);
515+
when(federatorSupport.getFederationMember()).thenReturn(fakeMember);
516+
449517
BtcToRskClient client = spy(buildWithFactoryAndSetup(
450-
mock(FederatorSupport.class),
518+
federatorSupport,
451519
mock(NodeBlockProcessor.class),
452520
mockedActivationConfig,
453521
mock(BitcoinWrapperImpl.class),
@@ -1683,6 +1751,8 @@ void updateTransaction_with_release_before_rskip143() throws Exception {
16831751
bitcoinWrapper.setBlocks(blocks);
16841752

16851753
SimpleFederatorSupport federatorSupport = new SimpleFederatorSupport();
1754+
// set a fake member to federatorSupport to recreate a not-null runner
1755+
federatorSupport.setMember(fakeMember);
16861756

16871757
BtcToRskClient client = buildWithFactoryAndSetup(
16881758
federatorSupport,
@@ -2164,8 +2234,11 @@ void updateBridgeBtcCoinbaseTransactions_when_coinbase_map_has_readyToBeInformed
21642234
BtcToRskClientFileStorage btcToRskClientFileStorageMock = mock(BtcToRskClientFileStorage.class);
21652235
when(btcToRskClientFileStorageMock.read(any())).thenReturn(new BtcToRskClientFileReadResult(true, btcToRskClientFileData));
21662236

2237+
FederatorSupport federatorSupport = mock(FederatorSupport.class);
2238+
when(federatorSupport.getFederationMember()).thenReturn(fakeMember);
2239+
21672240
BtcToRskClient client = buildWithFactoryAndSetup(
2168-
mock(FederatorSupport.class),
2241+
federatorSupport,
21692242
mock(NodeBlockProcessor.class),
21702243
activations,
21712244
mock(BitcoinWrapperImpl.class),
@@ -2201,6 +2274,7 @@ void updateBridgeBtcCoinbaseTransactions_when_coinbase_map_has_readyToBeInformed
22012274
FederatorSupport federatorSupport = mock(FederatorSupport.class);
22022275
// mocking that the coinbase was already informed
22032276
when(federatorSupport.hasBlockCoinbaseInformed(any())).thenReturn(true);
2277+
when(federatorSupport.getFederationMember()).thenReturn(fakeMember);
22042278

22052279
BtcToRskClient client = buildWithFactoryAndSetup(
22062280
federatorSupport,
@@ -2243,6 +2317,7 @@ void updateBridgeBtcCoinbaseTransactions_when_coinbase_map_has_readyToBeInformed
22432317
FederatorSupport federatorSupport = mock(FederatorSupport.class);
22442318
// Mocking the Bridge to indicate the coinbase was not informed, and then it was
22452319
when(federatorSupport.hasBlockCoinbaseInformed(any())).thenReturn(false, true);
2320+
when(federatorSupport.getFederationMember()).thenReturn(fakeMember);
22462321

22472322
BtcToRskClient client = buildWithFactoryAndSetup(
22482323
federatorSupport,
@@ -2288,6 +2363,7 @@ void updateBridgeBtcCoinbaseTransactions_not_removing_from_storage_until_confirm
22882363
FederatorSupport federatorSupport = mock(FederatorSupport.class);
22892364
// mocking that the coinbase was not informed
22902365
when(federatorSupport.hasBlockCoinbaseInformed(any())).thenReturn(false);
2366+
when(federatorSupport.getFederationMember()).thenReturn(fakeMember);
22912367

22922368
BtcToRskClient client = buildWithFactoryAndSetup(
22932369
federatorSupport,
@@ -2328,6 +2404,7 @@ void updateBridge_when_does_not_hasBetterBlockToSync_updates_headers_coinbase_tr
23282404

23292405
FederatorSupport federatorSupport = mock(FederatorSupport.class);
23302406
when(federatorSupport.getBtcBestBlockChainHeight()).thenReturn(1);
2407+
when(federatorSupport.getFederationMember()).thenReturn(fakeMember);
23312408

23322409
BitcoinWrapper bitcoinWrapper = mock(BitcoinWrapper.class);
23332410
when(bitcoinWrapper.getBestChainHeight()).thenReturn(1);
@@ -2366,6 +2443,7 @@ void updateBridgeBtcTransactions_tx_with_witness_already_informed() throws Excep
23662443
when(federatorSupport.getBtcBestBlockChainHeight()).thenReturn(1);
23672444
when(federatorSupport.isBtcTxHashAlreadyProcessed(peginTx.getTxId())).thenReturn(true);
23682445
when(federatorSupport.getBtcTxHashProcessedHeight(peginTx.getTxId())).thenReturn(1L);
2446+
when(federatorSupport.getFederationMember()).thenReturn(fakeMember);
23692447

23702448
BitcoinWrapper bitcoinWrapper = mock(BitcoinWrapper.class);
23712449
when(bitcoinWrapper.getBestChainHeight()).thenReturn(1);

0 commit comments

Comments
 (0)