Search in sources :

Example 1 with BlockSummary

use of snowblossom.proto.BlockSummary in project snowblossom by snowblossomcoin.

the class BlockIngestorTest method testFirstBlockSummary.

@Test
public void testFirstBlockSummary() {
    NetworkParams params = new NetworkParamsTestnet();
    BlockHeader header = BlockHeader.newBuilder().setTarget(BlockchainUtil.targetBigIntegerToBytes(params.getMaxTarget())).setTimestamp(System.currentTimeMillis()).build();
    BlockSummary prev_summary;
    prev_summary = BlockSummary.newBuilder().build();
    System.out.println(prev_summary);
    BlockSummary s = BlockchainUtil.getNewSummary(header, prev_summary, params, 1L, 600L, new LinkedList());
    Assert.assertNotNull(s.getHeader());
    Assert.assertEquals("1024", s.getWorkSum());
    Assert.assertEquals(params.getMaxTarget().toString(), s.getTargetAverage());
    Assert.assertEquals(params.getBlockTimeTarget(), s.getBlocktimeAverageMs());
}
Also used : NetworkParamsTestnet(snowblossom.lib.NetworkParamsTestnet) NetworkParams(snowblossom.lib.NetworkParams) BlockHeader(snowblossom.proto.BlockHeader) BlockSummary(snowblossom.proto.BlockSummary) LinkedList(java.util.LinkedList) Test(org.junit.Test)

Example 2 with BlockSummary

use of snowblossom.proto.BlockSummary in project snowblossom by snowblossomcoin.

the class BlockIngestor method checkResummary.

private void checkResummary() {
    BlockSummary curr = chainhead;
    LinkedList<ChainHash> recalc_list = new LinkedList<>();
    while (curr.getSummaryVersion() < SUMMARY_VERSION) {
        recalc_list.addFirst(new ChainHash(curr.getHeader().getSnowHash()));
        ChainHash prevblock = new ChainHash(curr.getHeader().getPrevBlockHash());
        if (prevblock.equals(ChainHash.ZERO_HASH)) {
            curr = getStartSummary();
        } else {
            curr = db.getBlockSummaryMap().get(prevblock.getBytes());
        }
    }
    if (recalc_list.size() > 0) {
        node.setStatus(String.format("Need to recalcuate chain index of %d blocks now", recalc_list.size()));
        for (ChainHash hash : recalc_list) {
            BlockSummary summary = db.getBlockSummaryMap().get(hash.getBytes());
            Block blk = db.getBlockMap().get(hash.getBytes());
            node.setStatus("Reindexing: " + summary.getHeader().getBlockHeight() + " - " + hash + " - " + blk.getTransactionsCount());
            ChainHash prevblock = new ChainHash(summary.getHeader().getPrevBlockHash());
            BlockSummary prevsummary = null;
            if (prevblock.equals(ChainHash.ZERO_HASH)) {
                prevsummary = getStartSummary();
            } else {
                prevsummary = db.getBlockSummaryMap().get(prevblock.getBytes());
            }
            long tx_body_size = 0;
            for (Transaction tx : blk.getTransactionsList()) {
                tx_body_size += tx.getInnerData().size();
                tx_body_size += tx.getTxHash().size();
            }
            summary = BlockchainUtil.getNewSummary(blk.getHeader(), prevsummary, node.getParams(), blk.getTransactionsCount(), tx_body_size, blk.getImportedBlocksList());
            summary = saveOtherChainIndexBits(summary, prevsummary, blk);
            db.getBlockSummaryMap().put(hash.getBytes(), summary);
        }
        // Resave head
        chainhead = db.getBlockSummaryMap().get(chainhead.getHeader().getSnowHash());
        db.getBlockSummaryMap().put(HEAD, chainhead);
    }
}
Also used : Transaction(snowblossom.proto.Transaction) ImportedBlock(snowblossom.proto.ImportedBlock) Block(snowblossom.proto.Block) BlockSummary(snowblossom.proto.BlockSummary) LinkedList(java.util.LinkedList)

Example 3 with BlockSummary

use of snowblossom.proto.BlockSummary 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 4 with BlockSummary

use of snowblossom.proto.BlockSummary in project snowblossom by snowblossomcoin.

the class BlockIngestorTest method testMagicBlockSummary.

@Test
public void testMagicBlockSummary() {
    NetworkParams params = new NetworkParamsTestnet();
    long time = System.currentTimeMillis();
    BigInteger using_target = params.getMaxTarget().divide(BigInteger.valueOf(2L));
    BlockHeader header = BlockHeader.newBuilder().setTarget(BlockchainUtil.targetBigIntegerToBytes(using_target)).setTimestamp(time).build();
    long using_time = params.getBlockTimeTarget() / 2;
    BlockHeader prev_header = BlockHeader.newBuilder().setTimestamp(time - using_time).build();
    BlockSummary prev_summary;
    prev_summary = BlockSummary.newBuilder().setWorkSum("1000").setBlocktimeAverageMs(params.getBlockTimeTarget()).setTargetAverage(params.getMaxTarget().toString()).setHeader(prev_header).build();
    System.out.println(prev_summary);
    BlockSummary s = BlockchainUtil.getNewSummary(header, prev_summary, params, 1L, 600L, new LinkedList());
    BigInteger expected_target = params.getMaxTarget().multiply(BigInteger.valueOf(990L)).add(using_target.multiply(BigInteger.valueOf(10L))).divide(BigInteger.valueOf(1000L));
    long expected_time = (params.getBlockTimeTarget() * 990L + using_time * 10L) / 1000L;
    Assert.assertNotNull(s.getHeader());
    int work = 1000 + 1024 * 2;
    Assert.assertEquals("" + work, s.getWorkSum());
    Assert.assertEquals(expected_target.toString(), s.getTargetAverage());
    Assert.assertEquals(expected_time, s.getBlocktimeAverageMs());
}
Also used : NetworkParamsTestnet(snowblossom.lib.NetworkParamsTestnet) NetworkParams(snowblossom.lib.NetworkParams) BigInteger(java.math.BigInteger) BlockHeader(snowblossom.proto.BlockHeader) BlockSummary(snowblossom.proto.BlockSummary) LinkedList(java.util.LinkedList) Test(org.junit.Test)

Aggregations

BlockSummary (snowblossom.proto.BlockSummary)4 LinkedList (java.util.LinkedList)3 Test (org.junit.Test)2 NetworkParams (snowblossom.lib.NetworkParams)2 NetworkParamsTestnet (snowblossom.lib.NetworkParamsTestnet)2 BlockHeader (snowblossom.proto.BlockHeader)2 ImportedBlock (snowblossom.proto.ImportedBlock)2 Transaction (snowblossom.proto.Transaction)2 ByteString (com.google.protobuf.ByteString)1 MetricLog (duckutil.MetricLog)1 TimeRecordAuto (duckutil.TimeRecordAuto)1 BigInteger (java.math.BigInteger)1 HashMap (java.util.HashMap)1 Block (snowblossom.proto.Block)1