Search in sources :

Example 26 with Block

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

the class BlockDbH2Impl method getBlock.

/**
 * return the block at the given height, with transactions attached.
 *
 * @param blockHeight
 *            the block height to use.
 * @param withTransactions
 *            if true, add transactions. If false, only return the block header.
 * @return the block at the given height.
 */
private Block getBlock(final long blockHeight, final boolean withTransactions) {
    synchronized (this) {
        if (closed) {
            return null;
        }
    }
    final JdbcTemplate t = new JdbcTemplate(ds);
    final byte[] indexBa = BlockUtil.getBlockHeightBa(blockHeight);
    final String sql = getSql("getBlockWithIndex");
    final List<byte[]> data = t.queryForList(sql, byte[].class, indexBa);
    if (data.isEmpty()) {
        return null;
    }
    final Block block = new Block(ByteBuffer.wrap(data.get(0)));
    if (withTransactions) {
        getTransactionsForBlock(block);
    }
    return block;
}
Also used : Block(neo.model.core.Block) JdbcTemplate(org.springframework.jdbc.core.JdbcTemplate)

Example 27 with Block

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

the class BlockDbH2Impl method validate.

@Override
public void validate() {
    LOG.info("STARTED validate");
    final Block block0 = getBlock(0, false);
    if (!block0.hash.equals(GenesisBlockUtil.GENESIS_HASH)) {
        throw new RuntimeException("height 0 block hash \"" + block0.hash.toHexString() + "\" does not match genesis block hash \"" + GenesisBlockUtil.GENESIS_HASH.toHexString() + "\".");
    }
    long lastInfoMs = System.currentTimeMillis();
    long validBlockHeight = 1;
    final long maxBlockCount = getBlockCount();
    while (validBlockHeight < maxBlockCount) {
        LOG.debug("INTERIM DEBUG validate {} of {} STARTED ", validBlockHeight, maxBlockCount);
        final Block block = getBlock(validBlockHeight, false);
        if (block == null) {
            LOG.error("INTERIM validate {} of {} FAILURE, block not found in blockchain.", validBlockHeight, maxBlockCount);
        } else if (!containsBlockWithHash(block.prevHash)) {
            LOG.error("INTERIM validate {} of {} FAILURE, prevHash {} not found in blockchain.", validBlockHeight, maxBlockCount, block.prevHash.toHexString());
            deleteBlockAtHeight(validBlockHeight);
        } else if (block.getIndexAsLong() != validBlockHeight) {
            LOG.error("INTERIM validate {} of {} FAILURE, indexAsLong {} does not match blockchain.", validBlockHeight, maxBlockCount, block.getIndexAsLong());
            deleteBlockAtHeight(validBlockHeight);
        } else {
            if (System.currentTimeMillis() > (lastInfoMs + 1000)) {
                LOG.info("INTERIM INFO  validate {} of {} SUCCESS ", validBlockHeight, maxBlockCount);
                lastInfoMs = System.currentTimeMillis();
            } else {
                LOG.debug("INTERIM DEBUG validate {} of {} SUCCESS ", validBlockHeight, maxBlockCount);
            }
        }
        validBlockHeight++;
    }
    LOG.info("SUCCESS validate");
}
Also used : Block(neo.model.core.Block)

Example 28 with Block

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

the class BlockDbMapDbImpl method getBlock.

/**
 * return the block at the given height, with transactions attached.
 *
 * @param blockHeight
 *            the block height to use.
 * @param withTransactions
 *            if true, add transactions. If false, only return the block header.
 * @return the block at the given height.
 */
private Block getBlock(final long blockHeight, final boolean withTransactions) {
    synchronized (this) {
        if (closed) {
            return null;
        }
    }
    final BTreeMap<Long, byte[]> map = getBlockHeaderByIndexMap();
    if (!map.containsKey(blockHeight)) {
        return null;
    }
    final Block block = new Block(ByteBuffer.wrap(map.get(blockHeight)));
    if (withTransactions) {
        getTransactionsForBlock(block);
    }
    return block;
}
Also used : Block(neo.model.core.Block)

Example 29 with Block

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

the class BlockDbMapDbImpl method validate.

@Override
public void validate() {
    LOG.info("STARTED validate");
    try {
        final Block block0 = getBlock(0, false);
        if (!block0.hash.equals(GenesisBlockUtil.GENESIS_HASH)) {
            throw new RuntimeException("height 0 block hash \"" + block0.hash.toHexString() + "\" does not match genesis block hash \"" + GenesisBlockUtil.GENESIS_HASH.toHexString() + "\".");
        }
        long lastInfoMs = System.currentTimeMillis();
        long blockHeight = 0;
        long lastGoodBlockIndex = -1;
        final long maxBlockCount = getBlockCount();
        boolean blockHeightNoLongerValid = false;
        final String maxBlockCountStr;
        if (LOG.isDebugEnabled() || LOG.isErrorEnabled()) {
            maxBlockCountStr = NumberFormat.getIntegerInstance().format(maxBlockCount);
        } else {
            maxBlockCountStr = null;
        }
        LOG.info("INTERIM validate, clear account list STARTED");
        final BTreeMap<byte[], byte[]> assetAndValueByAccountMap = getAssetAndValueByAccountMap();
        assetAndValueByAccountMap.clear();
        LOG.info("INTERIM validate, clear account list SUCCESS");
        LOG.info("INTERIM validate, clear transaction output state STARTED");
        getTransactionByAccountAndIndexMap().clear();
        getTransactionByAccountMaxIndexMap().clear();
        LOG.info("INTERIM validate, clear  transaction output state SUCCESS");
        while (blockHeight < maxBlockCount) {
            final String blockHeightStr;
            if (LOG.isDebugEnabled() || LOG.isErrorEnabled()) {
                blockHeightStr = NumberFormat.getIntegerInstance().format(blockHeight);
            } else {
                blockHeightStr = null;
            }
            LOG.debug("INTERIM DEBUG validate {} of {} STARTED ", blockHeightStr, maxBlockCountStr);
            final Block block = getBlock(blockHeight, true);
            if (block == null) {
                LOG.error("INTERIM validate {} of {} FAILURE, block not found in blockchain.", blockHeightStr, maxBlockCountStr);
                blockHeightNoLongerValid = true;
            } else if ((blockHeight != 0) && (!containsBlockWithHash(block.prevHash))) {
                LOG.error("INTERIM validate {} of {} FAILURE, prevHash {} not found in blockchain.", blockHeightStr, maxBlockCountStr, block.prevHash.toHexString());
                deleteBlockAtHeight(blockHeight);
                blockHeightNoLongerValid = true;
            } else if (block.getIndexAsLong() != blockHeight) {
                LOG.error("INTERIM validate {} of {} FAILURE, indexAsLong {} does not match blockchain.", blockHeightStr, maxBlockCountStr, block.getIndexAsLong());
                deleteBlockAtHeight(blockHeight);
                blockHeightNoLongerValid = true;
            } else if (blockHeightNoLongerValid) {
                LOG.error("INTERIM validate {} of {} FAILURE, block height tainted.", blockHeightStr, maxBlockCountStr, block.getIndexAsLong());
                deleteBlockAtHeight(blockHeight);
            } else {
                if (System.currentTimeMillis() > (lastInfoMs + 30000)) {
                    final String numberOfAccountsStr = NumberFormat.getIntegerInstance().format(assetAndValueByAccountMap.size());
                    LOG.info("INTERIM INFO  validate {} of {} SUCCESS, number of accounts:{}; date:{}", blockHeightStr, maxBlockCountStr, numberOfAccountsStr, block.getTimestamp());
                    lastInfoMs = System.currentTimeMillis();
                } else {
                    LOG.debug("INTERIM DEBUG validate {} of {} SUCCESS.", blockHeightStr, maxBlockCountStr);
                }
                final long blockIndex = block.getIndexAsLong();
                int transactionIndex = 0;
                final Map<ByteBuffer, byte[]> txKeyByTxHashMap = new TreeMap<>();
                for (final Transaction transaction : block.getTransactionList()) {
                    final byte[] transactionKeyBa = getTransactionKey(blockIndex, transactionIndex);
                    txKeyByTxHashMap.put(ByteBuffer.wrap(transaction.getHash().toByteArray()), transactionKeyBa);
                    transactionIndex++;
                }
                putWithByteBufferKey(TRANSACTION_KEY_BY_HASH, txKeyByTxHashMap);
                try {
                    updateAssetAndValueByAccountMap(block, false);
                } catch (final Exception e) {
                    throw new RuntimeException("validate: error updating assets for block [" + block.getIndexAsLong() + "]" + block.hash, e);
                }
                lastGoodBlockIndex = block.getIndexAsLong();
            }
            final boolean forceSynch = (lastGoodBlockIndex % BLOCK_FORCE_SYNCH_INTERVAL) == 0;
            if (forceSynch) {
                LOG.info("INTERIM validate, partial commit STARTED index {}", lastGoodBlockIndex);
                commitValidation(lastGoodBlockIndex);
                LOG.info("INTERIM validate, partial commit SUCCESS index {}", lastGoodBlockIndex);
            }
            blockHeight++;
        }
        LOG.info("INTERIM validate, commit STARTED index {}", lastGoodBlockIndex);
        commitValidation(lastGoodBlockIndex);
        LOG.info("INTERIM validate, commit SUCCESS index {}", lastGoodBlockIndex);
        LOG.info("SUCCESS validate");
    } catch (final Exception e) {
        LOG.error("FAILURE validate", e);
        db.rollback();
        throw new RuntimeException(e);
    }
}
Also used : Transaction(neo.model.core.Transaction) Block(neo.model.core.Block) Map(java.util.Map) TreeMap(java.util.TreeMap) BTreeMap(org.mapdb.BTreeMap) NotImplementedException(org.apache.commons.lang3.NotImplementedException) SQLException(java.sql.SQLException) IOException(java.io.IOException)

Example 30 with Block

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

the class BlockDbH2Impl 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) {
    synchronized (this) {
        if (closed) {
            return null;
        }
    }
    final JdbcTemplate t = new JdbcTemplate(ds);
    final String sql = getSql("getBlockWithHash");
    final List<byte[]> data = t.queryForList(sql, byte[].class, hash.toByteArray());
    if (data.isEmpty()) {
        return null;
    }
    final Block block = new Block(ByteBuffer.wrap(data.get(0)));
    if (withTransactions) {
        getTransactionsForBlock(block);
    }
    return block;
}
Also used : Block(neo.model.core.Block) JdbcTemplate(org.springframework.jdbc.core.JdbcTemplate)

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