Search in sources :

Example 21 with UInt256

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

the class MockUtil method getTransactionOutput001.

public static TransactionOutput getTransactionOutput001() {
    final int minSize = UInt256.SIZE + UInt160.SIZE + Fixed8.SIZE;
    final byte[] ba = new byte[minSize];
    final UInt256 neoHash = ModelUtil.NEO_HASH;
    final byte[] neoBytes = neoHash.getBytesCopy();
    ArrayUtils.reverse(neoBytes);
    System.arraycopy(neoBytes, 0, ba, 0, neoBytes.length);
    return new TransactionOutput(ByteBuffer.wrap(ba));
}
Also used : TransactionOutput(neo.model.core.TransactionOutput) UInt256(neo.model.bytes.UInt256)

Example 22 with UInt256

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

the class MockUtil method getCoinReference001.

public static CoinReference getCoinReference001() {
    final int minSize = UInt256.SIZE + UInt16.SIZE;
    final byte[] ba = new byte[minSize];
    final UInt256 txHash = GenesisBlockUtil.GENESIS_BLOCK.getTransactionList().get(3).getHash();
    System.arraycopy(txHash.getBytesCopy(), 0, ba, 0, txHash.getByteLength());
    return new CoinReference(ByteBuffer.wrap(ba));
}
Also used : CoinReference(neo.model.core.CoinReference) UInt256(neo.model.bytes.UInt256)

Example 23 with UInt256

use of neo.model.bytes.UInt256 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 24 with UInt256

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

the class BlockDbMapDbImpl method getAssetValueMapFromByteArray.

/**
 * converts a byte array into a map of assets and values.
 *
 * @param ba
 *            the byte array to use.
 * @return the map.
 */
private Map<UInt256, Fixed8> getAssetValueMapFromByteArray(final byte[] ba) {
    final Map<UInt256, Fixed8> map = new TreeMap<>();
    final ByteBuffer bb = ByteBuffer.wrap(ba);
    final int size = ModelUtil.getBigInteger(bb).intValue();
    while (map.size() < size) {
        final UInt256 key = new UInt256(ModelUtil.getVariableLengthByteArray(bb));
        final Fixed8 value = new Fixed8(ByteBuffer.wrap(ModelUtil.getVariableLengthByteArray(bb)));
        map.put(key, value);
    }
    return map;
}
Also used : Fixed8(neo.model.bytes.Fixed8) TreeMap(java.util.TreeMap) BTreeMap(org.mapdb.BTreeMap) ByteBuffer(java.nio.ByteBuffer) UInt256(neo.model.bytes.UInt256)

Example 25 with UInt256

use of neo.model.bytes.UInt256 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)

Aggregations

UInt256 (neo.model.bytes.UInt256)36 TransactionOutput (neo.model.core.TransactionOutput)15 JSONObject (org.json.JSONObject)14 TreeMap (java.util.TreeMap)13 Fixed8 (neo.model.bytes.Fixed8)13 Transaction (neo.model.core.Transaction)13 Map (java.util.Map)11 UInt160 (neo.model.bytes.UInt160)11 CoinReference (neo.model.core.CoinReference)11 Block (neo.model.core.Block)8 JSONArray (org.json.JSONArray)7 UInt16 (neo.model.bytes.UInt16)5 BlockDb (neo.model.db.BlockDb)5 ArrayList (java.util.ArrayList)3 Header (neo.model.core.Header)3 BTreeMap (org.mapdb.BTreeMap)3 JdbcTemplate (org.springframework.jdbc.core.JdbcTemplate)3 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 InvPayload (neo.model.network.InvPayload)2 Color (java.awt.Color)1