use of neo.model.core.Block in project neo-java by coranos.
the class RpcServerUtil method onGetAccountList.
/**
* returns the account list for accounts that were active between the given
* timestamps.
*
* @param controller
* the controller to use.
* @param id
* the id to use.
* @param params
* the parameters to use.
* @return the list of account data.
*/
private static JSONObject onGetAccountList(final LocalControllerNode controller, final int id, final JSONArray params) {
try {
LOG.trace("getaccountlist 0");
final BlockDb blockDb = controller.getLocalNodeData().getBlockDb();
final long fromTs = params.getLong(0);
final long toTs = params.getLong(1);
final long minHeight = 0;
final long maxHeight = blockDb.getBlockCount();
final long fromHeight = getHeightOfTs(controller, 0, minHeight, maxHeight, fromTs);
final long toHeight = getHeightOfTs(controller, 0, fromHeight, maxHeight, toTs);
LOG.trace("getaccountlist 1 fromHeight:{};toHeight:{};", fromHeight, toHeight);
LOG.trace("getaccountlist 2 accountStateCache STARTED");
final Map<UInt160, Map<UInt256, Fixed8>> addressStateCache = blockDb.getAccountAssetValueMap();
LOG.trace("getaccountlist 2 accountStateCache SUCCESS, count:{}", addressStateCache.size());
final Map<UInt160, Long> neoTxByAddress = new TreeMap<>();
final Map<UInt160, Long> gasTxByAddress = new TreeMap<>();
final Map<UInt160, Long> claimTxByAddress = new TreeMap<>();
final Map<UInt160, Long> neoInByAddress = new TreeMap<>();
final Map<UInt160, Long> gasInByAddress = new TreeMap<>();
final Map<UInt160, Long> neoOutByAddress = new TreeMap<>();
final Map<UInt160, Long> gasOutByAddress = new TreeMap<>();
final Map<UInt160, Long> firstTsByAddress = new TreeMap<>();
final Map<UInt160, Long> lastTsByAddress = new TreeMap<>();
for (long index = fromHeight; index < toHeight; index++) {
LOG.trace("getaccountlist 3 fromHeight:{};toHeight:{};index:{};", fromHeight, toHeight, index);
final Block block = blockDb.getFullBlockFromHeight(index);
for (final Transaction t : block.getTransactionList()) {
final Map<UInt160, Map<UInt256, Long>> addressAssetMap = getAddressAssetMap(blockDb, t);
for (final UInt160 friend : addressAssetMap.keySet()) {
if (!firstTsByAddress.containsKey(friend)) {
firstTsByAddress.put(friend, block.timestamp.asLong());
}
lastTsByAddress.put(friend, block.timestamp.asLong());
if (t.type.equals(TransactionType.CLAIM_TRANSACTION)) {
MapUtil.increment(claimTxByAddress, friend);
}
if (addressAssetMap.get(friend).containsKey(ModelUtil.NEO_HASH)) {
MapUtil.increment(neoTxByAddress, friend);
final long value = addressAssetMap.get(friend).get(ModelUtil.NEO_HASH);
if (value < 0) {
MapUtil.increment(neoInByAddress, friend, -value);
} else {
MapUtil.increment(neoOutByAddress, friend, value);
}
}
if (addressAssetMap.get(friend).containsKey(ModelUtil.GAS_HASH)) {
MapUtil.increment(gasTxByAddress, friend);
final long value = addressAssetMap.get(friend).get(ModelUtil.GAS_HASH);
if (value < 0) {
MapUtil.increment(gasInByAddress, friend, -value);
} else {
MapUtil.increment(gasOutByAddress, friend, value);
}
}
}
}
}
LOG.trace("getaccountlist 4 addressByAccount STARTED");
final Map<UInt160, String> addressByScriptHash = new TreeMap<>();
for (final UInt160 key : addressStateCache.keySet()) {
final String address = ModelUtil.scriptHashToAddress(key);
addressByScriptHash.put(key, address);
}
LOG.trace("getaccountlist 4 addressByAccount SUCCESS, address count:{};", addressByScriptHash.size());
LOG.trace("getaccountlist 5 returnList STARTED");
final JSONArray returnList = new JSONArray();
for (final UInt160 key : addressStateCache.keySet()) {
LOG.trace("getaccountlist 6 key:{};", key);
if (addressByScriptHash.containsKey(key)) {
final Map<UInt256, Fixed8> addressState = addressStateCache.get(key);
final String address = addressByScriptHash.get(key);
LOG.trace("getaccountlist 7 key:{}; address:{};", key, address);
final JSONObject entry = new JSONObject();
entry.put("account", address);
if (addressState.containsKey(ModelUtil.NEO_HASH)) {
entry.put(ModelUtil.NEO, ModelUtil.toRoundedLong(addressState.get(ModelUtil.NEO_HASH).value));
} else {
entry.put(ModelUtil.NEO, 0);
}
if (addressState.containsKey(ModelUtil.GAS_HASH)) {
entry.put(ModelUtil.GAS, ModelUtil.toRoundedDouble(addressState.get(ModelUtil.GAS_HASH).value));
} else {
entry.put(ModelUtil.GAS, 0);
}
if (neoInByAddress.containsKey(key)) {
entry.put(NEO_IN, ModelUtil.toRoundedLong(neoInByAddress.get(key)));
} else {
entry.put(NEO_IN, 0);
}
if (neoOutByAddress.containsKey(key)) {
entry.put(NEO_OUT, ModelUtil.toRoundedLong(neoOutByAddress.get(key)));
} else {
entry.put(NEO_OUT, 0);
}
if (gasInByAddress.containsKey(key)) {
entry.put(GAS_IN, ModelUtil.toRoundedDouble(gasInByAddress.get(key)));
} else {
entry.put(GAS_IN, 0);
}
if (gasOutByAddress.containsKey(key)) {
entry.put(GAS_OUT, ModelUtil.toRoundedDouble(gasOutByAddress.get(key)));
} else {
entry.put(GAS_OUT, 0);
}
if (neoTxByAddress.containsKey(key)) {
entry.put(NEO_TX, neoTxByAddress.get(key));
} else {
entry.put(NEO_TX, 0);
}
if (gasTxByAddress.containsKey(key)) {
entry.put(GAS_TX, gasTxByAddress.get(key));
} else {
entry.put(GAS_TX, 0);
}
if (claimTxByAddress.containsKey(key)) {
entry.put(CLAIM_TX, claimTxByAddress.get(key));
} else {
entry.put(CLAIM_TX, 0);
}
if (firstTsByAddress.containsKey(key)) {
entry.put(FIRST_TS, firstTsByAddress.get(key));
} else {
entry.put(FIRST_TS, 0);
}
if (lastTsByAddress.containsKey(key)) {
entry.put(LAST_TS, lastTsByAddress.get(key));
} else {
entry.put(LAST_TS, 0);
}
returnList.put(entry);
}
}
LOG.trace("getaccountlist 5 returnList SUCCESS, returnList.size:{};", returnList.length());
LOG.trace("getaccountlist 6 return");
final JSONObject response = new JSONObject();
response.put(ID, id);
response.put(JSONRPC, VERSION_2_0);
response.put(RESULT, returnList);
return response;
} catch (final RuntimeException e) {
LOG.error("error in onGetAccountList:", e);
final JSONObject response = new JSONObject();
response.put(ERROR, e.getMessage());
response.put(EXPECTED, new JSONArray());
response.put(ACTUAL, new JSONArray());
return response;
}
}
use of neo.model.core.Block in project neo-java by coranos.
the class LocalNodeDataSynchronizedUtil method verifyUnverifiedHeaders.
/**
* verify any unverified headers, by checking if their block height is less than
* the max block height in the blockchain.
*
* @param localNodeData
* the local node data to use.
* @return true if any block was added to the chain.
*/
public static boolean verifyUnverifiedHeaders(final LocalNodeData localNodeData) {
synchronized (localNodeData) {
LOG.debug("STARTED verifyUnverifiedHeaders");
boolean anyHeaderChanged = false;
final Block highestBlock = localNodeData.getBlockDb().getHeaderOfBlockWithMaxIndex();
final UInt256 highestBlockHash;
final long highestBlockIndex;
if (highestBlock == null) {
highestBlockHash = GenesisBlockUtil.GENESIS_HASH;
highestBlockIndex = 0;
} else {
highestBlockHash = highestBlock.hash;
highestBlockIndex = highestBlock.getIndexAsLong();
}
removeHeadersNotOverBlockIndexUnsynchronized(localNodeData, highestBlockIndex);
final Iterator<Header> unverifiedHeaderIt = localNodeData.getUnverifiedHeaderPoolSet().iterator();
while (unverifiedHeaderIt.hasNext()) {
final Header unverifiedHeader = unverifiedHeaderIt.next();
if (LOG.isTraceEnabled()) {
LOG.trace("INTERIM verifyUnverifiedHeaders, unverifiedHeader index:{};hash:{}; VerifiedHeaderPoolMap.isEmpty:{};", unverifiedHeader.getIndexAsLong(), unverifiedHeader.hash, localNodeData.getVerifiedHeaderPoolMap().isEmpty());
}
if (localNodeData.getVerifiedHeaderPoolMap().isEmpty()) {
if (LOG.isTraceEnabled()) {
final String message = "INTERIM verifyUnverifiedHeaders[1]," + " unverifiedHeader index:{};hash:{};prevHash:{}; highestBlock index:{};hash:{};";
LOG.trace(message, unverifiedHeader.getIndexAsLong(), unverifiedHeader.hash, unverifiedHeader.prevHash, highestBlockIndex, highestBlockHash);
}
if (unverifiedHeader.prevHash.equals(highestBlockHash)) {
localNodeData.getVerifiedHeaderPoolMap().put(unverifiedHeader.getIndexAsLong(), unverifiedHeader);
unverifiedHeaderIt.remove();
anyHeaderChanged = true;
if (LOG.isTraceEnabled()) {
final String message = "SUCCESS verifyUnverifiedHeaders[1]," + " unverifiedHeader index:{};hash:{};prevHash:{};";
LOG.trace(message, unverifiedHeader.getIndexAsLong(), unverifiedHeader.hash, unverifiedHeader.prevHash);
}
} else {
if (LOG.isTraceEnabled()) {
final String message = "FAILURE verifyUnverifiedHeaders[2]," + " unverifiedHeader index:{};hash:{};prevHash:{};highestBlockHash:{};";
LOG.trace(message, unverifiedHeader.getIndexAsLong(), unverifiedHeader.hash, unverifiedHeader.prevHash, highestBlockHash);
}
}
} else {
final long verifiedHeaderHeight = localNodeData.getVerifiedHeaderPoolMap().lastKey();
final Header verifiedHeader = localNodeData.getVerifiedHeaderPoolMap().get(verifiedHeaderHeight);
if (LOG.isTraceEnabled()) {
final String message = "INTERIM verifyUnverifiedHeaders[2]," + " unverifiedHeader index:{};hash:{};prevHash:{}; verifiedHeader index:{};hash:{};";
LOG.trace(message, unverifiedHeader.getIndexAsLong(), unverifiedHeader.hash, unverifiedHeader.prevHash, verifiedHeaderHeight, verifiedHeader.hash);
}
if (unverifiedHeader.prevHash.equals(verifiedHeader.hash)) {
localNodeData.getVerifiedHeaderPoolMap().put(unverifiedHeader.getIndexAsLong(), unverifiedHeader);
unverifiedHeaderIt.remove();
anyHeaderChanged = true;
if (LOG.isTraceEnabled()) {
LOG.trace("SUCCESS verifyUnverifiedHeaders, unverifiedHeader index:{};hash:{};prevHash:{};", unverifiedHeader.getIndexAsLong(), unverifiedHeader.hash, unverifiedHeader.prevHash);
}
} else {
if (LOG.isTraceEnabled()) {
LOG.trace("FAILURE verifyUnverifiedHeaders, unverifiedHeader index:{};hash:{};prevHash:{};", unverifiedHeader.getIndexAsLong(), unverifiedHeader.hash, unverifiedHeader.prevHash);
}
}
}
}
LOG.debug("SUCCESS verifyUnverifiedHeaders, anyHeaderChanged:{};", anyHeaderChanged);
return anyHeaderChanged;
}
}
use of neo.model.core.Block in project neo-java by coranos.
the class LocalNodeDataSynchronizedUtil method verifyUnverifiedBlocks.
/**
* verify any unverified blocks, by checking for their prevHash in the
* blockchain.
*
* @param localNodeData
* the local node data to use.
* @return true if any block was added to the chain.
*/
public static boolean verifyUnverifiedBlocks(final LocalNodeData localNodeData) {
synchronized (localNodeData) {
boolean anyBlockChanged = false;
final List<Block> putBlockList = new ArrayList<>();
final Set<UInt256> putBlockHashs = new TreeSet<>();
for (final Block block : localNodeData.getUnverifiedBlockPoolSet()) {
if (localNodeData.getBlockDb().containsBlockWithHash(block.prevHash) || block.hash.equals(GenesisBlockUtil.GENESIS_HASH) || putBlockHashs.contains(block.prevHash)) {
putBlockList.add(block);
putBlockHashs.add(block.hash);
anyBlockChanged = true;
localNodeData.updateHighestBlockTime();
final long blockIndex = block.getIndexAsLong();
localNodeData.getVerifiedHeaderPoolMap().remove(blockIndex);
}
}
final Block highestBlock = localNodeData.getBlockDb().getHeaderOfBlockWithMaxIndex();
if (!putBlockList.isEmpty()) {
final boolean forceSynch;
final long localBlockHeight;
if (highestBlock != null) {
localBlockHeight = highestBlock.getIndexAsLong();
} else {
localBlockHeight = 0;
}
final long blockchainBlockHeight = localNodeData.getBlockchainBlockHeight();
final long localBlockHeightLowerBy = blockchainBlockHeight - localBlockHeight;
if (localBlockHeightLowerBy < 10) {
forceSynch = true;
} else {
forceSynch = false;
}
if (LOG.isDebugEnabled()) {
final String msg = "INTERIM put forceSynch={};localBlockHeight:{};blockchainBlockHeight:{};localBlockHeightLowerBy:{};";
LOG.debug(msg, forceSynch, localBlockHeight, blockchainBlockHeight, localBlockHeightLowerBy);
}
localNodeData.getBlockDb().put(forceSynch, putBlockList.toArray(new Block[0]));
}
if (highestBlock != null) {
final long highestIndex = highestBlock.getIndexAsLong();
final Iterator<Block> blockIt = localNodeData.getUnverifiedBlockPoolSet().iterator();
while (blockIt.hasNext()) {
final Block block = blockIt.next();
if (block.getIndexAsLong() <= highestIndex) {
blockIt.remove();
anyBlockChanged = true;
}
}
}
return anyBlockChanged;
}
}
use of neo.model.core.Block in project neo-java by coranos.
the class TestBlockSerialization method assertTransactionTypeEquals.
/**
* reads in the test json for the given test name, gets the tx at the given
* index, and verifys that it's transaction type is the expected transaction
* type.
*
* @param testFunctionName
* the test function name to use.
* @param txIx
* the transaction index to use.
* @param expectedTransactionType
* the expected transaction type to use.
*/
private void assertTransactionTypeEquals(final String testFunctionName, final int txIx, final TransactionType expectedTransactionType) {
try {
final String blockJsonStr = TestUtil.getJsonTestResourceAsString("test", getClass().getSimpleName(), testFunctionName);
final JSONObject blockJson = new JSONObject(blockJsonStr);
final String blockStr = TestUtil.fromHexJsonObject(blockJson);
final byte[] blockBa = Hex.decodeHex(blockStr.toCharArray());
final Block block = new Block(ByteBuffer.wrap(blockBa));
final Transaction tx = block.getTransactionList().get(txIx);
final TransactionType actulaTransactionType = tx.type;
Assert.assertEquals("transaction types must match", expectedTransactionType, actulaTransactionType);
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
use of neo.model.core.Block in project neo-java by coranos.
the class TestBlockSerialization method testGetBlock.
/**
* test reading a miner transaction.
*/
@Test
@Ignore
public void testGetBlock() {
final BlockDb blockDb = new AbstractJsonMockBlockDb() {
@Override
public JSONArray getMockBlockDb() {
return new JSONArray();
}
};
try {
final String testName = "test001TxTypeMiner1";
final int blockIx = 1271700;
final String expectedBlockJsonStr = IOUtils.toString(this.getClass().getResourceAsStream("/neo/rpc/client/test/TestBlockSerialization." + testName + ".json"), "UTF-8");
final Block block = blockDb.getFullBlockFromHeight(blockIx);
final String actualBlockHex = ModelUtil.toHexString(block.toByteArray());
final JSONObject actualBlockJson = TestUtil.toHexJsonObject(actualBlockHex);
final String actualBlockJsonStr = actualBlockJson.toString(2);
Assert.assertEquals("hex encodings of blocks must match", expectedBlockJsonStr, actualBlockJsonStr);
} catch (final Exception e) {
throw new RuntimeException(e);
} finally {
blockDb.close();
}
}
Aggregations