use of neo.model.core.Block 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);
}
}
use of neo.model.core.Block in project neo-java by coranos.
the class StatsModel method addBlockchainStats.
/**
* add stats about the blockchain.
*
* @param localNodeData
* the local node data to use.
*/
private void addBlockchainStats(final LocalNodeData localNodeData) {
final long blockCount = localNodeData.getBlockDb().getBlockCount();
final long blockFileSize = localNodeData.getBlockFileSize();
final long allChainBlockHeight = localNodeData.getBlockchainBlockHeight();
addNameAndValue(BLOCKCHAIN_BLOCK_HEIGHT, allChainBlockHeight);
addNameAndValue(KNOWN_BLOCK_COUNT, blockCount);
final long blockHeight;
final Block highestBlock = localNodeData.getBlockDb().getHeaderOfBlockWithMaxIndex();
if (highestBlock != null) {
addNameAndValue(MAX_BLOCK_HEIGHT, highestBlock.getIndexAsLong());
addNameAndValue(MAX_BLOCK_TIMESTAMP, highestBlock.getTimestamp());
blockHeight = highestBlock.getIndexAsLong();
} else {
blockHeight = 0;
}
if (localNodeData.getHighestBlockTime() != null) {
addNameAndValue(LAST_BLOCK_HEIGHT_CHANGE, localNodeData.getHighestBlockTime());
}
if (!localNodeData.getVerifiedHeaderPoolMap().isEmpty()) {
addNameAndValue(MAX_HEADER_HEIGHT, localNodeData.getVerifiedHeaderPoolMap().lastKey());
} else {
if (highestBlock != null) {
addNameAndValue(MAX_HEADER_HEIGHT, highestBlock.getIndexAsLong());
}
}
if (localNodeData.getHighestHeaderTime() != null) {
addNameAndValue(LAST_HEADER_HEIGHT_CHANGE, localNodeData.getHighestHeaderTime());
}
addNameAndValue(BLOCK_FILE_SIZE, blockFileSize);
if (blockHeight > 0) {
addNameAndValue(AVG_FILE_SIZE_PER_BLOCK, blockFileSize / blockHeight);
addNameAndValue(EST_FILE_SIZE_FOR_BLOCKCHAIN, (blockFileSize / blockHeight) * allChainBlockHeight);
final long startBlockHeight = localNodeData.getStartBlockHeight();
addNameAndValue(STARTING_BLOCK_HEIGHT, startBlockHeight);
final long numBlocks = blockHeight - startBlockHeight;
addNameAndValue(ELAPSED_SINCE_START_BLOCK_HEIGHT, numBlocks);
final long durationInSeconds = getDurationInSeconds(localNodeData);
addNameAndValue(ELAPSED_SINCE_START_SECONDS, durationInSeconds);
if (numBlocks > 0) {
final long millisecondsPerBlock = (durationInSeconds * 1000) / numBlocks;
addNameAndValue(EST_TIME_FOR_BLOCK_MS, millisecondsPerBlock);
final long remainingChainBlockHeight = allChainBlockHeight - blockHeight;
addNameAndValue(REMAINING_BLOCKCHAIN_BLOCK_HEIGHT, remainingChainBlockHeight);
final long secondsForChain = (remainingChainBlockHeight * millisecondsPerBlock) / 1000;
addNameAndValue(REMAINING_TIME_FOR_BLOCKCHAIN, secondsForChain);
final Date estEndTime = new Date(System.currentTimeMillis() + (secondsForChain * 1000));
addNameAndValue(EST_END_TIME, estEndTime);
}
}
}
use of neo.model.core.Block in project neo-java by coranos.
the class TestVm method test999Vm.
@Test
public void test999Vm() {
LOG.info("STARTED vm");
final LocalNodeData localNodeData = CONTROLLER.getLocalNodeData();
final BlockDb blockDb = localNodeData.getBlockDb();
final long maxIndex = blockDb.getHeaderOfBlockWithMaxIndex().getIndexAsLong();
long startMs = -1;
for (long blockHeight = 0; blockHeight <= maxIndex; blockHeight++) {
LOG.info("STARTED block {} of {} ", blockHeight, maxIndex);
final Block block = blockDb.getFullBlockFromHeight(blockHeight);
final int maxTxIx = block.getTransactionList().size();
for (int txIx = 0; txIx < maxTxIx; txIx++) {
final Transaction tx = block.getTransactionList().get(txIx);
if (tx.type.equals(TransactionType.ISSUE_TRANSACTION)) {
LOG.info("SKIPPED block {} of {} tx {} of {} : {}", blockHeight, maxIndex, txIx, maxTxIx, tx.getHash());
} else {
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 : " + tx.type + ":" + verifyScriptsResult);
} else {
LOG.info("SUCCESS block {} of {} tx {} of {} : {} {}", blockHeight, maxIndex, txIx, maxTxIx, tx.type, tx.getHash());
}
}
}
final Timestamp blockTs = block.getTimestamp();
if (startMs < 0) {
startMs = blockTs.getTime();
}
final long ms = blockTs.getTime() - startMs;
if (ms > (86400 * 1000)) {
final String targetDateStr = DATE_FORMAT.format(blockTs);
LOG.info("INTERIM vm {} of {}, date {}", INTEGER_FORMAT.format(blockHeight), INTEGER_FORMAT.format(maxIndex), targetDateStr);
startMs = blockTs.getTime();
}
}
LOG.debug("SUCCESS vm");
}
use of neo.model.core.Block in project neo-java by coranos.
the class AbstractJsonMockBlockDb method getBlock.
/**
* returns the block with the given hash.
*
* @param hash
* the hash to use.
* @param withTransactions
* if true, add transactions. If false, only return the block header.
* @return the block with the given hash.
*/
private Block getBlock(final UInt256 hash, final boolean withTransactions) {
final String hashHex = hash.toHexString();
final JSONArray mockBlockDb = getMockBlockDb();
for (int ix = 0; ix < mockBlockDb.length(); ix++) {
final JSONObject mockBlock = mockBlockDb.getJSONObject(ix);
if (mockBlock.getString(HASH).equals(hashHex)) {
final Block block = getBlock(mockBlock, withTransactions);
return block;
}
}
throw new RuntimeException("no block at hash:" + hash);
}
use of neo.model.core.Block in project neo-java by coranos.
the class AbstractJsonMockBlockDb method put.
@Override
public final void put(final boolean forceSynch, final Block... blocks) {
for (final Block block : blocks) {
if (!containsBlockWithHash(block.hash)) {
final JSONObject mockBlock = new JSONObject();
mockBlock.put(HASH, block.hash.toHexString());
mockBlock.put(INDEX, block.getIndexAsLong());
mockBlock.put(BLOCK, ModelUtil.toHexString(block.toByteArray()));
getMockBlockDb().put(mockBlock);
}
}
}
Aggregations