Search in sources :

Example 11 with UInt160

use of neo.model.bytes.UInt160 in project neo-java by coranos.

the class TestAccountPng method test001GetAccountSankey.

@Test
public void test001GetAccountSankey() throws JSONException, IOException {
    LOG.debug("STARTED png");
    final LocalNodeData localNodeData = CONTROLLER.getLocalNodeData();
    final BlockDb blockDb = localNodeData.getBlockDb();
    final long maxIndex = blockDb.getHeaderOfBlockWithMaxIndex().getIndexAsLong();
    final CoinData neoData = new CoinData();
    final CoinData gasData = new CoinData();
    final Map<UInt256, CoinData> coinDataMap = new TreeMap<>();
    coinDataMap.put(ModelUtil.NEO_HASH, neoData);
    coinDataMap.put(ModelUtil.GAS_HASH, gasData);
    final File dir = new File("/Users/dps/git-coranos.github.io/neo/charts");
    final Map<UInt256, File> coinFileMap = new TreeMap<>();
    coinFileMap.put(ModelUtil.NEO_HASH, new File(dir, "neo-account.png"));
    coinFileMap.put(ModelUtil.GAS_HASH, new File(dir, "gas-account.png"));
    long startMs = -1;
    for (long blockIx = 0; blockIx <= maxIndex; blockIx++) {
        LOG.debug("STARTED png {} of {} ", blockIx, maxIndex);
        final Block block = blockDb.getFullBlockFromHeight(blockIx);
        for (final Transaction t : block.getTransactionList()) {
            // update assets based on tx inputs.
            for (final CoinReference cr : t.inputs) {
                final TransactionOutput ti = ModelUtil.getTransactionOutput(blockDb, cr);
                if (coinDataMap.containsKey(ti.assetId)) {
                    final CoinData coinData = coinDataMap.get(ti.assetId);
                    final UInt160 input = ti.scriptHash;
                    if (!coinData.accountValueMap.containsKey(input)) {
                        coinData.accountValueMap.put(input, ModelUtil.FIXED8_ZERO);
                        coinData.newAccountSet.add(input);
                    }
                    final Fixed8 oldValue = coinData.accountValueMap.get(input);
                    final Fixed8 newValue = ModelUtil.subtract(ti.value, oldValue);
                    if (newValue.equals(ModelUtil.FIXED8_ZERO)) {
                        coinData.accountValueMap.remove(input);
                    } else {
                        coinData.accountValueMap.put(input, newValue);
                    }
                }
            }
            // update assets based on tx outputs.
            for (int outputIx = 0; outputIx < t.outputs.size(); outputIx++) {
                final TransactionOutput to = t.outputs.get(outputIx);
                final UInt160 output = to.scriptHash;
                if (coinDataMap.containsKey(to.assetId)) {
                    final CoinData coinData = coinDataMap.get(to.assetId);
                    coinData.txAccountSet.add(output);
                    if (!coinData.accountValueMap.containsKey(output)) {
                        coinData.accountValueMap.put(output, ModelUtil.FIXED8_ZERO);
                        coinData.newAccountSet.add(output);
                    }
                    final Fixed8 oldValue = coinData.accountValueMap.get(output);
                    final Fixed8 newValue = ModelUtil.add(oldValue, to.value);
                    if (newValue.equals(ModelUtil.FIXED8_ZERO)) {
                        coinData.accountValueMap.remove(output);
                    } else {
                        coinData.accountValueMap.put(output, newValue);
                    }
                }
            }
            for (final UInt256 assetId : coinDataMap.keySet()) {
                final CoinData coinData = coinDataMap.get(assetId);
                for (final UInt160 txAccount : coinData.txAccountSet) {
                    MapUtil.increment(coinData.newAccountTxCountMap, txAccount);
                }
                coinData.txAccountSet.clear();
            }
        }
        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);
            for (final UInt256 assetId : coinDataMap.keySet()) {
                final CoinData coinData = coinDataMap.get(assetId);
                final List<UInt160> accountList = new ArrayList<>();
                accountList.addAll(coinData.accountValueMap.keySet());
                Collections.sort(accountList, new Comparator<UInt160>() {

                    @Override
                    public int compare(final UInt160 account1, final UInt160 account2) {
                        final Long value1 = coinData.accountValueMap.get(account1).value;
                        final Long value2 = coinData.accountValueMap.get(account2).value;
                        return value1.compareTo(value2);
                    }
                });
                Collections.reverse(accountList);
                long maxTx = 0;
                long totalValue = 0;
                {
                    final List<DrawingData> drawingData = new ArrayList<>();
                    coinData.drawingDataList.add(drawingData);
                    int startDayPixel = 0;
                    int visibleAccountCount = 0;
                    for (final UInt160 account : accountList) {
                        totalValue += coinData.accountValueMap.get(account).value;
                    }
                    for (final UInt160 account : accountList) {
                        final int scaleLength = getScaleLength(coinData.accountValueMap, account, totalValue);
                        if (scaleLength != 0) {
                            visibleAccountCount++;
                        }
                        MapUtil.touch(coinData.newAccountTxCountMap, account);
                        maxTx = Math.max(maxTx, coinData.newAccountTxCountMap.get(account));
                    }
                    final float greenStep = 1.0f / visibleAccountCount;
                    final float redStep = 1.0f / maxTx;
                    float green = 1.0f;
                    for (final UInt160 account : accountList) {
                        final int scaleLength = getScaleLength(coinData.accountValueMap, account, totalValue);
                        if (scaleLength != 0) {
                            final float blue;
                            if (coinData.newAccountSet.contains(account)) {
                                blue = 1.0f;
                            } else {
                                blue = 0.0f;
                            }
                            float red = 0.0f;
                            if (coinData.newAccountTxCountMap.containsKey(account)) {
                                red = redStep * coinData.newAccountTxCountMap.get(account);
                            } else {
                                red = 0.0f;
                            }
                            drawingData.add(new DrawingData(startDayPixel, scaleLength, red, green, blue));
                        }
                        green -= greenStep;
                        startDayPixel += scaleLength;
                    }
                }
                final BufferedImage im = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
                final Graphics2D g = (Graphics2D) im.getGraphics();
                g.scale((WIDTH * 1.0) / coinData.drawingDataList.size(), 1.0 / HEIGHT_SUBPIXELS);
                for (int x = 0; x < coinData.drawingDataList.size(); x++) {
                    final List<DrawingData> drawingData = coinData.drawingDataList.get(x);
                    for (final DrawingData drawing : drawingData) {
                        g.setColor(new Color(drawing.r, drawing.g, drawing.b));
                        g.fillRect(x, drawing.y, 1, drawing.h);
                        g.setColor(Color.black);
                        g.drawLine(x, drawing.y, x + 1, drawing.y);
                    }
                }
                g.dispose();
                final File file = coinFileMap.get(assetId);
                ImageIO.write(im, "png", file);
                LOG.info("INTERIM file {}, {} of {}, date {}, accountList {}, tx {}, value {}", file.getName(), INTEGER_FORMAT.format(blockIx), INTEGER_FORMAT.format(maxIndex), targetDateStr, INTEGER_FORMAT.format(accountList.size()), INTEGER_FORMAT.format(maxTx), INTEGER_FORMAT.format(totalValue / ModelUtil.DECIMAL_DIVISOR));
                startMs = blockTs.getTime();
                coinData.newAccountSet.clear();
                coinData.newAccountTxCountMap.clear();
            }
        }
    }
    LOG.debug("SUCCESS png");
}
Also used : TransactionOutput(neo.model.core.TransactionOutput) ArrayList(java.util.ArrayList) Timestamp(java.sql.Timestamp) BufferedImage(java.awt.image.BufferedImage) UInt160(neo.model.bytes.UInt160) Fixed8(neo.model.bytes.Fixed8) ArrayList(java.util.ArrayList) List(java.util.List) CoinReference(neo.model.core.CoinReference) LocalNodeData(neo.network.model.LocalNodeData) Color(java.awt.Color) TreeMap(java.util.TreeMap) Graphics2D(java.awt.Graphics2D) Transaction(neo.model.core.Transaction) Block(neo.model.core.Block) BlockDb(neo.model.db.BlockDb) File(java.io.File) UInt256(neo.model.bytes.UInt256) Test(org.junit.Test)

Example 12 with UInt160

use of neo.model.bytes.UInt160 in project neo-java by coranos.

the class BlockDbMapDbImpl method updateAssetAndValueByAccountMap.

/**
 * updates the asset and value by account map.
 *
 * @param block
 *            the block to update.
 * @param reverse
 *            if true, reverse the update.
 */
private void updateAssetAndValueByAccountMap(final Block block, final boolean reverse) {
    final BTreeMap<byte[], byte[]> assetAndValueByAccountMap = getAssetAndValueByAccountMap();
    final BTreeMap<byte[], byte[]> transactionByAccountAndIndexMap = getTransactionByAccountAndIndexMap();
    final BTreeMap<byte[], Long> transactionByAccountMaxIndexMap = getTransactionByAccountMaxIndexMap();
    final BTreeMap<byte[], Boolean> transactionOutputSpentStateMap = getTransactionOutputSpentStateMap();
    LOG.debug("updateAssetAndValueByAccountMap STARTED block;{};reverse;{};numberOfAccounts:{}", block.getIndexAsLong(), reverse, assetAndValueByAccountMap.size());
    for (final Transaction t : block.getTransactionList()) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("updateAssetAndValueByAccountMap INTERIM tx:{}", t.getHash());
        }
        for (final CoinReference cr : t.inputs) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("updateAssetAndValueByAccountMap INTERIM cr:{}", cr.toJSONObject());
            }
            final byte[] crBa = cr.toByteArray();
            if (!transactionOutputSpentStateMap.containsKey(crBa)) {
                throw new RuntimeException("referenced transaction output was never a transaction input:" + cr);
            }
            final boolean oldSpendState;
            final boolean newSpendState;
            if (reverse) {
                oldSpendState = true;
                newSpendState = false;
            } else {
                oldSpendState = false;
                newSpendState = true;
            }
            if (transactionOutputSpentStateMap.get(crBa) == oldSpendState) {
                transactionOutputSpentStateMap.put(crBa, newSpendState);
                final UInt256 prevHashReversed = cr.prevHash.reverse();
                final Transaction tiTx = getTransactionWithHash(prevHashReversed);
                if (tiTx == null) {
                    throw new RuntimeException("no transaction with prevHash:" + prevHashReversed + " in block[1] " + block.hash + " index[1] " + block.getIndexAsLong());
                }
                final int prevIndex = cr.prevIndex.asInt();
                if (prevIndex >= tiTx.outputs.size()) {
                    throw new RuntimeException("prevIndex:" + prevIndex + " exceeds output size:" + tiTx.outputs.size() + "; in block[2] " + block.hash + " index[2] " + block.getIndexAsLong());
                }
                final TransactionOutput ti = tiTx.outputs.get(prevIndex);
                final UInt160 input = ti.scriptHash;
                final byte[] inputBa = input.toByteArray();
                final Map<UInt256, Fixed8> accountAssetValueMap = ensureAccountExists(assetAndValueByAccountMap, inputBa);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("TI beforeMap {}", accountAssetValueMap);
                }
                if (!accountAssetValueMap.containsKey(ti.assetId)) {
                    accountAssetValueMap.put(ti.assetId, ModelUtil.FIXED8_ZERO);
                }
                final Fixed8 oldValue = accountAssetValueMap.get(ti.assetId);
                final Fixed8 newValue;
                if (reverse) {
                    newValue = ModelUtil.add(ti.value, oldValue);
                } else {
                    newValue = ModelUtil.subtract(ti.value, oldValue);
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM input;{};", ModelUtil.scriptHashToAddress(input));
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM ti.assetId:{} oldValue:{};", ti.assetId, oldValue);
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM ti.assetId:{} to.value:{};", ti.assetId, ti.value);
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM ti.assetId:{} newValue:{};", ti.assetId, newValue);
                }
                if (newValue.equals(ModelUtil.FIXED8_ZERO)) {
                    accountAssetValueMap.remove(ti.assetId);
                } else {
                    accountAssetValueMap.put(ti.assetId, newValue);
                }
                if (accountAssetValueMap.isEmpty()) {
                    assetAndValueByAccountMap.remove(inputBa);
                } else {
                    putAssetValueMap(assetAndValueByAccountMap, inputBa, accountAssetValueMap);
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug("TI afterMap {}", ensureAccountExists(assetAndValueByAccountMap, inputBa));
                }
            } else {
                if (reverse) {
                    throw new RuntimeException("referenced transaction output is not already spent:" + cr);
                } else {
                    throw new RuntimeException("referenced transaction output is already spent:" + cr);
                }
            }
        }
        try {
            for (int outputIx = 0; outputIx < t.outputs.size(); outputIx++) {
                final TransactionOutput to = t.outputs.get(outputIx);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM to:{}", to.toJSONObject());
                }
                final UInt160 output = to.scriptHash;
                final byte[] outputBa = output.toByteArray();
                final Map<UInt256, Fixed8> accountAssetValueMap = ensureAccountExists(assetAndValueByAccountMap, outputBa);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("TO beforeMap {}", accountAssetValueMap);
                }
                if (!accountAssetValueMap.containsKey(to.assetId)) {
                    accountAssetValueMap.put(to.assetId, ModelUtil.FIXED8_ZERO);
                }
                final Fixed8 oldValue = accountAssetValueMap.get(to.assetId);
                if (LOG.isDebugEnabled()) {
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM output;{};", ModelUtil.scriptHashToAddress(output));
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM to.assetId:{} oldValue:{};", to.assetId, oldValue);
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM to.assetId:{} to.value:{};", to.assetId, to.value);
                }
                final Fixed8 newValue;
                if (reverse) {
                    newValue = ModelUtil.subtract(to.value, oldValue);
                } else {
                    newValue = ModelUtil.add(oldValue, to.value);
                }
                accountAssetValueMap.put(to.assetId, newValue);
                if (accountAssetValueMap.isEmpty()) {
                    assetAndValueByAccountMap.remove(outputBa);
                } else {
                    putAssetValueMap(assetAndValueByAccountMap, outputBa, accountAssetValueMap);
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug("updateAssetAndValueByAccountMap INTERIM to.assetId:{} newValue:{};", to.assetId, newValue);
                    LOG.debug("TO afterMap {}", ensureAccountExists(assetAndValueByAccountMap, outputBa));
                }
                final CoinReference cr = new CoinReference(t.getHash().reverse(), new UInt16(outputIx));
                if (reverse) {
                    transactionOutputSpentStateMap.remove(cr.toByteArray());
                } else {
                    transactionOutputSpentStateMap.put(cr.toByteArray(), false);
                }
            }
            final byte[] tBa = t.toByteArray();
            final long index;
            if (transactionByAccountMaxIndexMap.containsKey(tBa)) {
                index = transactionByAccountMaxIndexMap.get(tBa);
            } else {
                index = 0;
            }
            transactionByAccountMaxIndexMap.put(tBa, index + 1);
            final byte[] accountKeyBa = getAccountKey(tBa, index);
            transactionByAccountAndIndexMap.put(accountKeyBa, tBa);
        } catch (final RuntimeException e) {
            final String msg = "error processing transaction type " + t.type + " hash " + t.getHash();
            throw new RuntimeException(msg, e);
        }
    }
    LOG.debug("updateAssetAndValueByAccountMap SUCCESS block;{};numberOfAccounts:{}", block.getIndexAsLong(), assetAndValueByAccountMap.size());
}
Also used : CoinReference(neo.model.core.CoinReference) TransactionOutput(neo.model.core.TransactionOutput) Transaction(neo.model.core.Transaction) UInt160(neo.model.bytes.UInt160) Fixed8(neo.model.bytes.Fixed8) UInt16(neo.model.bytes.UInt16) UInt256(neo.model.bytes.UInt256)

Example 13 with UInt160

use of neo.model.bytes.UInt160 in project neo-java by coranos.

the class BlockDbMapDbImpl method getAccountAssetValueMap.

@Override
public Map<UInt160, Map<UInt256, Fixed8>> getAccountAssetValueMap() {
    LOG.info("getAccountAssetValueMap STARTED");
    final Map<UInt160, Map<UInt256, Fixed8>> accountAssetValueMap = new TreeMap<>();
    final BTreeMap<byte[], byte[]> assetAndValueByAccountMap = getAssetAndValueByAccountMap();
    LOG.info("getAccountAssetValueMap INTERIM assetAndValueByAccountMap.size:{};", assetAndValueByAccountMap.size());
    for (final byte[] key : assetAndValueByAccountMap.getKeys()) {
        final byte[] value = assetAndValueByAccountMap.get(key);
        final UInt160 account = new UInt160(key);
        final Map<UInt256, Fixed8> map = getAssetValueMapFromByteArray(value);
        accountAssetValueMap.put(account, map);
    }
    LOG.info("getAccountAssetValueMap SUCCESS, count:{}", accountAssetValueMap.size());
    return accountAssetValueMap;
}
Also used : UInt160(neo.model.bytes.UInt160) Fixed8(neo.model.bytes.Fixed8) TreeMap(java.util.TreeMap) BTreeMap(org.mapdb.BTreeMap) Map(java.util.Map) TreeMap(java.util.TreeMap) BTreeMap(org.mapdb.BTreeMap) UInt256(neo.model.bytes.UInt256)

Example 14 with UInt160

use of neo.model.bytes.UInt160 in project neo-java by coranos.

the class RpcServerUtil method onGetCityOfZionBalance.

/**
 * return the balance of the address.
 *
 * @param controller
 *            the controller to use.
 * @param address
 *            the address to use.
 * @return the balance of the address.
 */
private static JSONObject onGetCityOfZionBalance(final LocalControllerNode controller, final String address) {
    final UInt160 scriptHash = ModelUtil.addressToScriptHash(address);
    if (LOG.isTraceEnabled()) {
        LOG.trace("onGetCityOfZionBalance.scriptHash:{}", scriptHash);
    }
    try {
        final BlockDb blockDb = controller.getLocalNodeData().getBlockDb();
        final Map<UInt256, Fixed8> assetValueMap = blockDb.getAssetValueMap(scriptHash);
        final Map<UInt256, Map<TransactionOutput, CoinReference>> transactionOutputListMap = blockDb.getUnspentTransactionOutputListMap(scriptHash);
        if (assetValueMap == null) {
            final JSONObject response = new JSONObject();
            response.put(GAS, new JSONObject());
            response.put(NEO, new JSONObject());
            response.put(NET, controller.getLocalNodeData().getNetworkName());
            return response;
        }
        final Fixed8 neo = assetValueMap.get(ModelUtil.NEO_HASH);
        final Fixed8 gas = assetValueMap.get(ModelUtil.GAS_HASH);
        final JSONObject response = new JSONObject();
        final JSONObject neoJo = new JSONObject();
        neoJo.put(UNSPENT, toUnspentJSONArray(transactionOutputListMap.get(ModelUtil.NEO_HASH), false));
        neoJo.put(BALANCE, neo);
        final JSONObject gasJo = new JSONObject();
        gasJo.put(UNSPENT, toUnspentJSONArray(transactionOutputListMap.get(ModelUtil.GAS_HASH), true));
        gasJo.put(BALANCE, gas);
        response.put(GAS, gasJo);
        response.put(NEO, neoJo);
        response.put(NET, controller.getLocalNodeData().getNetworkName());
        return response;
    } catch (final RuntimeException e) {
        LOG.error("onGetCityOfZionBalance", e);
        final JSONObject response = new JSONObject();
        if (e.getMessage() == null) {
            response.put(ERROR, e.getClass().getName());
        } else {
            response.put(ERROR, e.getMessage());
        }
        response.put(EXPECTED, EXPECTED_GENERIC_HEX);
        response.put(ACTUAL, address);
        return response;
    }
}
Also used : JSONObject(org.json.JSONObject) UInt160(neo.model.bytes.UInt160) Fixed8(neo.model.bytes.Fixed8) BlockDb(neo.model.db.BlockDb) Map(java.util.Map) TreeMap(java.util.TreeMap) UInt256(neo.model.bytes.UInt256)

Example 15 with UInt160

use of neo.model.bytes.UInt160 in project neo-java by coranos.

the class RpcServerUtil method getAddressAssetMap.

/**
 * returns the address asset map.
 *
 * @param blockDb
 *            the block database to use.
 * @param transaction
 *            the transaction to use.
 * @return the address asset map.
 */
public static Map<UInt160, Map<UInt256, Long>> getAddressAssetMap(final BlockDb blockDb, final Transaction transaction) {
    final Map<UInt160, Map<UInt256, Long>> friendAssetMap = new TreeMap<>();
    for (final CoinReference cr : transaction.inputs) {
        final UInt256 prevHashReversed = cr.prevHash.reverse();
        final Transaction tiTx = blockDb.getTransactionWithHash(prevHashReversed);
        if (tiTx == null) {
            throw new RuntimeException("no transaction with prevHash:" + prevHashReversed);
        }
        final TransactionOutput ti = tiTx.outputs.get(cr.prevIndex.asInt());
        final UInt160 input = ti.scriptHash;
        if ((ti.assetId.equals(ModelUtil.NEO_HASH)) || (ti.assetId.equals(ModelUtil.GAS_HASH))) {
            MapUtil.increment(friendAssetMap, input, ti.assetId, ti.value.value, TreeMap.class);
        }
    }
    for (final TransactionOutput to : transaction.outputs) {
        final UInt160 output = to.scriptHash;
        if ((to.assetId.equals(ModelUtil.NEO_HASH)) || (to.assetId.equals(ModelUtil.GAS_HASH))) {
            MapUtil.increment(friendAssetMap, output, to.assetId, -to.value.value, TreeMap.class);
        }
    }
    return friendAssetMap;
}
Also used : CoinReference(neo.model.core.CoinReference) TransactionOutput(neo.model.core.TransactionOutput) Transaction(neo.model.core.Transaction) UInt160(neo.model.bytes.UInt160) TreeMap(java.util.TreeMap) Map(java.util.Map) TreeMap(java.util.TreeMap) UInt256(neo.model.bytes.UInt256)

Aggregations

UInt160 (neo.model.bytes.UInt160)16 UInt256 (neo.model.bytes.UInt256)11 Fixed8 (neo.model.bytes.Fixed8)10 TransactionOutput (neo.model.core.TransactionOutput)9 TreeMap (java.util.TreeMap)8 Transaction (neo.model.core.Transaction)8 Map (java.util.Map)7 JSONObject (org.json.JSONObject)7 BlockDb (neo.model.db.BlockDb)5 CoinReference (neo.model.core.CoinReference)4 JSONArray (org.json.JSONArray)4 Block (neo.model.core.Block)3 Color (java.awt.Color)1 Graphics2D (java.awt.Graphics2D)1 BufferedImage (java.awt.image.BufferedImage)1 File (java.io.File)1 Timestamp (java.sql.Timestamp)1 ArrayList (java.util.ArrayList)1 LinkedHashSet (java.util.LinkedHashSet)1 List (java.util.List)1