use of neo.model.core.Block in project neo-java by coranos.
the class BlockDbMapDbImpl method put.
@Override
public void put(final boolean forceSynch, final Block... blocks) {
synchronized (this) {
if (closed) {
return;
}
}
if (LOG.isDebugEnabled()) {
LOG.debug("STARTED put, {} blocks", NumberFormat.getIntegerInstance().format(blocks.length));
}
try {
final BTreeMap<byte[], Long> blockIndexByHashMap = getBlockIndexByHashMap();
final BTreeMap<Long, byte[]> blockHeaderByIndexMap = getBlockHeaderByIndexMap();
for (final Block block : blocks) {
synchronized (this) {
if (closed) {
db.rollback();
return;
}
}
final long blockIndex = block.getIndexAsLong();
final long maxBlockIndex = getMaxBlockIndex();
final boolean duplicateBlock;
if ((blockIndex <= maxBlockIndex) && (blockIndex != 0) && (maxBlockIndex != 0)) {
duplicateBlock = true;
} else {
duplicateBlock = false;
}
if (duplicateBlock) {
LOG.error("duplicate block,blockIndex:{};maxBlockIndex:{};hash:{};", blockIndex, maxBlockIndex, block.hash);
} else {
final byte[] prevHashBa = block.prevHash.toByteArray();
ArrayUtils.reverse(prevHashBa);
blockIndexByHashMap.put(block.hash.toByteArray(), blockIndex);
blockHeaderByIndexMap.put(blockIndex, block.toHeaderByteArray());
int transactionIndex = 0;
final Map<Long, List<byte[]>> txKeyByBlockIxMap = new TreeMap<>();
final Map<ByteBuffer, byte[]> txByKeyMap = new TreeMap<>();
final Map<ByteBuffer, byte[]> txKeyByTxHashMap = new TreeMap<>();
txKeyByBlockIxMap.put(blockIndex, new ArrayList<>());
for (final Transaction transaction : block.getTransactionList()) {
final byte[] transactionBaseBa = transaction.toByteArray();
final byte[] transactionKeyBa = getTransactionKey(blockIndex, transactionIndex);
putList(txKeyByBlockIxMap, blockIndex, transactionKeyBa);
final ByteBuffer transactionKeyBb = ByteBuffer.wrap(transactionKeyBa);
txByKeyMap.put(transactionKeyBb, transactionBaseBa);
txKeyByTxHashMap.put(ByteBuffer.wrap(transaction.getHash().toByteArray()), transactionKeyBa);
transactionIndex++;
}
putWithByteBufferKey(TRANSACTION_KEY_BY_HASH, txKeyByTxHashMap);
putWithByteBufferKey(TRANSACTION_BY_KEY, txByKeyMap);
putWithLongKey(TRANSACTION_KEYS_BY_BLOCK_INDEX, toByteBufferValue(txKeyByBlockIxMap));
try {
updateAssetAndValueByAccountMap(block, false);
} catch (final Exception e) {
throw new RuntimeException("put: error updating assets for block " + block.hash, e);
}
updateMaxBlockIndex(blockIndex);
}
}
db.commit();
} catch (final Exception e) {
LOG.error("FAILURE put, {} blocks", NumberFormat.getIntegerInstance().format(blocks.length));
LOG.error("FAILURE put", e);
db.rollback();
throw new RuntimeException(e);
}
if (LOG.isDebugEnabled()) {
LOG.debug("SUCCESS put, {} blocks", NumberFormat.getIntegerInstance().format(blocks.length));
}
}
use of neo.model.core.Block in project neo-java by coranos.
the class BlockDbMapDbImpl method deleteHighestBlock.
@Override
public void deleteHighestBlock() {
LOG.info("STARTED deleteHighestBlock");
try {
long blockHeight = getHeaderOfBlockWithMaxIndex().getIndexAsLong();
Block blockHeader = getBlock(blockHeight, false);
while (blockHeader == null) {
LOG.error("INTERIM INFO deleteHighestBlock height:{} block is null, decrementing by 1 and retrying");
blockHeight--;
blockHeader = getBlock(blockHeight, false);
}
LOG.info("INTERIM INFO deleteHighestBlock height:{};hash:{};timestamp:{};", blockHeight, blockHeader.hash, blockHeader.getTimestamp());
final Block fullBlock = getBlock(blockHeight, true);
deleteBlockAtHeight(blockHeight);
try {
updateAssetAndValueByAccountMap(fullBlock, true);
} catch (final Exception e) {
throw new RuntimeException("deleteHighestBlock: error updating assets for block " + blockHeader.hash, e);
}
setBlockIndex(blockHeight - 1);
db.commit();
} catch (final Exception e) {
LOG.error("FAILURE deleteHighestBlock", e);
db.rollback();
}
LOG.info("SUCCESS deleteHighestBlock");
}
use of neo.model.core.Block in project neo-java by coranos.
the class RpcServerUtil method getHeightOfTs.
/**
* finds a block with a given timestamp.
*
* @param controller
* the controller to use.
* @param level
* the level at which we are searching.
* @param minHeight
* the min height to find.
* @param maxHeight
* the max height to find.
* @param ts
* the timestamp to find.
* @return the block height closest to the given timestamp.
*/
private static long getHeightOfTs(final LocalControllerNode controller, final long level, final long minHeight, final long maxHeight, final long ts) {
final long midHeight = minHeight + ((maxHeight - minHeight) / 2);
if ((midHeight == minHeight) || (midHeight == maxHeight)) {
return minHeight;
}
final Block midBlock = controller.getLocalNodeData().getBlockDb().getHeaderOfBlockFromHeight(midHeight);
if (midBlock == null) {
LOG.trace("getHeightOfTs[null]level:{};minHeight:{};midHeight:{};", level, minHeight, midHeight);
return getHeightOfTs(controller, level + 1, minHeight, maxHeight - 1, ts);
}
final long midBlockTs = midBlock.timestamp.asLong();
if (ts == midBlockTs) {
return midHeight;
} else if (ts < midBlockTs) {
LOG.trace("getHeightOfTs[upper]level:{};minHeight:{};midHeight:{};midBlock.Timestamp:{};", level, minHeight, midHeight, midBlock.timestamp);
return getHeightOfTs(controller, level + 1, minHeight, midHeight, ts);
} else {
LOG.trace("getHeightOfTs[lower]level:{};minHeight:{};midHeight:{};midBlock.Timestamp:{};", level, midHeight, maxHeight, midBlock.timestamp);
return getHeightOfTs(controller, level + 1, midHeight, maxHeight, ts);
}
}
use of neo.model.core.Block in project neo-java by coranos.
the class RpcServerUtil method onSubmitBlock.
/**
* submit a block.
*
* @param controller
* the controller to use.
* @param id
* the id to use.
* @param params
* the parameters to use.
* @return true if the block validated, false if it did not.
*/
private static JSONObject onSubmitBlock(final LocalControllerNode controller, final int id, final JSONArray params) {
if (params.length() == 0) {
final JSONObject response = new JSONObject();
response.put(ERROR, "no parameters, expected a hashed block");
response.put(EXPECTED, EXPECTED_GENERIC_HEX);
response.put(ACTUAL, NULL);
return response;
}
try {
final String hex = params.getString(0);
final byte[] ba = ModelUtil.decodeHex(hex);
final Block block = new Block(ByteBuffer.wrap(ba));
controller.getLocalNodeData().getBlockDb().put(false, block);
} catch (final RuntimeException e) {
final JSONObject response = new JSONObject();
response.put(ERROR, e.getMessage());
response.put(EXPECTED, true);
response.put(ACTUAL, params.get(0));
return response;
}
final JSONObject response = new JSONObject();
response.put(RESULT, true);
response.put(ID, id);
response.put(JSONRPC, VERSION_2_0);
return response;
}
use of neo.model.core.Block in project neo-java by coranos.
the class RpcServerUtil method onGetBestBlockHash.
/**
* responds to a "getbestblockhash" command.
*
* @param controller
* the controller to use.
* @param id
* the request id to use.
* @return the response.
*/
private static JSONObject onGetBestBlockHash(final LocalControllerNode controller, final int id) {
final Block block = controller.getLocalNodeData().getBlockDb().getHeaderOfBlockWithMaxIndex();
if (block == null) {
final JSONObject response = new JSONObject();
response.put(ERROR, ERROR_NO_BLOCKS_IN_BLOCKCHAIN);
response.put(EXPECTED, EXPECTED_GENERIC_HEX);
response.put(ACTUAL, NULL);
return response;
} else {
final JSONObject response = new JSONObject();
final String hashHex = block.hash.toHexString();
response.put(RESULT, "0x" + hashHex);
response.put(ID, id);
response.put(JSONRPC, VERSION_2_0);
return response;
}
}
Aggregations