use of snowblossom.proto.TransactionInner in project snowblossom by snowblossomcoin.
the class MemPool method rebuildPriorityMap.
public synchronized void rebuildPriorityMap(ChainHash new_utxo_root) {
logger.log(Level.FINE, String.format("Mempool.rebuildPriorityMap(%s)", new_utxo_root));
utxo_for_pri_map = new_utxo_root;
priority_map.clear();
LinkedList<ChainHash> remove_list = new LinkedList<>();
for (TransactionMempoolInfo info : known_transactions.values()) {
Transaction tx = info.tx;
TXCluster cluster;
try {
cluster = buildTXCluster(tx);
} catch (ValidationException e) {
cluster = null;
}
if (cluster == null) {
remove_list.add(new ChainHash(tx.getTxHash()));
TransactionInner inner = TransactionUtil.getInner(tx);
for (TransactionInput in : inner.getInputsList()) {
String key = HexUtil.getHexString(in.getSrcTxId()) + ":" + in.getSrcTxOutIdx();
claimed_outputs.remove(key);
}
} else {
double ratio = (double) cluster.total_fee / (double) cluster.total_size;
priority_map.put(ratio, cluster);
}
}
logger.log(Level.FINER, String.format("Removing %d transactions from mempool", remove_list.size()));
for (ChainHash h : remove_list) {
TransactionMempoolInfo info = known_transactions.remove(h);
for (AddressSpecHash spec_hash : info.involved_addresses) {
address_tx_map.remove(spec_hash, h);
}
}
logger.log(Level.FINER, String.format("Remaining in mempool: %d", known_transactions.size()));
}
use of snowblossom.proto.TransactionInner in project snowblossom by snowblossomcoin.
the class TransactionBridge method getConnections.
public static List<TransactionBridge> getConnections(Transaction tx) {
TransactionInner inner = TransactionUtil.getInner(tx);
LinkedList<TransactionBridge> lst = new LinkedList<>();
for (int i = 0; i < inner.getOutputsCount(); i++) {
TransactionOutput out = inner.getOutputs(i);
lst.add(new TransactionBridge(out, i, new ChainHash(tx.getTxHash())));
}
return lst;
}
use of snowblossom.proto.TransactionInner in project snowblossom by snowblossomcoin.
the class MonitorTool method sendNotices.
private void sendNotices(AddressSpecHash hash, ByteString tx_hash) {
ByteString key = hash.getBytes().concat(tx_hash);
synchronized (processed_tx) {
if (processed_tx.contains(key))
return;
}
Transaction tx = stub_holder.getBlockingStub().getTransaction(RequestTransaction.newBuilder().setTxHash(tx_hash).build());
TransactionInner inner = TransactionUtil.getInner(tx);
int idx = 0;
for (TransactionInput in : inner.getInputsList()) {
if (hash.getBytes().equals(in.getSpecHash())) {
monitor_interface.onOutbound(tx, idx);
}
idx++;
}
idx = 0;
for (TransactionOutput out : inner.getOutputsList()) {
if (hash.getBytes().equals(out.getRecipientSpecHash())) {
monitor_interface.onInbound(tx, idx);
}
idx++;
}
synchronized (processed_tx) {
processed_tx.add(key);
}
}
use of snowblossom.proto.TransactionInner in project snowblossom by snowblossomcoin.
the class MemPool method buildTXCluster.
/**
* Attemped to build an ordered list of transactions
* that can confirm. In the simple case, it is just
* a single transaction that has all outputs already in utxo.
* In the more complex case, a chain of transactions needs to go
* in for the transaction in question to be confirmed.
* TODO - make faster, this thing sucks out loud.
* Probably need to actually build the graph and do graph
* theory things.
*/
private TXCluster buildTXCluster(Transaction target_tx) throws ValidationException {
HashMap<ChainHash, Transaction> working_map = new HashMap<>();
HashMultimap<ChainHash, ChainHash> depends_on_map = HashMultimap.<ChainHash, ChainHash>create();
LinkedList<TransactionInput> needed_inputs = new LinkedList<>();
addInputRequirements(target_tx, depends_on_map, needed_inputs);
working_map.put(new ChainHash(target_tx.getTxHash()), target_tx);
long t1;
while (needed_inputs.size() > 0) {
TransactionInput in = needed_inputs.pop();
ChainHash needed_tx = new ChainHash(in.getSrcTxId());
if (!working_map.containsKey(needed_tx)) {
ByteString key = UtxoUpdateBuffer.getKey(in);
t1 = System.nanoTime();
ByteString matching_output = utxo_hashed_trie.getLeafData(utxo_for_pri_map.getBytes(), key);
TimeRecord.record(t1, "utxo_lookup");
if (matching_output == null) {
if (known_transactions.containsKey(needed_tx)) {
t1 = System.nanoTime();
// TODO Check shard IDs
Transaction found_tx = known_transactions.get(needed_tx).tx;
TransactionInner found_tx_inner = TransactionUtil.getInner(found_tx);
TransactionOutput tx_out = found_tx_inner.getOutputs(in.getSrcTxOutIdx());
if (!shard_cover_set.contains(tx_out.getTargetShard())) {
throw new ValidationException(String.format("Transaction %s depends on %s which seems to be in other shard", new ChainHash(target_tx.getTxHash()), in.toString()));
}
working_map.put(needed_tx, found_tx);
addInputRequirements(found_tx, depends_on_map, needed_inputs);
TimeRecord.record(t1, "input_add");
} else {
throw new ValidationException(String.format("Unable to find source tx %s", needed_tx.toString()));
}
}
}
}
// At this point we have all the inputs satisfied. Now to figure out ordering.
t1 = System.nanoTime();
LinkedList<Transaction> ordered_list = getOrderdTxList(working_map, depends_on_map, new ChainHash(target_tx.getTxHash()));
TimeRecord.record(t1, "get_order");
t1 = System.nanoTime();
UtxoUpdateBuffer test_buffer = new UtxoUpdateBuffer(utxo_hashed_trie, utxo_for_pri_map);
int header_version = 1;
if (chain_state_source.getParams().getActivationHeightShards() <= chain_state_source.getHeight() + 1) {
header_version = 2;
}
BlockHeader dummy_header = BlockHeader.newBuilder().setBlockHeight(chain_state_source.getHeight() + 1).setTimestamp(System.currentTimeMillis()).setVersion(header_version).build();
// TODO - assign shard correctly
Map<Integer, UtxoUpdateBuffer> export_utxo_buffer = new TreeMap<>();
for (Transaction t : ordered_list) {
Validation.deepTransactionCheck(t, test_buffer, dummy_header, chain_state_source.getParams(), shard_cover_set, export_utxo_buffer);
}
TimeRecord.record(t1, "utxo_sim");
return new TXCluster(ordered_list);
}
use of snowblossom.proto.TransactionInner in project snowblossom by snowblossomcoin.
the class MemPool method addInputRequirements.
private static void addInputRequirements(Transaction tx, HashMultimap<ChainHash, ChainHash> depends_on_map, List<TransactionInput> needed_inputs) {
ChainHash tx_id = new ChainHash(tx.getTxHash());
TransactionInner inner = TransactionUtil.getInner(tx);
for (TransactionInput in : inner.getInputsList()) {
depends_on_map.put(tx_id, new ChainHash(in.getSrcTxId()));
needed_inputs.add(in);
}
}
Aggregations