Skip to content

Commit

Permalink
Load active peers from previous session saved into file.
Browse files Browse the repository at this point in the history
  • Loading branch information
asoto-iov committed Jan 18, 2024
1 parent 6ba039d commit 8be6a43
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 51 deletions.
7 changes: 7 additions & 0 deletions rskj-core/src/main/java/co/rsk/RskContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -1588,6 +1588,13 @@ protected PeerExplorer getPeerExplorer() {
initialBootNodes.add(address.getHostName() + ":" + address.getPort());
}
}

if (rskSystemProperties.usePeersFromLastSession()) {
List<String> peerLastSession = rskSystemProperties.peerLastSession();
logger.debug("Loading peers from previous session: {}",peerLastSession);
initialBootNodes.addAll(peerLastSession);
}

peerExplorer = new PeerExplorer(
initialBootNodes,
localNode,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class RskSystemProperties extends SystemProperties {
private static final int CHUNK_SIZE = 192;

public static final String PROPERTY_SYNC_TOP_BEST = "sync.topBest";
public static final String USE_PEERS_FROM_LAST_SESSION = "peer.usePeersFromLastSession";

//TODO: REMOVE THIS WHEN THE LocalBLockTests starts working with REMASC
private boolean remascEnabled = true;
Expand Down Expand Up @@ -235,6 +236,10 @@ public boolean skipRemasc() {
return getBoolean("rpc.skipRemasc", false);
}

public boolean usePeersFromLastSession() {
return getBoolean(USE_PEERS_FROM_LAST_SESSION, false);
}

public long peerDiscoveryMessageTimeOut() {
return getLong("peer.discovery.msg.timeout", PD_DEFAULT_TIMEOUT_MESSAGE);
}
Expand Down
20 changes: 20 additions & 0 deletions rskj-core/src/main/java/org/ethereum/config/SystemProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -106,6 +109,7 @@ public abstract class SystemProperties {
public static final String PROPERTY_PERSIST_BLOOMS_CACHE_SNAPSHOT = "cache.blooms.persist-snapshot";

/* Testing */
public static final String LAST_CONNECTED_PEERS_FILE = "lastPeers.txt";
private static final Boolean DEFAULT_VMTEST_LOAD_LOCAL = false;

protected final Config configFromFiles;
Expand Down Expand Up @@ -251,6 +255,18 @@ public List<Node> peerActive() {
return list.stream().map(this::parsePeer).collect(Collectors.toList());
}

public List<String> peerLastSession() {
Path lastConnectedPeersFile = getLastConnectedPeersFilePath();
try {
if (Files.exists(lastConnectedPeersFile)) {
return Files.readAllLines(lastConnectedPeersFile);
}
} catch (IOException e) {
logger.error("Failed to read last connected peers file path {}. Error: {}", lastConnectedPeersFile.toAbsolutePath(), e.getMessage());
}
return Collections.emptyList();
}

private Node parsePeer(ConfigObject configObject) {
if (configObject.get("url") != null) {
String url = configObject.toConfig().getString("url");
Expand Down Expand Up @@ -312,6 +328,10 @@ public String databaseDir() {
return databaseDir == null ? configFromFiles.getString(PROPERTY_BASE_PATH) : databaseDir;
}

public Path getLastConnectedPeersFilePath() {
return Paths.get(databaseDir(), LAST_CONNECTED_PEERS_FILE);
}

public void setDataBaseDir(String dataBaseDir) {
this.databaseDir = dataBaseDir;
}
Expand Down
1 change: 1 addition & 0 deletions rskj-core/src/main/java/org/ethereum/net/NodeManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public synchronized List<NodeHandler> getNodes(Set<String> nodesInUse) {
List<Node> foundNodes = this.peerExplorer.getNodes();
if (this.discoveryEnabled && !foundNodes.isEmpty()) {
logger.debug("{} Nodes retrieved from the PE.", foundNodes.size());
foundNodes.forEach(n -> logger.debug("Node: {}", n.toString()));
foundNodes.stream().filter(n -> !nodeHandlerMap.containsKey(n.getHexId())).forEach(this::createNodeHandler);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
package org.ethereum.net.server;

import co.rsk.config.RskSystemProperties;
import co.rsk.net.Peer;
import co.rsk.net.NodeID;
import co.rsk.net.Peer;
import co.rsk.net.Status;
import co.rsk.net.messages.*;
import co.rsk.scoring.InetAddressUtils;
Expand All @@ -33,11 +33,14 @@
import org.ethereum.core.Transaction;
import org.ethereum.net.message.ReasonCode;
import org.ethereum.sync.SyncPool;
import org.ethereum.util.SimpleFileWriter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.net.InetAddress;
import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant;
import java.util.*;
Expand Down Expand Up @@ -74,6 +77,8 @@ public class ChannelManagerImpl implements ChannelManager {
private final int maxActivePeers;
private final int maxConnectionsAllowed;
private final int networkCIDR;
private final Path peerListFileDir;
private final SimpleFileWriter fileDataSaver;

private long timeLastLoggedPeers = System.currentTimeMillis();

Expand All @@ -87,6 +92,8 @@ public ChannelManagerImpl(RskSystemProperties config, SyncPool syncPool) {
this.newPeers = new CopyOnWriteArrayList<>();
this.maxConnectionsAllowed = config.maxConnectionsAllowed();
this.networkCIDR = config.networkCIDR();
this.peerListFileDir = config.getLastConnectedPeersFilePath();
fileDataSaver = SimpleFileWriter.getInstance();
}

@Override
Expand All @@ -96,9 +103,28 @@ public void start() {

@Override
public void stop() {
saveActivePeersToFile();
mainWorker.shutdown();
}

private void saveActivePeersToFile() {
if (!activePeers.isEmpty()) {
logger.debug("Shutting down ChannelManagerImpl. Showing list of active peers");

StringBuilder sb = new StringBuilder();
for (Channel peerChannel : activePeers.values()) {
sb.append(peerChannel.getAddress().getCanonicalHostName()).append(":").append(peerChannel.getInetSocketAddress().getPort()).append("\n");
}
logger.debug("Active peer to save: -> {}", sb);

Check failure

Code scanning / CodeQL

Log Injection High

This log entry depends on a
user-provided value
.
try {
fileDataSaver.saveDataIntoFile(sb.toString(), peerListFileDir);
} catch (IOException e) {
logger.error("Error saving active peers to file: {}", e.getMessage());
}
}
}


private void handleNewPeersAndDisconnections() {
this.tryProcessNewPeers();
this.cleanDisconnections();
Expand Down Expand Up @@ -175,6 +201,7 @@ private boolean isRecent(Instant disconnectionTimeout, Instant currentTime) {
}

private void addToActives(Channel peer) {

if (peer.isUsingNewProtocol() || peer.hasEthStatusSucceeded()) {
syncPool.add(peer);
synchronized (activePeersLock) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ public void initChannel(NioSocketChannel ch) {
try {
logger.info("Open {} connection, channel: {}", isInbound() ? "inbound" : "outbound", ch);

if (isInbound()) {
if (isInbound()) {
InetAddress address = ch.remoteAddress().getAddress();
if (channelManager.isRecentlyDisconnected(address)) {
// avoid too frequent connection attempts
Expand Down
52 changes: 52 additions & 0 deletions rskj-core/src/main/java/org/ethereum/util/SimpleFileWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* This file is part of RskJ
* Copyright (C) 2023 RSK Labs Ltd.
* (derived from ethereumJ library, Copyright (c) 2016 <ether.camp>)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* 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 org.ethereum.util;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

public class SimpleFileWriter {
private static final String TMP = ".tmp";
private static SimpleFileWriter instance;

private SimpleFileWriter() {
}

public static SimpleFileWriter getInstance() {
if (instance == null) {
instance = new SimpleFileWriter();
}
return instance;
}

public void saveDataIntoFile(String data, Path filePath) throws IOException {
File tempFile = File.createTempFile(filePath.toString(), TMP);

Check warning

Code scanning / CodeQL

Local information disclosure in a temporary directory Medium

Local information disclosure vulnerability due to use of file readable by other local users.
try (FileWriter writer = new FileWriter(tempFile, false)) {
writer.write(data);
}

Files.move(tempFile.toPath(), filePath, REPLACE_EXISTING);
}
}

1 change: 1 addition & 0 deletions rskj-core/src/main/resources/config/testnet.conf
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ blockchain.config {
}

peer {
usePeersFromLastSession = true

discovery = {

Expand Down
99 changes: 50 additions & 49 deletions rskj-core/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,62 +56,63 @@
</appender>

<!-- Loggers -->
<logger name="execute" level="INFO"/>
<logger name="execute" level="DEBUG"/>
<logger name="blockvalidator" level="INFO"/>
<logger name="blockexecutor" level="INFO"/>
<logger name="general" level="INFO"/>
<logger name="gaspricetracker" level="INFO"/>
<logger name="web3" level="INFO"/>
<logger name="repository" level="INFO"/>
<logger name="blockexecutor" level="DEBUG"/>
<logger name="general" level="DEBUG"/>
<logger name="gaspricetracker" level="DEBUG"/>
<logger name="web3" level="DEBUG"/>
<logger name="repository" level="DEBUG"/>
<logger name="VM" level="ERROR"/>
<logger name="blockqueue" level="INFO"/>
<logger name="io.netty" level="INFO"/>
<logger name="block" level="INFO"/>
<logger name="minerserver" level="INFO"/>
<logger name="txbuilderex" level="INFO"/>
<logger name="pendingstate" level="INFO"/>
<logger name="hsqldb.db" level="INFO"/>
<logger name="TCK-Test" level="INFO"/>
<logger name="db" level="INFO"/>
<logger name="net" level="INFO"/>
<logger name="start" level="INFO"/>
<logger name="cli" level="INFO"/>
<logger name="txs" level="INFO"/>
<logger name="blockqueue" level="DEBUG"/>
<logger name="io.netty" level="DEBUG"/>
<logger name="block" level="DEBUG"/>
<logger name="minerserver" level="DEBUG"/>
<logger name="txbuilderex" level="DEBUG"/>
<logger name="pendingstate" level="DEBUG"/>
<logger name="hsqldb.db" level="DEBUG"/>
<logger name="TCK-Test" level="DEBUG"/>
<logger name="db" level="DEBUG"/>
<logger name="net" level="DEBUG"/>
<logger name="start" level="DEBUG"/>
<logger name="cli" level="DEBUG"/>
<logger name="txs" level="DEBUG"/>
<logger name="gas" level="ERROR"/>
<logger name="main" level="INFO"/>
<logger name="trie" level="INFO"/>
<logger name="peermonitor" level="INFO"/>
<logger name="bridge" level="INFO"/>
<logger name="rlp" level="INFO"/>
<logger name="messagehandler" level="INFO"/>
<logger name="sync" level="INFO"/>
<logger name="BtcToRskClient" level="INFO"/>
<logger name="ui" level="INFO"/>
<logger name="java.nio" level="INFO"/>
<logger name="org.eclipse.jetty" level="INFO"/>
<logger name="main" level="DEBUG"/>
<logger name="trie" level="DEBUG"/>
<logger name="peermonitor" level="DEBUG"/>
<logger name="bridge" level="DEBUG"/>
<logger name="rlp" level="DEBUG"/>
<logger name="messagehandler" level="DEBUG"/>
<logger name="sync" level="DEBUG"/>
<logger name="BtcToRskClient" level="DEBUG"/>
<logger name="ui" level="DEBUG"/>
<logger name="java.nio" level="DEBUG"/>
<logger name="org.eclipse.jetty" level="DEBUG"/>
<logger name="wire" level="INFO"/>
<logger name="BridgeSupport" level="INFO"/>
<logger name="jsonrpc" level="INFO"/>
<logger name="wallet" level="INFO"/>
<logger name="BridgeSupport" level="DEBUG"/>
<logger name="jsonrpc" level="DEBUG"/>
<logger name="wallet" level="DEBUG"/>
<logger name="blockchain" level="INFO"/>
<logger name="blockprocessor" level="INFO"/>
<logger name="asyncblockprocessor" level="INFO"/>
<logger name="state" level="INFO"/>
<logger name="org.bitcoinj" level="INFO"/>
<logger name="metrics" level="INFO"/>
<logger name="messageProcess" level="INFO"/>
<logger name="co.rsk.db.migration.OrchidToUnitrieMigrator" level="INFO"/>
<logger name="co.rsk.db.migration.MissingOrchidStorageKeysProvider" level="INFO"/>
<logger name="blooms" level="INFO"/>
<logger name="triestore" level="INFO" />
<logger name="btcBlockStore" level="INFO" />
<logger name="secp256k1" level="INFO" />
<logger name="altbn128" level="INFO" />
<logger name="co.rsk.net.discovery.PeerExplorer" level="INFO" />
<logger name="co.rsk.net.discovery.NodeChallengeManager" level="INFO" />
<logger name="blockprocessor" level="DEBUG"/>
<logger name="asyncblockprocessor" level="DEBUG"/>
<logger name="state" level="DEBUG"/>
<logger name="org.bitcoinj" level="DEBUG"/>
<logger name="metrics" level="DEBUG"/>
<logger name="messageProcess" level="DEBUG"/>
<logger name="co.rsk.db.migration.OrchidToUnitrieMigrator" level="DEBUG"/>
<logger name="co.rsk.db.migration.MissingOrchidStorageKeysProvider" level="DEBUG"/>
<logger name="blooms" level="DEBUG"/>
<logger name="triestore" level="DEBUG" />
<logger name="btcBlockStore" level="DEBUG" />
<logger name="secp256k1" level="DEBUG" />
<logger name="altbn128" level="DEBUG" />
<logger name="co.rsk.net.discovery.PeerExplorer" level="DEBUG" />
<logger name="co.rsk.net.discovery.NodeChallengeManager" level="DEBUG" />
<logger name="co.rsk.bitcoinj.script.RedeemScriptParserFactory" level="INFO" />

<!-- Use INFO or upper levels for production environments. -->
<logger name="com.googlecode.jsonrpc4j" level="INFO" />
<logger name="com.googlecode.jsonrpc4j" level="DEBUG" />

<!-- Logger for CLI tools -->
<logger name="clitool" level="DEBUG" additivity="false" >
Expand Down
3 changes: 3 additions & 0 deletions rskj-core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ peer {
# Use to connect to specific nodes
active = [ ]

# If true, the node will try to connect to the peers from the last session
usePeersFromLastSession = false

# list of trusted peers the incoming connections is always accepted from. Even if the max amount of connections is reached
# This is used to create a filter of Trusted peers
trusted = [
Expand Down

0 comments on commit 8be6a43

Please sign in to comment.