Search in sources :

Example 21 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class BlockchainUtil method addBlockToHistory.

private static void addBlockToHistory(BlockSummary.Builder bs, int shard, BlockImportList bil) {
    try (TimeRecordAuto tra = TimeRecord.openAuto("BlockchainUtil.addBlockToHistoryMap")) {
        if (!bs.getShardHistoryMap().containsKey(shard)) {
            bs.putShardHistoryMap(shard, bil);
        } else {
            BlockImportList.Builder b = BlockImportList.newBuilder();
            b.mergeFrom(bs.getShardHistoryMap().get(shard));
            b.mergeFrom(bil);
            bs.putShardHistoryMap(shard, b.build());
        }
    }
}
Also used : TimeRecordAuto(duckutil.TimeRecordAuto)

Example 22 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class BlockIngestor method ingestBlock.

public boolean ingestBlock(Block blk) throws ValidationException {
    ChainHash blockhash;
    try (TimeRecordAuto tra_blk = TimeRecord.openAuto("BlockIngestor.ingestBlock");
        MetricLog mlog = new MetricLog()) {
        mlog.setOperation("ingest_block");
        mlog.setModule("block_ingestor");
        Validation.checkBlockBasics(node.getParams(), blk, true, false);
        if (blk.getHeader().getShardId() != shard_id) {
            throw new ValidationException("Block for incorrect shard");
        }
        blockhash = new ChainHash(blk.getHeader().getSnowHash());
        mlog.set("hash", blockhash.toString());
        mlog.set("height", blk.getHeader().getBlockHeight());
        mlog.set("shard", blk.getHeader().getShardId());
        mlog.set("size", blk.toByteString().size());
        mlog.set("tx_count", blk.getTransactionsCount());
        if (db.getBlockSummaryMap().containsKey(blockhash.getBytes())) {
            return false;
        }
        ChainHash prevblock = new ChainHash(blk.getHeader().getPrevBlockHash());
        BlockSummary prev_summary;
        if (prevblock.equals(ChainHash.ZERO_HASH)) {
            prev_summary = getStartSummary();
        } else {
            try (TimeRecordAuto tra_prv = TimeRecord.openAuto("BlockIngestor.getPrevSummary")) {
                prev_summary = db.getBlockSummaryMap().get(prevblock.getBytes());
            }
        }
        if (prev_summary == null) {
            return false;
        }
        long tx_body_size = 0;
        for (Transaction tx : blk.getTransactionsList()) {
            tx_body_size += tx.getInnerData().size();
            tx_body_size += tx.getTxHash().size();
        }
        BlockSummary summary = BlockchainUtil.getNewSummary(blk.getHeader(), prev_summary, node.getParams(), blk.getTransactionsCount(), tx_body_size, blk.getImportedBlocksList());
        Validation.deepBlockValidation(node.getParams(), node.getUtxoHashedTrie(), blk, prev_summary);
        summary = saveOtherChainIndexBits(summary, prev_summary, blk);
        if (tx_index) {
            try (TimeRecordAuto tra_tx = TimeRecord.openAuto("BlockIngestor.saveTx")) {
                ByteString block_hash_str = blockhash.getBytes();
                HashMap<ByteString, Transaction> tx_map = new HashMap<>();
                for (Transaction tx : blk.getTransactionsList()) {
                    tx_map.put(tx.getTxHash(), tx);
                }
                db.getTransactionMap().putAll(tx_map);
            }
        }
        try (TimeRecordAuto tra_tx = TimeRecord.openAuto("BlockIngestor.blockSave")) {
            db.getBlockMap().put(blockhash.getBytes(), blk);
            saveBlockChildMapping(blk.getHeader().getPrevBlockHash(), blockhash.getBytes());
            for (ImportedBlock ib : blk.getImportedBlocksList()) {
                // not positive we actually need this, but what the hell
                saveBlockChildMapping(ib.getHeader().getPrevBlockHash(), ib.getHeader().getSnowHash());
                node.getDB().getBlockHeaderMap().put(ib.getHeader().getSnowHash(), ib.getHeader());
            }
            db.setBestBlockAt(blk.getHeader().getShardId(), blk.getHeader().getBlockHeight(), BlockchainUtil.readInteger(summary.getWorkSum()));
            // THIS IS SUPER IMPORTANT!!!!
            // the summary being saved in the summary map acts as a signal that
            // - this block is fully stored
            // - we have the utxo saved
            // - we have the block itself saved
            // - if we are using tx_index, we have the transactions saved
            // - the previous block summary is also saved, which by induction means
            // that we have every block from this one all the way back to block 0
            // In short, after the summary is written, things can depend on this being
            // a valid and correct block that goes all the way back to block 0.
            // It might not be in the main chain, but it can be counted on to be valid chain
            db.getBlockSummaryMap().put(blockhash.getBytes(), summary);
            mlog.set("saved", 1);
        }
        if (ShardUtil.shardSplit(summary, params)) {
            for (int child : ShardUtil.getShardChildIds(summary.getHeader().getShardId())) {
                mlog.set("shard_split", 1);
                try {
                    node.openShard(child);
                } catch (Exception e) {
                    logger.warning("  Unable to open shard: " + e);
                }
            }
        }
        ChainHash prev_hash = new ChainHash(blk.getHeader().getPrevBlockHash());
        logger.info(String.format("New block: Shard %d Height %d %s (tx:%d sz:%d) - from %s", shard_id, blk.getHeader().getBlockHeight(), blockhash, blk.getTransactionsCount(), blk.toByteString().size(), prev_hash));
        node.getBlockForge().tickle(summary);
        SnowUserService u = node.getUserService();
        if (u != null) {
            u.tickleBlocks();
        }
        if (BlockchainUtil.isBetter(chainhead, summary)) {
            mlog.set("head_update", 1);
            chainhead = summary;
            db.getBlockSummaryMap().put(HEAD, summary);
            // System.out.println("UTXO at new root: " + HexUtil.getHexString(summary.getHeader().getUtxoRootHash()));
            // node.getUtxoHashedTrie().printTree(summary.getHeader().getUtxoRootHash());
            updateHeights(summary);
            logger.info(String.format("New chain tip: Shard %d Height %d %s (tx:%d sz:%d)", shard_id, blk.getHeader().getBlockHeight(), blockhash, blk.getTransactionsCount(), blk.toByteString().size()));
            String age = MiscUtils.getAgeSummary(System.currentTimeMillis() - blk.getHeader().getTimestamp());
            logger.info(String.format("  The activated field is %d (%s).  This block was %s ago.", chainhead.getActivatedField(), params.getSnowFieldInfo(chainhead.getActivatedField()).getName(), age));
            if (u != null) {
                u.tickleBlocks();
            }
            node.getMemPool(shard_id).tickleBlocks(new ChainHash(summary.getHeader().getUtxoRootHash()));
            node.getPeerage().sendAllTips(summary.getHeader().getShardId());
        }
    }
    return true;
}
Also used : HashMap(java.util.HashMap) ByteString(com.google.protobuf.ByteString) MetricLog(duckutil.MetricLog) ByteString(com.google.protobuf.ByteString) BlockSummary(snowblossom.proto.BlockSummary) Transaction(snowblossom.proto.Transaction) TimeRecordAuto(duckutil.TimeRecordAuto) ImportedBlock(snowblossom.proto.ImportedBlock)

Example 23 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class ShardBlockForge method getBlockTemplate.

public BlockTemplate getBlockTemplate(SubscribeBlockTemplateRequest mine_to) {
    try (TimeRecordAuto tra_gbt = TimeRecord.openAuto("ShardBlockForge.getBlockTemplate")) {
        last_template_request = System.currentTimeMillis();
        if (node.getBlockIngestor(0).getHead() == null) {
            // Let the old thing do the genesis gag
            return node.getBlockForge(0).getBlockTemplate(mine_to);
        }
        ArrayList<BlockConcept> possible_set = current_top_concepts;
        if (possible_set == null)
            return null;
        if (possible_set.size() == 0)
            return null;
        Random rnd = new Random();
        // Random
        // BlockConcept selected = possible_set.get( rnd.nextInt(possible_set.size()) );
        // First 4
        // BlockConcept selected = possible_set.get( rnd.nextInt(Math.min(4,possible_set.size())) );
        // First
        BlockConcept selected = possible_set.get(0);
        try {
            Block block = fleshOut(selected, mine_to);
            if (block != null) {
                return BlockTemplate.newBuilder().setBlock(block).setAdvancesShard(selected.getAdvancesShard()).build();
            } else {
                return null;
            }
        } catch (ValidationException e) {
            logger.warning("Validation failed in block fleshOut: " + e);
            return null;
        }
    } catch (Throwable t) {
        logger.warning("Exception in getBlockTemplate: " + t);
        t.printStackTrace();
        return null;
    }
}
Also used : Random(java.util.Random) TimeRecordAuto(duckutil.TimeRecordAuto)

Example 24 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class ShardUtxoImport method getImportBlock.

/**
 * Gets the ImportedBlock as if *all* the exported shards were to be imported.
 * That way this can be filtered for what is needed but cached as a whole thing.
 */
public ImportedBlock getImportBlock(ChainHash hash) {
    synchronized (cache) {
        ImportedBlock ib = cache.get(hash);
        if (ib != null)
            return ib;
    }
    try (TimeRecordAuto tra = TimeRecord.openAuto("ShardUtxoImport.getImportBlock")) {
        ImportedBlock ib = null;
        if (node.getDB().getBlockTrust(hash)) {
            ib = node.getDB().getImportedBlockMap().get(hash.getBytes());
        }
        if (ib == null) {
            ImportedBlock.Builder ibb = ImportedBlock.newBuilder();
            Block blk = node.getDB().getBlockMap().get(hash.getBytes());
            if (blk == null)
                return null;
            ibb.setHeader(blk.getHeader());
            Set<Integer> cover_set = ShardUtil.getCoverSet(blk.getHeader().getShardId(), node.getParams());
            Map<Integer, ImportedOutputList.Builder> output_list_map = new TreeMap<>();
            for (Transaction tx : blk.getTransactionsList()) {
                TransactionInner tx_inner = TransactionUtil.getInner(tx);
                ArrayList<ByteString> tx_out_wire_lst;
                try {
                    tx_out_wire_lst = TransactionUtil.extractWireFormatTxOut(tx);
                } catch (ValidationException e) {
                    throw new RuntimeException(e);
                }
                int out_idx = 0;
                for (TransactionOutput tx_out : tx_inner.getOutputsList()) {
                    if (!cover_set.contains(tx_out.getTargetShard())) {
                        int ts = tx_out.getTargetShard();
                        if (!output_list_map.containsKey(ts)) {
                            output_list_map.put(ts, ImportedOutputList.newBuilder());
                        }
                        ImportedOutput io = ImportedOutput.newBuilder().setRawOutput(tx_out_wire_lst.get(out_idx)).setTxId(tx.getTxHash()).setOutIdx(out_idx).build();
                        output_list_map.get(ts).addTxOuts(io);
                    }
                    out_idx++;
                }
            }
            for (Map.Entry<Integer, ImportedOutputList.Builder> me : output_list_map.entrySet()) {
                ibb.putImportOutputs(me.getKey(), me.getValue().build());
            }
            ib = ibb.build();
        }
        try (TimeRecordAuto tra_cache = TimeRecord.openAuto("ShardUtxoImport.getImportBlock_cachesave")) {
            synchronized (cache) {
                cache.put(hash, ib);
            }
        }
        return ib;
    }
}
Also used : ValidationException(snowblossom.lib.ValidationException) ByteString(com.google.protobuf.ByteString) TreeMap(java.util.TreeMap) TimeRecordAuto(duckutil.TimeRecordAuto) TreeMap(java.util.TreeMap) Map(java.util.Map)

Example 25 with TimeRecordAuto

use of duckutil.TimeRecordAuto in project snowblossom by snowblossomcoin.

the class SnowUserService method submitBlock.

@Override
public void submitBlock(Block block, StreamObserver<SubmitReply> responseObserver) {
    try (TimeRecordAuto tra = TimeRecord.openAuto("SnowUserService.submitBlock")) {
        try {
            logger.info("Submit block: " + node.getForgeInfo().getHeaderString(block.getHeader()));
            int shard_id = block.getHeader().getShardId();
            // TODO check to see if we are tracking that shard
            node.getBlockIngestor(shard_id).ingestBlock(block);
            logger.info("Accepted block: " + node.getForgeInfo().getBlockTextSummary(block.getHeader()));
        } catch (ValidationException e) {
            logger.info("Rejecting block: " + e);
            logger.info("Rejected block: " + node.getForgeInfo().getBlockTextSummary(block.getHeader()));
            responseObserver.onNext(SubmitReply.newBuilder().setSuccess(false).setErrorMessage("Rejecting block: " + e).build());
            responseObserver.onCompleted();
            return;
        }
        responseObserver.onNext(SubmitReply.newBuilder().setSuccess(true).build());
        responseObserver.onCompleted();
    }
}
Also used : TimeRecordAuto(duckutil.TimeRecordAuto)

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