Search in sources :

Example 1 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class ShardBlockForge method fleshOut.

public Block fleshOut(BlockConcept concept, SubscribeBlockTemplateRequest mine_to) throws ValidationException {
    try (TimeRecordAuto tra_blk = TimeRecord.openAuto("ShardBlockForge.fleshOut")) {
        Block.Builder block_builder = Block.newBuilder();
        BlockHeader.Builder header_builder = BlockHeader.newBuilder().mergeFrom(concept.getHeader());
        BlockSummary prev_summary = concept.getPrevSummary();
        long time = System.currentTimeMillis();
        BigInteger target = PowUtil.calcNextTarget(prev_summary, params, time);
        header_builder.setTimestamp(time);
        header_builder.setTarget(BlockchainUtil.targetBigIntegerToBytes(target));
        ChainHash prev_utxo_root = new ChainHash(prev_summary.getHeader().getUtxoRootHash());
        if (header_builder.getShardId() != prev_summary.getHeader().getShardId())
            if (!ShardUtil.getInheritSet(header_builder.getShardId()).contains(prev_summary.getHeader().getShardId())) {
                // If we are a split and do not inherit, start with clean slate
                prev_utxo_root = new ChainHash(HashUtils.hashOfEmpty());
            }
        UtxoUpdateBuffer utxo_buffer = new UtxoUpdateBuffer(node.getUtxoHashedTrie(), prev_utxo_root);
        // Add import shards to utxo buffer
        block_builder.addAllImportedBlocks(concept.getImportedBlocks());
        for (ImportedBlock ib : block_builder.getImportedBlocksList()) {
            for (ImportedOutputList lst : ib.getImportOutputsMap().values()) {
                utxo_buffer.addOutputs(lst);
            }
        }
        // Copy in just for size estimate - we will do it again later
        block_builder.setHeader(header_builder.build());
        int max_tx_fill_size = node.getParams().getMaxBlockSize() - block_builder.build().toByteString().size() - 8192;
        List<Transaction> regular_transactions = node.getMemPool(header_builder.getShardId()).getTransactionsForBlock(prev_utxo_root, max_tx_fill_size);
        long fee_sum = 0L;
        Set<Integer> shard_cover_set = ShardUtil.getCoverSet(header_builder.getShardId(), params);
        Map<Integer, UtxoUpdateBuffer> export_utxo_buffer = new TreeMap<>();
        for (Transaction tx : regular_transactions) {
            fee_sum += Validation.deepTransactionCheck(tx, utxo_buffer, header_builder.build(), params, shard_cover_set, export_utxo_buffer);
        }
        Transaction coinbase = BlockForge.buildCoinbase(params, header_builder.build(), fee_sum, mine_to, header_builder.getShardId());
        Validation.deepTransactionCheck(coinbase, utxo_buffer, header_builder.build(), params, shard_cover_set, export_utxo_buffer);
        block_builder.addTransactions(coinbase);
        block_builder.addAllTransactions(regular_transactions);
        // Save export UTXO data
        for (int export_shard_id : export_utxo_buffer.keySet()) {
            UtxoUpdateBuffer export_buffer = export_utxo_buffer.get(export_shard_id);
            header_builder.putShardExportRootHash(export_shard_id, export_buffer.simulateUpdates().getBytes());
        }
        int tx_size_total = 0;
        LinkedList<ChainHash> tx_list = new LinkedList<ChainHash>();
        for (Transaction tx : block_builder.getTransactionsList()) {
            tx_list.add(new ChainHash(tx.getTxHash()));
            tx_size_total += tx.getInnerData().size() + tx.getTxHash().size();
        }
        if (header_builder.getVersion() == 2) {
            header_builder.setTxDataSizeSum(tx_size_total);
            header_builder.setTxCount(tx_list.size());
        }
        header_builder.setMerkleRootHash(DigestUtil.getMerkleRootForTxList(tx_list).getBytes());
        header_builder.setUtxoRootHash(utxo_buffer.simulateUpdates().getBytes());
        block_builder.setHeader(header_builder.build());
        return block_builder.build();
    }
}
Also used : TreeMap(java.util.TreeMap) LinkedList(java.util.LinkedList) BigInteger(java.math.BigInteger) TimeRecordAuto(duckutil.TimeRecordAuto) BigInteger(java.math.BigInteger)

Example 2 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class ShardBlockForge method exploreCoordinatorSpecific.

private void exploreCoordinatorSpecific(BlockHeader prev_header, int coord_shard, TreeSet<BlockConcept> concepts) {
    BlockSummary prev = node.getForgeInfo().getSummary(prev_header.getSnowHash());
    if (prev == null)
        return;
    synchronized (signature_cache) {
        signature_cache.put(getSignature(prev), true);
    }
    List<BlockConcept> concept_list = initiateBlockConcepts(prev);
    logger.info("exploreCoordinatorSpecific concepts: " + concept_list.size());
    for (BlockConcept bc : concept_list) {
        // If it is a shard we actually work on
        if (node.getInterestShards().contains(bc.getHeader().getShardId())) {
            // If we are splitting into a non-coordinator shard, don't add any other imports
            if (isCoordinator(bc.getHeader().getShardId())) {
                // We might be in a different shard from the parent
                int local_coord_shard = bc.getHeader().getShardId();
                // Make a list sorted by block height of things we could possible include
                ListMultimap<Integer, BlockHeader> possible_import_blocks = MultimapBuilder.treeKeys().arrayListValues().build();
                Set<ChainHash> possible_hashes = new HashSet<>();
                for (BlockHeader current_import_head : prev.getImportedShardsMap().values()) {
                    int depth = node.getParams().getMaxShardSkewHeight() * 2;
                    depth = 3;
                    possible_hashes.addAll(node.getForgeInfo().climb(new ChainHash(current_import_head.getSnowHash()), -1, depth));
                }
                logger.info("Possible import hashes: " + possible_hashes.size());
                for (ChainHash ch : possible_hashes) {
                    BlockHeader blk_h = node.getForgeInfo().getHeader(ch);
                    if (blk_h != null)
                        if (blk_h.getBlockHeight() + node.getParams().getMaxShardSkewHeight() * 2 >= prev_header.getBlockHeight()) {
                            // exclude things that import coord blocks that do not match this one
                            boolean invalid_coord_import = false;
                            if (blk_h.getShardImportMap().containsKey(local_coord_shard)) {
                                for (ByteString hash : blk_h.getShardImportMap().get(local_coord_shard).getHeightMap().values()) {
                                    BlockHeader check = node.getForgeInfo().getHeader(new ChainHash(hash));
                                    if ((check == null) || (!node.getForgeInfo().isInChain(prev_header, check))) {
                                        invalid_coord_import = true;
                                    }
                                }
                            }
                            if (!invalid_coord_import) {
                                possible_import_blocks.put(blk_h.getBlockHeight(), blk_h);
                            }
                        }
                }
                logger.info("Possible import blocks: " + possible_import_blocks.size());
                for (BlockHeader imp_blk : possible_import_blocks.values()) {
                    logger.info(String.format("Checking block for import: s:%d h:%d - %s", imp_blk.getShardId(), imp_blk.getBlockHeight(), new ChainHash(imp_blk.getSnowHash())));
                    try (TimeRecordAuto tra = TimeRecord.openAuto("ShardBlockForge.coordBuild")) {
                        // Not in the cover set from this coordinator
                        if (!ShardUtil.getCoverSet(local_coord_shard, node.getParams()).contains(imp_blk.getShardId())) {
                            List<BlockHeader> imp_seq = node.getForgeInfo().getImportPath(bc.getShardHeads(), imp_blk);
                            if (dancer.isCompliant(imp_blk))
                                if (imp_seq != null)
                                    if (imp_seq.size() == 1) {
                                        BlockHeader join_point = node.getForgeInfo().getLatestShard(imp_blk, local_coord_shard);
                                        if (node.getForgeInfo().isInChain(prev_header, join_point)) {
                                            try {
                                                bc = bc.importShard(imp_blk);
                                            } catch (ValidationException e) {
                                                logger.warning("Build validation: " + e);
                                            }
                                        }
                                    }
                        }
                    }
                }
            }
            considerAdd(concepts, bc);
        }
    }
}
Also used : ByteString(com.google.protobuf.ByteString) BigInteger(java.math.BigInteger) TimeRecordAuto(duckutil.TimeRecordAuto) HashSet(java.util.HashSet)

Example 3 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class ShardBlockForge method initiateBlockConcepts.

/**
 * create concepts for blocks that could be generated based on this one.
 * Usually one block.  Sometimes two, if the prev_summary is a block just about to shard.
 */
public List<BlockConcept> initiateBlockConcepts(BlockSummary prev_summary) {
    try (TimeRecordAuto tra_blk = TimeRecord.openAuto("ShardBlockForge.initiateBlockConcepts")) {
        LinkedList<BlockConcept> lst = new LinkedList<>();
        BlockHeader.Builder header_builder = BlockHeader.newBuilder();
        header_builder.setShardId(prev_summary.getHeader().getShardId());
        header_builder.setBlockHeight(prev_summary.getHeader().getBlockHeight() + 1);
        header_builder.setPrevBlockHash(prev_summary.getHeader().getSnowHash());
        if (header_builder.getBlockHeight() >= params.getActivationHeightShards()) {
            header_builder.setVersion(2);
        } else {
            header_builder.setVersion(1);
        }
        long time = System.currentTimeMillis();
        BigInteger target = PowUtil.calcNextTarget(prev_summary, params, time);
        header_builder.setTimestamp(time);
        header_builder.setTarget(BlockchainUtil.targetBigIntegerToBytes(target));
        header_builder.setSnowField(prev_summary.getActivatedField());
        if (ShardUtil.shardSplit(prev_summary, params)) {
            // split
            for (int c : ShardUtil.getShardChildIds(prev_summary.getHeader().getShardId())) {
                if (node.getInterestShards().contains(c)) {
                    try {
                        node.openShard(c);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    header_builder.setShardId(c);
                    lst.add(new BlockConcept(prev_summary, header_builder.build()));
                }
            }
        } else {
            lst.add(new BlockConcept(prev_summary, header_builder.build()));
        }
        return lst;
    }
}
Also used : TimeRecordAuto(duckutil.TimeRecordAuto) BigInteger(java.math.BigInteger) LinkedList(java.util.LinkedList)

Example 4 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class ShardUtxoImport method getImportBlockForTarget.

public ImportedBlock getImportBlockForTarget(ChainHash hash, int target_shard) {
    try (TimeRecordAuto tra = TimeRecord.openAuto("ShardUtxoImport.getImportBlockForTarget")) {
        ImportedBlock src = getImportBlock(hash);
        if (src == null)
            return null;
        ImportedBlock.Builder ibb = ImportedBlock.newBuilder();
        ibb.setHeader(src.getHeader());
        // Copy the entries from our cover set into this object
        for (int s : ShardUtil.getCoverSet(target_shard, node.getParams())) {
            if (src.getImportOutputsMap().containsKey(s)) {
                ibb.putImportOutputs(s, src.getImportOutputsMap().get(s));
            }
        }
        return ibb.build();
    }
}
Also used : TimeRecordAuto(duckutil.TimeRecordAuto)

Example 5 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class LoadTestShard method runLoadTestInner.

private void runLoadTestInner() throws Exception {
    try (TimeRecordAuto tra = TimeRecord.openAuto("LoadTestShard.runLoadTestInner")) {
        try (TimeRecordAuto tra_ns = TimeRecord.openAuto("LoadTestShard.nodeStatus")) {
            NodeStatus ns = client.getNodeStatus();
            active_shards.clear();
            active_shards.addAll(ns.getNetworkActiveShardsList());
            if (preferred_shard >= 0) {
                Set<Integer> pref_children = ShardUtil.getChildrenRecursive(preferred_shard, client.getParams().getMaxShardId());
                preferred_shards.clear();
                for (int s : active_shards) {
                    if (pref_children.contains(s)) {
                        preferred_shards.add(s);
                    }
                }
            }
            logger.info(String.format("Active shards: %s Preferred shards: %s", active_shards, preferred_shards));
        }
        SplittableRandom rnd = new SplittableRandom();
        TreeMap<Integer, LinkedList<TransactionBridge>> spendable_map = new TreeMap<>();
        for (TransactionBridge br : client.getAllSpendable()) {
            if (!br.spent)
                if ((use_pending) || (br.isConfirmed())) {
                    if (!spendable_map.containsKey(br.shard_id)) {
                        spendable_map.put(br.shard_id, new LinkedList<TransactionBridge>());
                    }
                    spendable_map.get(br.shard_id).add(br);
                }
        }
        // Shuffle
        for (LinkedList<TransactionBridge> lst : spendable_map.values()) Collections.shuffle(lst);
        int sent = 0;
        long start_send_time = System.currentTimeMillis();
        long end_send_time = start_send_time + 600L * 1000L;
        while (spendable_map.size() > 0) {
            if (trySend(spendable_map, rnd))
                sent++;
            if (sent >= 5000)
                break;
            if (System.currentTimeMillis() > end_send_time)
                break;
        }
        if (sent == 0) {
            System.out.println("Unable to send any, sleeping");
            Thread.sleep(5000);
        }
    } finally {
        System.out.println("-----------------------------------------------");
        time_record.printReport(System.out);
        time_record.reset();
        DecimalFormat df = new DecimalFormat("0.0");
        System.out.println("Sent: " + rate_sent.getReportShort(df));
        System.out.println("Accepted: " + rate_accepted.getReportShort(df));
        System.out.println("Rejected: " + rate_rejected.getReportShort(df));
    }
}
Also used : DecimalFormat(java.text.DecimalFormat) TreeMap(java.util.TreeMap) LinkedList(java.util.LinkedList) TimeRecordAuto(duckutil.TimeRecordAuto) SplittableRandom(java.util.SplittableRandom)

Aggregations

TimeRecordAuto (duckutil.TimeRecordAuto)31 ByteString (com.google.protobuf.ByteString)11 LinkedList (java.util.LinkedList)10 BigInteger (java.math.BigInteger)7 TreeMap (java.util.TreeMap)7 MessageDigest (java.security.MessageDigest)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 ArrayList (java.util.ArrayList)2 TreeSet (java.util.TreeSet)2 CodedInputStream (com.google.protobuf.CodedInputStream)1 MetricLog (duckutil.MetricLog)1 DecimalFormat (java.text.DecimalFormat)1 HashSet (java.util.HashSet)1 Random (java.util.Random)1 SplittableRandom (java.util.SplittableRandom)1 ValidationException (snowblossom.lib.ValidationException)1 HashedTrie (snowblossom.lib.trie.HashedTrie)1 TrieDBMem (snowblossom.lib.trie.TrieDBMem)1