use of neo.network.model.LocalNodeData in project neo-java by coranos.
the class TestVm method testTransaction.
private void testTransaction(final long blockHeight, final int txIx) {
final LocalNodeData localNodeData = CONTROLLER.getLocalNodeData();
final BlockDb blockDb = localNodeData.getBlockDb();
final Block block = blockDb.getFullBlockFromHeight(blockHeight);
final int maxTxIx = block.getTransactionList().size();
final Transaction tx = block.getTransactionList().get(txIx);
final long maxIndex = blockDb.getHeaderOfBlockWithMaxIndex().getIndexAsLong();
LOG.info("STARTED block {} of {} tx {} of {} : {} {}", blockHeight, maxIndex, txIx, maxTxIx, tx.type, tx.getHash());
final ScriptVerificationResultEnum verifyScriptsResult = VerifyScriptUtil.verifyScripts(blockDb, tx);
if (!verifyScriptsResult.equals(ScriptVerificationResultEnum.PASS)) {
LOG.error("FAILURE block {} of {} tx {} of {} : {} {} : {}", blockHeight, maxIndex, txIx, maxTxIx, tx.type, tx.getHash(), verifyScriptsResult);
throw new RuntimeException("script failed : " + verifyScriptsResult);
} else {
LOG.info("SUCCESS block {} of {} tx {} of {} : {} {}", blockHeight, maxIndex, txIx, maxTxIx, tx.type, tx.getHash());
}
}
use of neo.network.model.LocalNodeData in project neo-java by coranos.
the class BlockImportExportUtil method importBlocks.
/**
* imports the blocks from the file.
*
* @param controller
* the controller.
*/
public static void importBlocks(final LocalControllerNode controller) {
final LocalNodeData localNodeData = controller.getLocalNodeData();
final BlockDb blockDb = localNodeData.getBlockDb();
try (OutputStream statsFileOut = new FileOutputStream(localNodeData.getChainExportStatsFileName());
PrintWriter statsWriter = new PrintWriter(statsFileOut, true)) {
statsWriter.println(OPEN_BRACKET);
long maxIndex = 0;
try (InputStream fileIn = new FileInputStream(localNodeData.getChainExportDataFileName());
BufferedInputStream buffIn = new BufferedInputStream(fileIn, 1024 * 1024 * 32);
DataInputStream in = new DataInputStream(buffIn)) {
final byte[] maxIndexBa = new byte[UInt32.SIZE];
in.read(maxIndexBa);
if (LOG.isTraceEnabled()) {
LOG.info("import maxIndexBa asread {}", Hex.encode(maxIndexBa));
}
ArrayUtils.reverse(maxIndexBa);
maxIndex = new UInt32(maxIndexBa).asLong();
LOG.info("started import {}", INTEGER_FORMAT.format(maxIndex));
long startMs = -1;
long interimBlocks = 0;
long interimBytes = 0;
final long[] interimTx = new long[TransactionType.values().length];
final long[] interimTxNetworkFees = new long[TransactionType.values().length];
long totalTx = 0;
final Map<String, Long> numBlocksByTxCountMap = new TreeMap<>();
@SuppressWarnings("unchecked") final Set<UInt160>[] activeAccountSet = new Set[TransactionType.values().length];
for (int txOrdinal = 0; txOrdinal < activeAccountSet.length; txOrdinal++) {
activeAccountSet[txOrdinal] = new TreeSet<>();
}
long procStartMs = System.currentTimeMillis();
for (long blockIx = 0; blockIx < maxIndex; blockIx++) {
final int length = Integer.reverseBytes(in.readInt());
LOG.debug("STARTED import {} of {} length {}", INTEGER_FORMAT.format(blockIx), INTEGER_FORMAT.format(maxIndex), INTEGER_FORMAT.format(length));
final byte[] ba = new byte[length];
in.read(ba);
final Block block = new Block(ByteBuffer.wrap(ba));
final boolean forceSynch = (blockIx % BlockDb.BLOCK_FORCE_SYNCH_INTERVAL) == 0;
blockDb.put(forceSynch, block);
interimBlocks++;
interimBytes += ba.length;
for (final Transaction tx : block.getTransactionList()) {
interimTx[tx.type.ordinal()]++;
final Fixed8 systemFee = localNodeData.getTransactionSystemFeeMap().get(tx.type);
interimTxNetworkFees[tx.type.ordinal()] += getNetworkFee(blockDb, tx, systemFee).value;
totalTx++;
for (final TransactionOutput txOut : tx.outputs) {
activeAccountSet[tx.type.ordinal()].add(txOut.scriptHash);
}
}
LOG.debug("SUCCESS import {} of {} hash {}", INTEGER_FORMAT.format(blockIx), INTEGER_FORMAT.format(maxIndex), block.hash);
MapUtil.increment(numBlocksByTxCountMap, String.valueOf(block.getTransactionList().size()));
final Timestamp blockTs = block.getTimestamp();
if (startMs < 0) {
startMs = blockTs.getTime();
}
final long ms = blockTs.getTime() - startMs;
if (ms > (86400 * 1000)) {
blockDb.put(true);
final Block maxBlockHeader = blockDb.getHeaderOfBlockWithMaxIndex();
final JSONObject stats = getStats(blockDb, interimBlocks, interimBytes, interimTx, activeAccountSet, procStartMs, blockTs, interimTxNetworkFees, numBlocksByTxCountMap);
if (blockIx > 0) {
statsWriter.println(COMMA);
}
statsWriter.println(stats);
final long maxBlockHeaderIndex = maxBlockHeader.getIndexAsLong();
LOG.info("INTERIM import {} of {}, bx {}, tx {} json {}", INTEGER_FORMAT.format(blockIx), INTEGER_FORMAT.format(maxIndex), INTEGER_FORMAT.format(maxBlockHeaderIndex), INTEGER_FORMAT.format(totalTx), stats);
startMs = blockTs.getTime();
for (int ix = 0; ix < interimTx.length; ix++) {
interimTx[ix] = 0;
interimTxNetworkFees[ix] = 0;
}
interimBlocks = 0;
interimBytes = 0;
for (int txOrdinal = 0; txOrdinal < activeAccountSet.length; txOrdinal++) {
activeAccountSet[txOrdinal].clear();
}
numBlocksByTxCountMap.clear();
procStartMs = System.currentTimeMillis();
}
}
blockDb.put(true);
LOG.info("SUCCESS import {}, synched", INTEGER_FORMAT.format(maxIndex));
} catch (final IOException e) {
if (e instanceof EOFException) {
blockDb.put(true);
final Block maxBlockHeader = blockDb.getHeaderOfBlockWithMaxIndex();
LOG.error("FAILURE import {} of {}, synched, EOFException", INTEGER_FORMAT.format(maxBlockHeader.getIndexAsLong()), maxIndex);
LOG.error("EOFException", e);
return;
} else {
throw new RuntimeException(e);
}
} finally {
statsWriter.println(CLOSE_BRACKET);
}
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
use of neo.network.model.LocalNodeData 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.LocalNodeData in project neo-java by coranos.
the class RemoteNodeControllerRunnable method run.
/**
* the run method.
*/
@Override
public void run() {
LOG.debug("STARTED RemoteNodeControllerRunnable run {}", data.getHostAddress());
final long startTimeMs = System.currentTimeMillis();
final LocalNodeData localNodeData = localControllerNode.getLocalNodeData();
final long readTimeOut = localNodeData.getRpcServerTimeoutMillis();
final long magic = localNodeData.getMagic();
final int localPort = localNodeData.getTcpPort();
final int nonce = localNodeData.getNonce();
final Block maxStartHeightBlock = localNodeData.getBlockDb().getHeaderOfBlockWithMaxIndex();
final long startHeight;
if (maxStartHeightBlock == null) {
startHeight = 0;
} else {
startHeight = maxStartHeightBlock.getIndexAsLong();
}
data.getSendQueue().add(new Message(magic, CommandEnum.VERSION, PayloadUtil.getVersionPayload(localPort, nonce, startHeight).toByteArray()));
data.getSendQueue().add(new Message(magic, CommandEnum.VERACK));
try {
try (SocketWrapper s = localNodeData.getSocketFactory().newSocketWrapper()) {
s.setSoTimeout(2000);
s.connect(data.getTcpAddressAndPort(), 2000);
try (OutputStream out = s.getOutputStream();
InputStream in = s.getInputStream()) {
data.setGoodPeer(true);
while (data.isGoodPeer()) {
sendMessages(out);
out.flush();
try {
Thread.sleep(data.getSleepIntervalMs());
} catch (final InterruptedException e) {
LOG.debug("InterruptedException[1], stopping. {}", e.getMessage());
data.setGoodPeer(false);
}
if (data.isGoodPeer()) {
recieveMessages(readTimeOut, magic, in);
}
final long currTimeMs = System.currentTimeMillis();
final long recycleTimeMs = startTimeMs + data.getRecycleIntervalMs();
if (recycleTimeMs < currTimeMs) {
LOG.debug("recycling remote node {}", data.getHostAddress());
data.setGoodPeer(false);
}
if (data.isGoodPeer()) {
try {
Thread.sleep(data.getSleepIntervalMs());
} catch (final InterruptedException e) {
LOG.debug("InterruptedException[2], stopping. {}", e.getMessage());
data.setGoodPeer(false);
}
}
}
}
} catch (final SocketTimeoutException e) {
LOG.trace("SocketTimeoutException[2] from {}, closing peer", data.getHostAddress());
LOG.trace("SocketTimeoutException[2]", e);
data.setGoodPeer(false);
} catch (final ConnectException e) {
LOG.trace("ConnectException from {}, closing peer", data.getHostAddress());
LOG.trace("ConnectException", e);
data.setGoodPeer(false);
} catch (final MessageFormatException e) {
LOG.trace("MessageFormatException from {}, closing peer", data.getHostAddress());
LOG.trace("MessageFormatException", e);
data.setGoodPeer(false);
} catch (final SocketException e) {
if (e.getMessage().equals("Broken pipe (Write failed)")) {
LOG.trace("SocketException from {}, broken pipe, closing peer", data.getHostAddress());
} else if (e.getMessage().equals("Operation timed out (Read failed)")) {
LOG.trace("SocketException from {}, timeout, closing peer", data.getHostAddress());
} else if (e.getMessage().equals("Connection reset")) {
LOG.trace("SocketException from {}, connection reset, closing peer", data.getHostAddress());
} else if (e.getMessage().equals("Network is unreachable (connect failed)")) {
LOG.trace("SocketException from {}, unreachable network, closing peer", data.getHostAddress());
} else if (e.getMessage().equals("Protocol wrong type for socket (Write failed)")) {
LOG.trace("SocketException from {}, wrong protocol, closing peer", data.getHostAddress());
} else {
LOG.error("SocketException from {}, closing peer", data.getHostAddress());
LOG.error("SocketException", e);
}
data.setGoodPeer(false);
} catch (final ClosedChannelException e) {
LOG.trace("ClosedChannelException from {}, closing peer", data.getHostAddress());
data.setGoodPeer(false);
}
} catch (final Exception e) {
LOG.error("error", e);
LOG.debug("FAILURE RemoteNodeControllerRunnable run");
localControllerNode.onSocketClose(RemoteNodeControllerRunnable.this);
return;
}
localControllerNode.onSocketClose(RemoteNodeControllerRunnable.this);
LOG.debug("SUCCESS RemoteNodeControllerRunnable run");
}
use of neo.network.model.LocalNodeData in project neo-java by coranos.
the class BlockImportExportUtil method exportBlocks.
/**
* exports the blocks to the file.
*
* @param controller
* the controller.
*/
public static void exportBlocks(final LocalControllerNode controller) {
final LocalNodeData localNodeData = controller.getLocalNodeData();
final BlockDb blockDb = localNodeData.getBlockDb();
try (OutputStream statsFileOut = new FileOutputStream(localNodeData.getChainExportStatsFileName());
PrintWriter statsWriter = new PrintWriter(statsFileOut, true)) {
statsWriter.println(OPEN_BRACKET);
try (DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(localNodeData.getChainExportDataFileName()), 1024 * 1024 * 32))) {
final long maxIndex = blockDb.getHeaderOfBlockWithMaxIndex().getIndexAsLong();
final byte[] maxIndexBa = new UInt32(maxIndex + 1).toByteArray();
out.write(maxIndexBa);
if (LOG.isTraceEnabled()) {
LOG.trace("export maxIndexBa aswritten {}", Hex.encode(maxIndexBa));
}
long startMs = -1;
long interimBlocks = 0;
long interimBytes = 0;
final long[] interimTx = new long[TransactionType.values().length];
final long[] interimTxNetworkFees = new long[TransactionType.values().length];
long totalTx = 0;
final Map<String, Long> numBlocksByTxCountMap = new TreeMap<>();
@SuppressWarnings("unchecked") final Set<UInt160>[] activeAccountSet = new Set[TransactionType.values().length];
for (int txOrdinal = 0; txOrdinal < activeAccountSet.length; txOrdinal++) {
activeAccountSet[txOrdinal] = new TreeSet<>();
}
long procStartMs = System.currentTimeMillis();
for (long blockIx = 0; blockIx <= maxIndex; blockIx++) {
LOG.debug("STARTED export {} of {} ", blockIx, maxIndex);
final Block block = localNodeData.getBlockDb().getFullBlockFromHeight(blockIx);
final byte[] ba = block.toByteArray();
final int length = Integer.reverseBytes(ba.length);
out.writeInt(length);
out.write(ba);
LOG.debug("SUCCESS export {} of {} length {}", blockIx, maxIndex, ba.length);
final Timestamp blockTs = block.getTimestamp();
interimBlocks++;
interimBytes += ba.length;
for (final Transaction tx : block.getTransactionList()) {
interimTx[tx.type.ordinal()]++;
final Fixed8 systemFee = localNodeData.getTransactionSystemFeeMap().get(tx.type);
interimTxNetworkFees[tx.type.ordinal()] += getNetworkFee(blockDb, tx, systemFee).value;
totalTx++;
for (final TransactionOutput txOut : tx.outputs) {
activeAccountSet[tx.type.ordinal()].add(txOut.scriptHash);
}
}
MapUtil.increment(numBlocksByTxCountMap, String.valueOf(block.getTransactionList().size()));
if (startMs < 0) {
startMs = blockTs.getTime();
}
final long ms = blockTs.getTime() - startMs;
if (ms > (86400 * 1000)) {
out.flush();
final Block maxBlockHeader = blockDb.getHeaderOfBlockWithMaxIndex();
final JSONObject stats = getStats(blockDb, interimBlocks, interimBytes, interimTx, activeAccountSet, procStartMs, blockTs, interimTxNetworkFees, numBlocksByTxCountMap);
if (blockIx > 0) {
statsWriter.println(COMMA);
}
statsWriter.println(stats);
LOG.info("INTERIM export {} of {}, bx {}, tx {} json {}", INTEGER_FORMAT.format(blockIx), INTEGER_FORMAT.format(maxIndex), INTEGER_FORMAT.format(maxBlockHeader.getIndexAsLong()), INTEGER_FORMAT.format(totalTx), stats);
startMs = blockTs.getTime();
for (int ix = 0; ix < interimTx.length; ix++) {
interimTx[ix] = 0;
interimTxNetworkFees[ix] = 0;
}
interimBlocks = 0;
interimBytes = 0;
for (int txOrdinal = 0; txOrdinal < activeAccountSet.length; txOrdinal++) {
activeAccountSet[txOrdinal].clear();
}
numBlocksByTxCountMap.clear();
procStartMs = System.currentTimeMillis();
}
}
out.flush();
} catch (final IOException e) {
throw new RuntimeException(e);
} finally {
statsWriter.println(CLOSE_BRACKET);
}
} catch (final IOException e) {
throw new RuntimeException(e);
}
}
Aggregations