forked from Qortal/qortal
Various changes
- Added real address to API results - Added group member check to validations - Network changes
This commit is contained in:
parent
8ffb0625a1
commit
adbba0f947
@ -349,10 +349,28 @@ public class Account {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 'effective' minting level, or zero if reward-share does not exist.
|
||||
* Returns reward-share minting address, or unknown if reward-share does not exist.
|
||||
*
|
||||
* @param repository
|
||||
* @param rewardSharePublicKey
|
||||
* @return address or unknown
|
||||
* @throws DataException
|
||||
*/
|
||||
public static String getRewardShareMintingAddress(Repository repository, byte[] rewardSharePublicKey) throws DataException {
|
||||
// Find actual minter address
|
||||
RewardShareData rewardShareData = repository.getAccountRepository().getRewardShare(rewardSharePublicKey);
|
||||
|
||||
if (rewardShareData == null)
|
||||
return "Unknown";
|
||||
|
||||
return rewardShareData.getMinter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 'effective' minting level, or zero if reward-share does not exist.
|
||||
*
|
||||
* @param repository
|
||||
* @param rewardSharePublicKey
|
||||
* @return 0+
|
||||
* @throws DataException
|
||||
*/
|
||||
|
@ -1,7 +1,13 @@
|
||||
package org.qortal.api.model;
|
||||
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.repository.DataException;
|
||||
import org.qortal.repository.RepositoryManager;
|
||||
import org.qortal.repository.Repository;
|
||||
|
||||
import javax.xml.bind.annotation.XmlAccessType;
|
||||
import javax.xml.bind.annotation.XmlAccessorType;
|
||||
import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
// All properties to be converted to JSON via JAXB
|
||||
@XmlAccessorType(XmlAccessType.FIELD)
|
||||
@ -47,4 +53,31 @@ public class ApiOnlineAccount {
|
||||
return this.recipientAddress;
|
||||
}
|
||||
|
||||
public int getMinterLevelFromPublicKey() {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
return Account.getRewardShareEffectiveMintingLevel(repository, this.rewardSharePublicKey);
|
||||
} catch (DataException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getIsMember() {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
return repository.getGroupRepository().memberExists(694, getMinterAddress());
|
||||
} catch (DataException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// JAXB special
|
||||
|
||||
@XmlElement(name = "minterLevel")
|
||||
protected int getMinterLevel() {
|
||||
return getMinterLevelFromPublicKey();
|
||||
}
|
||||
|
||||
@XmlElement(name = "isMinterMember")
|
||||
protected boolean getMinterMember() {
|
||||
return getIsMember();
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import java.math.BigInteger;
|
||||
public class BlockMintingInfo {
|
||||
|
||||
public byte[] minterPublicKey;
|
||||
public String minterAddress;
|
||||
public int minterLevel;
|
||||
public int onlineAccountsCount;
|
||||
public BigDecimal maxDistance;
|
||||
@ -19,5 +20,4 @@ public class BlockMintingInfo {
|
||||
|
||||
public BlockMintingInfo() {
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -542,6 +542,7 @@ public class BlocksResource {
|
||||
}
|
||||
}
|
||||
|
||||
String minterAddress = Account.getRewardShareMintingAddress(repository, blockData.getMinterPublicKey());
|
||||
int minterLevel = Account.getRewardShareEffectiveMintingLevel(repository, blockData.getMinterPublicKey());
|
||||
if (minterLevel == 0)
|
||||
// This may be unavailable when requesting a trimmed block
|
||||
@ -554,6 +555,7 @@ public class BlocksResource {
|
||||
|
||||
BlockMintingInfo blockMintingInfo = new BlockMintingInfo();
|
||||
blockMintingInfo.minterPublicKey = blockData.getMinterPublicKey();
|
||||
blockMintingInfo.minterAddress = minterAddress;
|
||||
blockMintingInfo.minterLevel = minterLevel;
|
||||
blockMintingInfo.onlineAccountsCount = blockData.getOnlineAccountsCount();
|
||||
blockMintingInfo.maxDistance = new BigDecimal(block.MAX_DISTANCE);
|
||||
@ -887,5 +889,4 @@ public class BlocksResource {
|
||||
throw ApiExceptionFactory.INSTANCE.createException(request, ApiError.REPOSITORY_ISSUE, e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -145,7 +145,7 @@ public class Block {
|
||||
|
||||
private final Account recipientAccount;
|
||||
private final AccountData recipientAccountData;
|
||||
|
||||
|
||||
final BlockChain blockChain = BlockChain.getInstance();
|
||||
|
||||
ExpandedAccount(Repository repository, RewardShareData rewardShareData) throws DataException {
|
||||
@ -414,6 +414,21 @@ public class Block {
|
||||
});
|
||||
}
|
||||
|
||||
// After feature trigger, remove any online accounts that are not minter group member
|
||||
if (height >= BlockChain.getInstance().getGroupMemberCheckHeight()) {
|
||||
onlineAccounts.removeIf(a -> {
|
||||
try {
|
||||
int groupId = BlockChain.getInstance().getMintingGroupId();
|
||||
String address = Account.getRewardShareMintingAddress(repository, a.getPublicKey());
|
||||
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);
|
||||
return !isMinterGroupMember;
|
||||
} catch (DataException e) {
|
||||
// Something went wrong, so remove the account
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (onlineAccounts.isEmpty()) {
|
||||
LOGGER.debug("No online accounts - not even our own?");
|
||||
return null;
|
||||
@ -721,19 +736,19 @@ public class Block {
|
||||
List<ExpandedAccount> expandedAccounts = new ArrayList<>();
|
||||
|
||||
for (RewardShareData rewardShare : this.cachedOnlineRewardShares) {
|
||||
if (this.getBlockData().getHeight() < BlockChain.getInstance().getFixBatchRewardHeight()) {
|
||||
int groupId = BlockChain.getInstance().getMintingGroupId();
|
||||
String address = rewardShare.getMinter();
|
||||
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);
|
||||
|
||||
if (this.getBlockData().getHeight() < BlockChain.getInstance().getFixBatchRewardHeight())
|
||||
expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
|
||||
|
||||
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight() && isMinterGroupMember)
|
||||
expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
|
||||
}
|
||||
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight()) {
|
||||
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(BlockChain.getInstance().getMintingGroupId(), rewardShare.getMinter());
|
||||
if (isMinterGroupMember) {
|
||||
expandedAccounts.add(new ExpandedAccount(repository, rewardShare));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.cachedExpandedAccounts = expandedAccounts;
|
||||
LOGGER.trace(() -> String.format("Online reward-shares after expanded accounts %s", this.cachedOnlineRewardShares));
|
||||
|
||||
return this.cachedExpandedAccounts;
|
||||
}
|
||||
@ -1143,8 +1158,17 @@ public class Block {
|
||||
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getOnlineAccountMinterLevelValidationHeight()) {
|
||||
List<ExpandedAccount> expandedAccounts = this.getExpandedAccounts();
|
||||
for (ExpandedAccount account : expandedAccounts) {
|
||||
int groupId = BlockChain.getInstance().getMintingGroupId();
|
||||
String address = account.getMintingAccount().getAddress();
|
||||
boolean isMinterGroupMember = repository.getGroupRepository().memberExists(groupId, address);
|
||||
|
||||
if (account.getMintingAccount().getEffectiveMintingLevel() == 0)
|
||||
return ValidationResult.ONLINE_ACCOUNTS_INVALID;
|
||||
|
||||
if (this.getBlockData().getHeight() >= BlockChain.getInstance().getFixBatchRewardHeight()) {
|
||||
if (!isMinterGroupMember)
|
||||
return ValidationResult.ONLINE_ACCOUNTS_INVALID;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1273,6 +1297,7 @@ public class Block {
|
||||
|
||||
// Online Accounts
|
||||
ValidationResult onlineAccountsResult = this.areOnlineAccountsValid();
|
||||
LOGGER.trace("Accounts valid = {}", onlineAccountsResult);
|
||||
if (onlineAccountsResult != ValidationResult.OK)
|
||||
return onlineAccountsResult;
|
||||
|
||||
@ -1361,7 +1386,7 @@ public class Block {
|
||||
// Check transaction can even be processed
|
||||
validationResult = transaction.isProcessable();
|
||||
if (validationResult != Transaction.ValidationResult.OK) {
|
||||
LOGGER.info(String.format("Error during transaction validation, tx %s: %s", Base58.encode(transactionData.getSignature()), validationResult.name()));
|
||||
LOGGER.debug(String.format("Error during transaction validation, tx %s: %s", Base58.encode(transactionData.getSignature()), validationResult.name()));
|
||||
return ValidationResult.TRANSACTION_INVALID;
|
||||
}
|
||||
|
||||
@ -1562,6 +1587,7 @@ public class Block {
|
||||
this.blockData.setHeight(blockchainHeight + 1);
|
||||
|
||||
LOGGER.trace(() -> String.format("Processing block %d", this.blockData.getHeight()));
|
||||
LOGGER.trace(() -> String.format("Online Reward Shares in process %s", this.cachedOnlineRewardShares));
|
||||
|
||||
if (this.blockData.getHeight() > 1) {
|
||||
|
||||
@ -2280,7 +2306,6 @@ public class Block {
|
||||
// Select the correct set of share bins based on block height
|
||||
List<AccountLevelShareBin> accountLevelShareBinsForBlock = (this.blockData.getHeight() >= BlockChain.getInstance().getSharesByLevelV2Height()) ?
|
||||
BlockChain.getInstance().getAccountLevelShareBinsV2() : BlockChain.getInstance().getAccountLevelShareBinsV1();
|
||||
|
||||
// Determine reward candidates based on account level
|
||||
// This needs a deep copy, so the shares can be modified when tiers aren't activated yet
|
||||
List<AccountLevelShareBin> accountLevelShareBins = new ArrayList<>();
|
||||
@ -2570,9 +2595,11 @@ public class Block {
|
||||
return;
|
||||
|
||||
int minterLevel = Account.getRewardShareEffectiveMintingLevel(this.repository, this.getMinter().getPublicKey());
|
||||
String minterAddress = Account.getRewardShareMintingAddress(this.repository, this.getMinter().getPublicKey());
|
||||
|
||||
LOGGER.debug(String.format("======= BLOCK %d (%.8s) =======", this.getBlockData().getHeight(), Base58.encode(this.getSignature())));
|
||||
LOGGER.debug(String.format("Timestamp: %d", this.getBlockData().getTimestamp()));
|
||||
LOGGER.debug(String.format("Minter address: %s", minterAddress));
|
||||
LOGGER.debug(String.format("Minter level: %d", minterLevel));
|
||||
LOGGER.debug(String.format("Online accounts: %d", this.getBlockData().getOnlineAccountsCount()));
|
||||
LOGGER.debug(String.format("AT count: %d", this.getBlockData().getATCount()));
|
||||
|
@ -1,8 +1,11 @@
|
||||
package org.qortal.data.block;
|
||||
|
||||
import com.google.common.primitives.Bytes;
|
||||
import org.qortal.account.Account;
|
||||
import org.qortal.block.BlockChain;
|
||||
import org.qortal.crypto.Crypto;
|
||||
import org.qortal.repository.DataException;
|
||||
import org.qortal.repository.Repository;
|
||||
import org.qortal.repository.RepositoryManager;
|
||||
import org.qortal.settings.Settings;
|
||||
import org.qortal.utils.NTP;
|
||||
|
||||
@ -224,7 +227,7 @@ public class BlockData implements Serializable {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public boolean isTrimmed() {
|
||||
long onlineAccountSignaturesTrimmedTimestamp = NTP.getTime() - BlockChain.getInstance().getOnlineAccountSignaturesMaxLifetime();
|
||||
long currentTrimmableTimestamp = NTP.getTime() - Settings.getInstance().getAtStatesMaxLifetime();
|
||||
@ -232,11 +235,31 @@ public class BlockData implements Serializable {
|
||||
return blockTimestamp < onlineAccountSignaturesTrimmedTimestamp && blockTimestamp < currentTrimmableTimestamp;
|
||||
}
|
||||
|
||||
public String getMinterAddressFromPublicKey() {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
return Account.getRewardShareMintingAddress(repository, this.minterPublicKey);
|
||||
} catch (DataException e) {
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
public int getMinterLevelFromPublicKey() {
|
||||
try (final Repository repository = RepositoryManager.getRepository()) {
|
||||
return Account.getRewardShareEffectiveMintingLevel(repository, this.minterPublicKey);
|
||||
} catch (DataException e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// JAXB special
|
||||
|
||||
@XmlElement(name = "minterAddress")
|
||||
protected String getMinterAddress() {
|
||||
return Crypto.toAddress(this.minterPublicKey);
|
||||
return getMinterAddressFromPublicKey();
|
||||
}
|
||||
|
||||
@XmlElement(name = "minterLevel")
|
||||
protected int getMinterLevel() {
|
||||
return getMinterLevelFromPublicKey();
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public enum Handshake {
|
||||
|
||||
String versionString = helloMessage.getVersionString();
|
||||
|
||||
Matcher matcher = peer.VERSION_PATTERN.matcher(versionString);
|
||||
Matcher matcher = Peer.VERSION_PATTERN.matcher(versionString);
|
||||
if (!matcher.lookingAt()) {
|
||||
LOGGER.debug(() -> String.format("Peer %s sent invalid HELLO version string '%s'", peer, versionString));
|
||||
return null;
|
||||
@ -71,7 +71,7 @@ public enum Handshake {
|
||||
|
||||
// Ensure the peer is running at least the version specified in MIN_PEER_VERSION
|
||||
if (!peer.isAtLeastVersion(MIN_PEER_VERSION)) {
|
||||
LOGGER.debug(String.format("Ignoring peer %s because it is on an old version (%s)", peer, versionString));
|
||||
LOGGER.debug("Ignoring peer {} because it is on an old version ({})", peer, versionString);
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ public enum Handshake {
|
||||
// Ensure the peer is running at least the minimum version allowed for connections
|
||||
final String minPeerVersion = Settings.getInstance().getMinPeerVersion();
|
||||
if (!peer.isAtLeastVersion(minPeerVersion)) {
|
||||
LOGGER.debug(String.format("Ignoring peer %s because it is on an old version (%s)", peer, versionString));
|
||||
LOGGER.debug("Ignoring peer {} because it is on an old version ({})", peer, versionString);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -106,7 +106,7 @@ public enum Handshake {
|
||||
byte[] peersPublicKey = challengeMessage.getPublicKey();
|
||||
byte[] peersChallenge = challengeMessage.getChallenge();
|
||||
|
||||
// If public key matches our public key then we've connected to self
|
||||
// If public key matches our public key, then we've connected to self
|
||||
byte[] ourPublicKey = Network.getInstance().getOurPublicKey();
|
||||
if (Arrays.equals(ourPublicKey, peersPublicKey)) {
|
||||
// If outgoing connection then record destination as self so we don't try again
|
||||
@ -121,11 +121,11 @@ public enum Handshake {
|
||||
peer.disconnect("failed to send CHALLENGE to self");
|
||||
|
||||
/*
|
||||
* We return CHALLENGE here to prevent us from closing connection. Closing
|
||||
* connection currently preempts remote end from reading any pending messages,
|
||||
* We return the CHALLENGE here to prevent us from closing the connection.
|
||||
* Closing the connection currently preempts the remote end from reading any pending messages,
|
||||
* specifically the CHALLENGE message we just sent above. When our 'remote'
|
||||
* outbound counterpart reads our message, they will close both connections.
|
||||
* Failing that, our connection will timeout or a future handshake error will
|
||||
* Failing that, our connection will time out or a future handshake error will
|
||||
* occur.
|
||||
*/
|
||||
return CHALLENGE;
|
||||
@ -135,7 +135,7 @@ public enum Handshake {
|
||||
// Are we already connected to this peer?
|
||||
Peer existingPeer = Network.getInstance().getHandshakedPeerWithPublicKey(peersPublicKey);
|
||||
if (existingPeer != null) {
|
||||
LOGGER.info(() -> String.format("We already have a connection with peer %s - discarding", peer));
|
||||
LOGGER.debug(() -> String.format("We already have a connection with peer %s - discarding", peer));
|
||||
// Handshake failure - caller will deal with disconnect
|
||||
return null;
|
||||
}
|
||||
@ -148,7 +148,7 @@ public enum Handshake {
|
||||
|
||||
@Override
|
||||
public void action(Peer peer) {
|
||||
// Send challenge
|
||||
// Send a challenge
|
||||
byte[] publicKey = Network.getInstance().getOurPublicKey();
|
||||
byte[] challenge = peer.getOurChallenge();
|
||||
|
||||
@ -254,16 +254,17 @@ public enum Handshake {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(Handshake.class);
|
||||
|
||||
/** Maximum allowed difference between peer's reported timestamp and when they connected, in milliseconds. */
|
||||
/** The Maximum allowed difference between peer's reported timestamp and when they connected, in milliseconds. */
|
||||
private static final long MAX_TIMESTAMP_DELTA = 30 * 1000L; // ms
|
||||
|
||||
private static final long PEER_VERSION_131 = 0x0100030001L;
|
||||
|
||||
/** Minimum peer version that we are allowed to communicate with */
|
||||
private static final String MIN_PEER_VERSION = "4.1.1";
|
||||
private static final String MIN_PEER_VERSION = "4.6.5";
|
||||
|
||||
private static final int POW_BUFFER_SIZE_PRE_131 = 8 * 1024 * 1024; // bytes
|
||||
private static final int POW_DIFFICULTY_PRE_131 = 8; // leading zero bits
|
||||
|
||||
// Can always be made harder in the future...
|
||||
private static final int POW_BUFFER_SIZE_POST_131 = 2 * 1024 * 1024; // bytes
|
||||
private static final int POW_DIFFICULTY_POST_131 = 2; // leading zero bits
|
||||
@ -275,12 +276,11 @@ public enum Handshake {
|
||||
|
||||
public final MessageType expectedMessageType;
|
||||
|
||||
private Handshake(MessageType expectedMessageType) {
|
||||
Handshake(MessageType expectedMessageType) {
|
||||
this.expectedMessageType = expectedMessageType;
|
||||
}
|
||||
|
||||
public abstract Handshake onMessage(Peer peer, Message message);
|
||||
|
||||
public abstract void action(Peer peer);
|
||||
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ public class Network {
|
||||
"node.qortal.ru", "node2.qortal.ru", "node3.qortal.ru", "node.qortal.uk", "node22.qortal.org",
|
||||
"cinfu1.crowetic.com", "node.cwd.systems", "bootstrap.cwd.systems", "node1.qortalnodes.live",
|
||||
"node2.qortalnodes.live", "node3.qortalnodes.live", "node4.qortalnodes.live", "node5.qortalnodes.live",
|
||||
"node6.qortalnodes.live", "node7.qortalnodes.live", "node8.qortalnodes.live"
|
||||
"node.qortalnodes.live", "qortex.live",
|
||||
};
|
||||
|
||||
private static final long NETWORK_EPC_KEEPALIVE = 5L; // seconds
|
||||
@ -149,7 +149,7 @@ public class Network {
|
||||
|
||||
private final Lock mergePeersLock = new ReentrantLock();
|
||||
|
||||
private List<String> ourExternalIpAddressHistory = new ArrayList<>();
|
||||
private final List<String> ourExternalIpAddressHistory = new ArrayList<>();
|
||||
private String ourExternalIpAddress = null;
|
||||
private int ourExternalPort = Settings.getInstance().getListenPort();
|
||||
|
||||
@ -167,7 +167,7 @@ public class Network {
|
||||
ExecutorService networkExecutor = new ThreadPoolExecutor(2,
|
||||
Settings.getInstance().getMaxNetworkThreadPoolSize(),
|
||||
NETWORK_EPC_KEEPALIVE, TimeUnit.SECONDS,
|
||||
new SynchronousQueue<Runnable>(),
|
||||
new SynchronousQueue<>(),
|
||||
new NamedThreadFactory("Network-EPC", Settings.getInstance().getNetworkThreadPriority()));
|
||||
networkEPC = new NetworkProcessor(networkExecutor);
|
||||
}
|
||||
@ -314,7 +314,7 @@ public class Network {
|
||||
|
||||
public List<Peer> getImmutableConnectedDataPeers() {
|
||||
return this.getImmutableConnectedPeers().stream()
|
||||
.filter(p -> p.isDataPeer())
|
||||
.filter(Peer::isDataPeer)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@ -346,7 +346,7 @@ public class Network {
|
||||
public boolean requestDataFromPeer(String peerAddressString, byte[] signature) {
|
||||
if (peerAddressString != null) {
|
||||
PeerAddress peerAddress = PeerAddress.fromString(peerAddressString);
|
||||
PeerData peerData = null;
|
||||
PeerData peerData;
|
||||
|
||||
// Reuse an existing PeerData instance if it's already in the known peers list
|
||||
synchronized (this.allKnownPeers) {
|
||||
@ -370,9 +370,9 @@ public class Network {
|
||||
|
||||
// Check if we're already connected to and handshaked with this peer
|
||||
Peer connectedPeer = this.getImmutableConnectedPeers().stream()
|
||||
.filter(p -> p.getPeerData().getAddress().equals(peerAddress))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
.filter(p -> p.getPeerData().getAddress().equals(peerAddress))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
|
||||
boolean isConnected = (connectedPeer != null);
|
||||
|
||||
@ -710,7 +710,7 @@ public class Network {
|
||||
return true;
|
||||
}
|
||||
|
||||
private Peer getConnectablePeer(final Long now) throws InterruptedException {
|
||||
private Peer getConnectablePeer(final Long now) {
|
||||
// We can't block here so use tryRepository(). We don't NEED to connect a new peer.
|
||||
try (Repository repository = RepositoryManager.tryRepository()) {
|
||||
if (repository == null) {
|
||||
@ -807,7 +807,7 @@ public class Network {
|
||||
// Find peers that have reached their maximum connection age, and disconnect them
|
||||
List<Peer> peersToDisconnect = this.getImmutableConnectedPeers().stream()
|
||||
.filter(peer -> !peer.isSyncInProgress())
|
||||
.filter(peer -> peer.hasReachedMaxConnectionAge())
|
||||
.filter(Peer::hasReachedMaxConnectionAge)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (peersToDisconnect != null && !peersToDisconnect.isEmpty()) {
|
||||
@ -996,9 +996,9 @@ public class Network {
|
||||
}
|
||||
|
||||
// Add to per-message thread count (first initializing to 0 if not already present)
|
||||
threadsPerMessageType.computeIfAbsent(message.getType(), key -> 0);
|
||||
threadsPerMessageType.putIfAbsent(message.getType(), 0);
|
||||
threadsPerMessageType.computeIfPresent(message.getType(), (key, value) -> value + 1);
|
||||
|
||||
|
||||
// Add to total thread count
|
||||
synchronized (this) {
|
||||
totalThreadCount++;
|
||||
@ -1037,7 +1037,7 @@ public class Network {
|
||||
}
|
||||
|
||||
// Remove from per-message thread count (first initializing to 0 if not already present)
|
||||
threadsPerMessageType.computeIfAbsent(message.getType(), key -> 0);
|
||||
threadsPerMessageType.putIfAbsent(message.getType(), 0);
|
||||
threadsPerMessageType.computeIfPresent(message.getType(), (key, value) -> value - 1);
|
||||
|
||||
// Remove from total thread count
|
||||
@ -1135,7 +1135,7 @@ public class Network {
|
||||
Peer existingPeer = getHandshakedPeerWithPublicKey(peer.getPeersPublicKey());
|
||||
// NOTE: actual object reference compare, not Peer.equals()
|
||||
if (existingPeer != peer) {
|
||||
LOGGER.info("[{}] We already have a connection with peer {} - discarding",
|
||||
LOGGER.debug("[{}] We already have a connection with peer {} - discarding",
|
||||
peer.getPeerConnectionId(), peer);
|
||||
peer.disconnect("existing connection");
|
||||
return;
|
||||
@ -1216,29 +1216,7 @@ public class Network {
|
||||
* Returns PEERS message made from peers we've connected to recently, and this node's details
|
||||
*/
|
||||
public Message buildPeersMessage(Peer peer) {
|
||||
List<PeerData> knownPeers = this.getAllKnownPeers();
|
||||
|
||||
// Filter out peers that we've not connected to ever or within X milliseconds
|
||||
final long connectionThreshold = NTP.getTime() - RECENT_CONNECTION_THRESHOLD;
|
||||
Predicate<PeerData> notRecentlyConnected = peerData -> {
|
||||
final Long lastAttempted = peerData.getLastAttempted();
|
||||
final Long lastConnected = peerData.getLastConnected();
|
||||
|
||||
if (lastAttempted == null || lastConnected == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lastConnected < lastAttempted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lastConnected < connectionThreshold) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
knownPeers.removeIf(notRecentlyConnected);
|
||||
final var knownPeers = getPeerData();
|
||||
|
||||
List<PeerAddress> peerAddresses = new ArrayList<>();
|
||||
|
||||
@ -1262,6 +1240,29 @@ public class Network {
|
||||
return new PeersV2Message(peerAddresses);
|
||||
}
|
||||
|
||||
private List<PeerData> getPeerData() {
|
||||
List<PeerData> knownPeers = this.getAllKnownPeers();
|
||||
|
||||
// Filter out peers that we've not connected to ever or within X milliseconds
|
||||
final long connectionThreshold = NTP.getTime() - RECENT_CONNECTION_THRESHOLD;
|
||||
Predicate<PeerData> notRecentlyConnected = peerData -> {
|
||||
final Long lastAttempted = peerData.getLastAttempted();
|
||||
final Long lastConnected = peerData.getLastConnected();
|
||||
|
||||
if (lastAttempted == null || lastConnected == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (lastConnected < lastAttempted) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return lastConnected < connectionThreshold;
|
||||
};
|
||||
knownPeers.removeIf(notRecentlyConnected);
|
||||
return knownPeers;
|
||||
}
|
||||
|
||||
/** Builds either (legacy) HeightV2Message or (newer) BlockSummariesV2Message, depending on peer version.
|
||||
*
|
||||
* @return Message, or null if DataException was thrown.
|
||||
@ -1328,7 +1329,7 @@ public class Network {
|
||||
return;
|
||||
}
|
||||
String host = parts[0];
|
||||
|
||||
|
||||
try {
|
||||
InetAddress addr = InetAddress.getByName(host);
|
||||
if (addr.isAnyLocalAddress() || addr.isSiteLocalAddress()) {
|
||||
@ -1369,12 +1370,12 @@ public class Network {
|
||||
for (int i = size-1; i >= 0; i--) {
|
||||
String reading = ipAddressHistory.get(i);
|
||||
if (lastReading != null) {
|
||||
if (Objects.equals(reading, lastReading)) {
|
||||
if (Objects.equals(reading, lastReading)) {
|
||||
consecutiveReadings++;
|
||||
}
|
||||
else {
|
||||
consecutiveReadings = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
consecutiveReadings = 0;
|
||||
}
|
||||
}
|
||||
lastReading = reading;
|
||||
}
|
||||
@ -1515,12 +1516,8 @@ public class Network {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (peerData.getLastConnected() == null
|
||||
|| peerData.getLastConnected() > now - OLD_PEER_CONNECTION_PERIOD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return peerData.getLastConnected() == null
|
||||
|| peerData.getLastConnected() > now - OLD_PEER_CONNECTION_PERIOD;
|
||||
};
|
||||
|
||||
// Disregard peers that are NOT 'old'
|
||||
@ -1655,7 +1652,7 @@ public class Network {
|
||||
|
||||
// Stop processing threads
|
||||
try {
|
||||
if (!this.networkEPC.shutdown(5000)) {
|
||||
if (!this.networkEPC.shutdown(10000)) {
|
||||
LOGGER.warn("Network threads failed to terminate");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
@ -1667,5 +1664,4 @@ public class Network {
|
||||
peer.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user