use of neo.network.model.RemoteNodeData in project neo-java by coranos.
the class LocalControllerNode method onVersion.
/**
* when a "version" message is received, update the peer's connection phase to
* be "acknowledged" and set it's version to be the user agent in the payload.
*
* @param peer
* the peer that sent the message.
* @param message
* the message.
*/
private void onVersion(final RemoteNodeControllerRunnable peer, final Message message) {
if (stopped) {
return;
}
final RemoteNodeData data = peer.getData();
synchronized (data) {
final VersionPayload payload = message.getPayload(VersionPayload.class);
data.setVersion(payload.userAgent);
final long blockHeight = payload.startHeight.asLong();
data.setBlockHeight(blockHeight);
data.setLastMessageTimestamp(System.currentTimeMillis());
if (blockHeight > localNodeData.getBlockchainBlockHeight()) {
localNodeData.setBlockchainBlockHeight(blockHeight);
}
}
synchronized (RemoteNodeData.class) {
data.setConnectionPhase(NodeConnectionPhaseEnum.ACKNOWLEDGED);
}
final boolean stalledBlockchain = isStalledBlockchain(data);
if (stalledBlockchain) {
if (LOG.isDebugEnabled()) {
final String errorMessage = "recycling node {} with version {}" + " and stalled blockheight {} where our blockheight is {}";
final long blockCount = localNodeData.getBlockDb().getBlockCount();
LOG.debug(errorMessage, data.getHostAddress(), data.getVersion(), data.getBlockHeight(), blockCount);
}
data.setGoodPeer(false);
}
notifyNodeDataChangeListeners();
}
use of neo.network.model.RemoteNodeData in project neo-java by coranos.
the class LocalControllerNodeRefreshRunnable method run.
@Override
public void run() {
final LocalNodeData localNodeData = localControllerNode.getLocalNodeData();
final long prevSleepTime = 0;
try {
if (LOG.isDebugEnabled()) {
LOG.debug("STARTED refreshThread");
}
while (!stop) {
System.gc();
if (LOG.isTraceEnabled()) {
LOG.trace("INTERIM refreshThread");
}
final List<RemoteNodeData> allPeerDataList = new ArrayList<>();
final List<RemoteNodeData> activePeerDataList = new ArrayList<>();
localControllerNode.addPeerDataSetToList(allPeerDataList);
Collections.shuffle(allPeerDataList);
activePeerDataList.addAll(allPeerDataList);
retainOnlyActiveAndAcknowledgedPeers(activePeerDataList);
if (activePeerDataList.size() > localNodeData.getActiveThreadCount()) {
activePeerDataList.subList(localNodeData.getActiveThreadCount(), activePeerDataList.size()).clear();
}
if (!activePeerDataList.isEmpty()) {
if (activePeerDataList.size() == localNodeData.getActiveThreadCount()) {
activePeerDataList.remove(0).setGoodPeer(false);
}
}
for (final RemoteNodeData data : activePeerDataList) {
LOG.trace("refreshThread {} isGoodPeer:{}, isAcknowledgedPeer {}, getQueueDepth {}", data.getTcpAddressAndPortString(), data.isGoodPeer(), data.isAcknowledgedPeer(), data.getQueueDepth());
if (data.isGoodPeer()) {
if (data.isAcknowledgedPeer()) {
if (data.getQueueDepth() == 0) {
if (isReadyForSend(data, CommandEnum.GETADDR)) {
LocalNodeDataSynchronizedUtil.requestAddresses(localNodeData, data);
}
if (TimerUtil.getTimerData(data.getTimersMap(), CommandEnum.GETDATA, InventoryType.BLOCK.name().toLowerCase()).isReadyForSend()) {
LocalNodeDataSynchronizedUtil.requestBlocks(localNodeData, data);
}
if (isReadyForSend(data, CommandEnum.GETHEADERS)) {
LocalNodeDataSynchronizedUtil.requestHeaders(localNodeData, data);
sent(data, CommandEnum.GETHEADERS);
}
}
}
}
}
for (final RemoteNodeData data : allPeerDataList) {
boolean retry = false;
if (data.getConnectionPhase().equals(NodeConnectionPhaseEnum.UNKNOWN)) {
retry = true;
}
final List<RemoteNodeData> checkActivePeerDataList = new ArrayList<>();
localControllerNode.addPeerDataSetToList(checkActivePeerDataList);
retainOnlyActiveAndAcknowledgedPeers(checkActivePeerDataList);
final int peerDataSetSize = checkActivePeerDataList.size();
if (data.getConnectionPhase().equals(NodeConnectionPhaseEnum.INACTIVE)) {
if (peerDataSetSize < (localNodeData.getActiveThreadCount() - 1)) {
retry = true;
}
}
if (retry) {
try {
if (LOG.isDebugEnabled()) {
LOG.debug("refreshThread {} retrying node with phase {}", data.getTcpAddressAndPortString(), data.getConnectionPhase());
}
localControllerNode.addRemoteNodeDataToPool(data);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
}
if (TimerUtil.getTimerData(localNodeData.getTimersMap(), TimerTypeEnum.VERIFY, "headers").isReadyForSend()) {
LocalNodeDataSynchronizedUtil.verifyUnverifiedHeaders(localNodeData);
}
if (TimerUtil.getTimerData(localNodeData.getTimersMap(), TimerTypeEnum.VERIFY, "blocks").isReadyForSend()) {
LocalNodeDataSynchronizedUtil.verifyUnverifiedBlocks(localNodeData);
}
if (TimerUtil.getTimerData(localNodeData.getTimersMap(), TimerTypeEnum.REFRESH, "block-file-size").isReadyForSend()) {
LocalNodeDataSynchronizedUtil.refreshBlockFileSize(localNodeData);
}
if (TimerUtil.getTimerData(localNodeData.getTimersMap(), TimerTypeEnum.REFRESH, "block-height-city-of-zion").isReadyForSend()) {
LocalNodeDataSynchronizedUtil.refreshCityOfZionBlockHeight(localNodeData);
}
localControllerNode.notifyNodeDataChangeListeners();
final long currTime = System.currentTimeMillis();
final long sleepMs = Math.min(currTime - prevSleepTime, REFRESH_THREAD_MAX_MS);
try {
if (LOG.isDebugEnabled()) {
LOG.debug("STARTED refreshThread sleep for {} ms", sleepMs);
}
Thread.sleep(sleepMs);
if (LOG.isDebugEnabled()) {
LOG.debug("SUCCESS refreshThread sleep for {} ms", sleepMs);
}
} catch (final InterruptedException e) {
throw new RuntimeException(e);
}
}
} catch (final Exception e) {
LOG.error("FAILURE refreshThread", e);
return;
}
if (LOG.isDebugEnabled()) {
LOG.debug("SUCCESS refreshThread");
}
}
use of neo.network.model.RemoteNodeData in project neo-java by coranos.
the class RpcServerUtil method onGetConnectionCount.
/**
* responds to a "getconnectioncount" command.
*
* @param controller
* the controller to use.
* @param id
* the request id to use.
* @return the response.
*/
private static JSONObject onGetConnectionCount(final LocalControllerNode controller, final int id) {
int connectionCount = 0;
synchronized (controller) {
final LocalNodeData localNodeData = controller.getLocalNodeData();
synchronized (localNodeData) {
final List<RemoteNodeData> peerDataList = new ArrayList<>();
controller.addPeerDataSetToList(peerDataList);
for (final RemoteNodeData data : peerDataList) {
if (data.getConnectionPhase() == NodeConnectionPhaseEnum.ACKNOWLEDGED) {
connectionCount++;
}
}
}
}
final JSONObject response = new JSONObject();
response.put(RESULT, connectionCount);
response.put(ID, id);
response.put(JSONRPC, VERSION_2_0);
return response;
}
use of neo.network.model.RemoteNodeData in project neo-java by coranos.
the class LocalControllerNode method loadNodeFile.
/**
* loads the node file.
*
* @param nodeFile
* the node file to load.
*/
private void loadNodeFile(final File nodeFile) {
if (stopped) {
return;
}
try {
if (!nodeFile.exists()) {
LOG.error("FAILURE loadNodeFile, file does not exist: {}", nodeFile.getCanonicalPath());
return;
}
final JSONObject goodNodes = new JSONObject(FileUtils.readFileToString(nodeFile, Charset.defaultCharset()));
final JSONArray goodPeers = goodNodes.getJSONArray(GOOD_PEERS);
for (int ix = 0; ix < goodPeers.length(); ix++) {
final JSONObject goodPeer = goodPeers.getJSONObject(ix);
final String addressName = goodPeer.getString(ADDRESS);
final int port = goodPeer.getInt(PORT);
final InetAddress address = InetAddress.getByName(addressName);
final InetSocketAddress addressAndPort = new InetSocketAddress(address, port);
final RemoteNodeData data = getNewRemoteNodeData();
synchronized (RemoteNodeData.class) {
data.setConnectionPhase(NodeConnectionPhaseEnum.UNKNOWN);
}
data.setTcpAddressAndPort(addressAndPort);
addRemoteNodeDataToPool(data);
}
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
use of neo.network.model.RemoteNodeData in project neo-java by coranos.
the class LocalControllerNode method onSocketClose.
/**
* do something when a peer closes it's socket.
*
* @param peer
* the peer that closed the socket.
*/
public void onSocketClose(final RemoteNodeControllerRunnable peer) {
if (stopped) {
return;
}
final RemoteNodeData data = peer.getData();
final String version;
synchronized (data) {
version = data.getVersion();
}
if (version != null) {
LOG.debug("OnSocketClose {} {}", data.getTcpAddressAndPortString(), version);
}
synchronized (RemoteNodeData.class) {
if (version != null) {
data.setConnectionPhase(NodeConnectionPhaseEnum.INACTIVE);
} else {
data.setConnectionPhase(NodeConnectionPhaseEnum.REFUSED);
}
}
synchronized (data) {
data.setLastMessageTimestamp(System.currentTimeMillis());
}
notifyNodeDataChangeListeners();
}
Aggregations