Search in sources :

Example 16 with Block

use of neo.model.core.Block in project neo-java by coranos.

the class TestDBMapDb method test006putAndGetTransactionWithHash.

/**
 * test put, and getTransactionWithHash.
 */
@Test
public void test006putAndGetTransactionWithHash() {
    try (TestLocalControllerNode controller = getTestLocalControllerNode()) {
        final Block block = MockUtil.getMockBlock003();
        controller.getBlockDb().put(true, GenesisBlockUtil.GENESIS_BLOCK);
        controller.getBlockDb().put(true, block);
        final Transaction expectedTransaction = block.getTransactionList().get(0);
        final Transaction actualTransaction = controller.getBlockDb().getTransactionWithHash(expectedTransaction.getHash());
        Assert.assertEquals("transactions should match.", expectedTransaction.toJSONObject().toString(2), actualTransaction.toJSONObject().toString(2));
    }
}
Also used : Transaction(neo.model.core.Transaction) Block(neo.model.core.Block) Test(org.junit.Test)

Example 17 with Block

use of neo.model.core.Block 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);
    }
}
Also used : TreeSet(java.util.TreeSet) Set(java.util.Set) TransactionOutput(neo.model.core.TransactionOutput) BufferedOutputStream(java.io.BufferedOutputStream) DataOutputStream(java.io.DataOutputStream) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) Timestamp(java.sql.Timestamp) BufferedInputStream(java.io.BufferedInputStream) Fixed8(neo.model.bytes.Fixed8) EOFException(java.io.EOFException) PrintWriter(java.io.PrintWriter) LocalNodeData(neo.network.model.LocalNodeData) DataInputStream(java.io.DataInputStream) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) TreeMap(java.util.TreeMap) FileInputStream(java.io.FileInputStream) Transaction(neo.model.core.Transaction) JSONObject(org.json.JSONObject) FileOutputStream(java.io.FileOutputStream) Block(neo.model.core.Block) BlockDb(neo.model.db.BlockDb) UInt32(neo.model.bytes.UInt32)

Example 18 with Block

use of neo.model.core.Block in project neo-java by coranos.

the class LocalControllerNode method onBlock.

/**
 * does something on a "block" message.
 *
 * @param peer
 *            the peer that sent the message.
 * @param message
 *            the message.
 */
private void onBlock(final RemoteNodeControllerRunnable peer, final Message message) {
    if (stopped) {
        return;
    }
    final Block newBlock = message.getPayload(Block.class);
    final String expected = new String(Hex.encodeHexString(message.getPayloadByteArray()));
    final String actual = Hex.encodeHexString(newBlock.toByteArray());
    if (!expected.equals(actual)) {
        LOG.error("onBlock newBlock: {}", newBlock);
        LOG.error("onBlock expected: {}", expected);
        LOG.error("onBlock actual  : {}", actual);
        return;
    }
    LocalNodeDataSynchronizedUtil.addUnverifiedBlock(localNodeData, newBlock);
// LocalNodeDataSynchronizedUtil.verifyUnverifiedBlocks(localNodeData);
}
Also used : Block(neo.model.core.Block)

Example 19 with Block

use of neo.model.core.Block in project neo-java by coranos.

the class LocalNodeDataSynchronizedUtil method addHeaderIfNewUnsynchronized.

/**
 * add the header if it is new, this is the unsynchronized helper method.
 *
 * @param localNodeData
 *            the local node data to use.
 * @param header
 *            the header to add.
 * @return true if added, gfalse if not.
 */
private static boolean addHeaderIfNewUnsynchronized(final LocalNodeData localNodeData, final Header header) {
    final long headerIndex = header.getIndexAsLong();
    LOG.trace("STARTED addHeaderIfNewUnsynchronized adding header : index:{}; hash:{};", headerIndex, header.hash);
    final Block highestBlock = localNodeData.getBlockDb().getHeaderOfBlockWithMaxIndex();
    if (highestBlock != null) {
        final long maxBlockIndex = highestBlock.getIndexAsLong();
        // }
        if (headerIndex <= maxBlockIndex) {
            final String message = "FAILURE addHeaderIfNewUnsynchronized[1]" + " (headerIndex[{}] <= maxBlockIndex[{}]) adding header : index:{}; hash:{};";
            LOG.trace(message, headerIndex, maxBlockIndex, headerIndex, header.hash);
            return false;
        }
    }
    if (!localNodeData.getUnverifiedBlockPoolSet().isEmpty()) {
        final long maxBlockIndex = highestBlock.getIndexAsLong();
        final long numUnverifiedBlockCount = localNodeData.getUnverifiedBlockPoolSet().size();
        final long maxUnverifiedBlockIndex = localNodeData.getUnverifiedBlockPoolSet().last().getIndexAsLong();
        final boolean gapsInBlocks = (maxBlockIndex + numUnverifiedBlockCount) <= maxUnverifiedBlockIndex;
        if (LOG.isTraceEnabled()) {
            final String message = "INTERIM addHeaderIfNewUnsynchronized[2] " + " (maxBlockIndex[{}]+numUnverifiedBlockCount[{}] <= maxUnverifiedBlockIndex[{}]), " + " gaps:{};";
            LOG.trace(message, maxBlockIndex, numUnverifiedBlockCount, maxUnverifiedBlockIndex, gapsInBlocks);
        }
        if (gapsInBlocks) {
            if (LOG.isTraceEnabled()) {
                final String message = "INTERIM addHeaderIfNewUnsynchronized[2]" + " (maxBlockIndex[{}]+numUnverifiedBlockCount[{}] <= maxUnverifiedBlockIndex[{}])," + " there are gaps in unverified blocks.";
                LOG.trace(message, maxBlockIndex, numUnverifiedBlockCount, maxUnverifiedBlockIndex);
            }
            if (localNodeData.getBlockDb().containsBlockWithHash(header.hash)) {
                final String message = "FAILURE addHeaderIfNewUnsynchronized[3]" + " containsBlockWithHash : index:{}; hash:{}; ";
                LOG.trace(message, headerIndex, maxUnverifiedBlockIndex, headerIndex, header.hash);
                return false;
            }
        } else {
            if (headerIndex <= maxUnverifiedBlockIndex) {
                final String message = "FAILURE addHeaderIfNewUnsynchronized[4]" + " (headerIndex[{}] <= maxUnverifiedBlockIndex[{}]) adding header : index:{}; hash:{};";
                LOG.trace(message, headerIndex, maxUnverifiedBlockIndex, headerIndex, header.hash);
                return false;
            }
        }
    }
    if (localNodeData.getVerifiedHeaderPoolMap().containsKey(headerIndex)) {
        final String message = "FAILURE addHeaderIfNewUnsynchronized[5]" + " getVerifiedHeaderPoolMap().containsKey():true; adding header : index:{}; hash:{};";
        LOG.trace(message, headerIndex, header.hash);
        return false;
    }
    if (localNodeData.getVerifiedHeaderPoolMap().containsKey(headerIndex)) {
        final String message = "FAILURE addHeaderIfNewUnsynchronized[6]" + " getVerifiedHeaderPoolMap().containsKey(headerIndex):true; adding header : index:{}; hash:{};";
        LOG.trace(message, headerIndex, header.hash);
        return false;
    }
    if (localNodeData.getUnverifiedHeaderPoolSet().contains(header)) {
        final String message = "FAILURE addHeaderIfNewUnsynchronized[7]" + " getUnverifiedHeaderPoolSet().contains(header):true; adding header : index:{}; hash:{};";
        LOG.trace(message, headerIndex, header.hash);
        return false;
    }
    localNodeData.getUnverifiedHeaderPoolSet().add(header);
    localNodeData.updateHighestHeaderTime();
    LOG.trace("SUCCESS addHeaderIfNewUnsynchronized adding header : index:{}; hash:{};", headerIndex, header.hash);
    return true;
}
Also used : Block(neo.model.core.Block)

Example 20 with Block

use of neo.model.core.Block in project neo-java by coranos.

the class LocalNodeDataSynchronizedUtil method requestHeaders.

/**
 * request headers from the remote node.
 *
 * @param localNodeData
 *            the local node data to use.
 * @param remoteNodeData
 *            the remote node data to use.
 */
public static void requestHeaders(final LocalNodeData localNodeData, final RemoteNodeData remoteNodeData) {
    synchronized (localNodeData) {
        final UInt256 hashRaw;
        final long index;
        if (localNodeData.getUnverifiedBlockPoolSet().isEmpty() && (!localNodeData.getVerifiedHeaderPoolMap().isEmpty())) {
            final long highestHeaderIndex = localNodeData.getVerifiedHeaderPoolMap().lastKey();
            final Header highestHeader = localNodeData.getVerifiedHeaderPoolMap().get(highestHeaderIndex);
            LOG.debug("requestHeaders getVerifiedHeaderPoolMap height:{};hash:{};", highestHeaderIndex, highestHeader.hash);
            hashRaw = highestHeader.hash;
            index = highestHeader.getIndexAsLong();
        } else {
            final Block highestBlock = localNodeData.getBlockDb().getHeaderOfBlockWithMaxIndex();
            if (highestBlock != null) {
                LOG.debug("requestHeaders getHighestBlock height:{};hash:{};", highestBlock.getIndexAsLong(), highestBlock.hash);
                hashRaw = highestBlock.hash;
                index = highestBlock.getIndexAsLong();
            } else {
                LOG.debug("requestHeaders hash is genesis.");
                hashRaw = GenesisBlockUtil.GENESIS_HASH;
                index = GenesisBlockUtil.GENESIS_BLOCK.getIndexAsLong();
            }
        }
        final byte[] ba = hashRaw.getBytesCopy();
        final UInt256 hash = new UInt256(ba);
        LOG.debug("requestHeaders index:{};hash:{};", index, hash);
        // fixed bug at height 2000190
        // final String goodHashStr =
        // "8cb9fee28a48a45468e3c0a229fd4473288cdd9794c10cac7b8f4681ca404342";
        // final UInt256 goodHash = new
        // UInt256(ByteBuffer.wrap(Hex.decode(goodHashStr)));
        // MessageUtil.sendGetHeaders(remoteNodeData, localNodeData, goodHash);
        MessageUtil.sendGetHeaders(remoteNodeData, localNodeData, hash);
    }
}
Also used : Header(neo.model.core.Header) Block(neo.model.core.Block) UInt256(neo.model.bytes.UInt256)

Aggregations

Block (neo.model.core.Block)65 Test (org.junit.Test)26 Transaction (neo.model.core.Transaction)25 JSONObject (org.json.JSONObject)24 JSONArray (org.json.JSONArray)16 TransactionOutput (neo.model.core.TransactionOutput)9 BlockDb (neo.model.db.BlockDb)9 IOException (java.io.IOException)8 TreeMap (java.util.TreeMap)8 UInt256 (neo.model.bytes.UInt256)8 LocalNodeData (neo.network.model.LocalNodeData)6 Fixed8 (neo.model.bytes.Fixed8)5 Timestamp (java.sql.Timestamp)4 ArrayList (java.util.ArrayList)4 Map (java.util.Map)4 TreeSet (java.util.TreeSet)4 OutputStream (java.io.OutputStream)3 SQLException (java.sql.SQLException)3 UInt160 (neo.model.bytes.UInt160)3 UInt32 (neo.model.bytes.UInt32)3