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();
}
}
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);
}
}
}
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;
}
}
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();
}
}
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));
}
}
Aggregations