use of com.iota.iri.model.Hash in project iri by iotaledger.
the class API method checkConsistencyStatement.
private AbstractResponse checkConsistencyStatement(List<String> transactionsList) throws Exception {
final List<Hash> transactions = transactionsList.stream().map(Hash::new).collect(Collectors.toList());
boolean state = true;
String info = "";
// check transactions themselves are valid
for (Hash transaction : transactions) {
TransactionViewModel txVM = TransactionViewModel.fromHash(instance.tangle, transaction);
if (txVM.getType() == TransactionViewModel.PREFILLED_SLOT) {
return ErrorResponse.create("Invalid transaction, missing: " + transaction);
}
if (txVM.getCurrentIndex() != 0) {
return ErrorResponse.create("Invalid transaction, not a tail: " + transaction);
}
if (!instance.transactionValidator.checkSolidity(txVM.getHash(), false)) {
state = false;
info = "tails are not solid (missing a referenced tx): " + transaction;
break;
} else if (BundleValidator.validate(instance.tangle, txVM.getHash()).size() == 0) {
state = false;
info = "tails are not consistent (bundle is invalid): " + transaction;
break;
}
}
if (state) {
instance.milestone.latestSnapshot.rwlock.readLock().lock();
try {
if (!instance.ledgerValidator.checkConsistency(transactions)) {
state = false;
info = "tails are not consistent (would lead to inconsistent ledger state)";
}
} finally {
instance.milestone.latestSnapshot.rwlock.readLock().unlock();
}
}
return CheckConsistency.create(state, info);
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class API method findTransactionStatement.
private synchronized AbstractResponse findTransactionStatement(final Map<String, Object> request) throws Exception {
final Set<Hash> foundTransactions = new HashSet<>();
boolean containsKey = false;
final Set<Hash> bundlesTransactions = new HashSet<>();
if (request.containsKey("bundles")) {
final HashSet<String> bundles = getParameterAsSet(request, "bundles", HASH_SIZE);
for (final String bundle : bundles) {
bundlesTransactions.addAll(BundleViewModel.load(instance.tangle, new Hash(bundle)).getHashes());
}
foundTransactions.addAll(bundlesTransactions);
containsKey = true;
}
final Set<Hash> addressesTransactions = new HashSet<>();
if (request.containsKey("addresses")) {
final HashSet<String> addresses = getParameterAsSet(request, "addresses", HASH_SIZE);
for (final String address : addresses) {
addressesTransactions.addAll(AddressViewModel.load(instance.tangle, new Hash(address)).getHashes());
}
foundTransactions.addAll(addressesTransactions);
containsKey = true;
}
final Set<Hash> tagsTransactions = new HashSet<>();
if (request.containsKey("tags")) {
final HashSet<String> tags = getParameterAsSet(request, "tags", 0);
for (String tag : tags) {
tag = padTag(tag);
tagsTransactions.addAll(TagViewModel.load(instance.tangle, new Hash(tag)).getHashes());
}
foundTransactions.addAll(tagsTransactions);
containsKey = true;
}
final Set<Hash> approveeTransactions = new HashSet<>();
if (request.containsKey("approvees")) {
final HashSet<String> approvees = getParameterAsSet(request, "approvees", HASH_SIZE);
for (final String approvee : approvees) {
approveeTransactions.addAll(TransactionViewModel.fromHash(instance.tangle, new Hash(approvee)).getApprovers(instance.tangle).getHashes());
}
foundTransactions.addAll(approveeTransactions);
containsKey = true;
}
if (!containsKey) {
throw new ValidationException(invalidParams);
}
// Using multiple of these input fields returns the intersection of the values.
if (request.containsKey("bundles")) {
foundTransactions.retainAll(bundlesTransactions);
}
if (request.containsKey("addresses")) {
foundTransactions.retainAll(addressesTransactions);
}
if (request.containsKey("tags")) {
foundTransactions.retainAll(tagsTransactions);
}
if (request.containsKey("approvees")) {
foundTransactions.retainAll(approveeTransactions);
}
if (foundTransactions.size() > maxFindTxs) {
return ErrorResponse.create(overMaxErrorMessage);
}
final List<String> elements = foundTransactions.stream().map(Hash::toString).collect(Collectors.toCollection(LinkedList::new));
return FindTransactionsResponse.create(elements);
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class API method wereAddressesSpentFromStatement.
private AbstractResponse wereAddressesSpentFromStatement(List<String> addressesStr) throws Exception {
final List<Hash> addresses = addressesStr.stream().map(Hash::new).collect(Collectors.toList());
final boolean[] states = new boolean[addresses.size()];
int index = 0;
for (Hash address : addresses) {
states[index++] = wasAddressSpentFrom(address);
}
return wereAddressesSpentFrom.create(states);
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class API method getNewInclusionStateStatement.
private AbstractResponse getNewInclusionStateStatement(final List<String> trans, final List<String> tps) throws Exception {
final List<Hash> transactions = trans.stream().map(Hash::new).collect(Collectors.toList());
final List<Hash> tips = tps.stream().map(Hash::new).collect(Collectors.toList());
int numberOfNonMetTransactions = transactions.size();
final int[] inclusionStates = new int[numberOfNonMetTransactions];
List<Integer> tipsIndex = new LinkedList<>();
{
for (Hash tip : tips) {
TransactionViewModel tx = TransactionViewModel.fromHash(instance.tangle, tip);
if (tx.getType() != TransactionViewModel.PREFILLED_SLOT) {
tipsIndex.add(tx.snapshotIndex());
}
}
}
int minTipsIndex = tipsIndex.stream().reduce((a, b) -> a < b ? a : b).orElse(0);
if (minTipsIndex > 0) {
int maxTipsIndex = tipsIndex.stream().reduce((a, b) -> a > b ? a : b).orElse(0);
int count = 0;
for (Hash hash : transactions) {
TransactionViewModel transaction = TransactionViewModel.fromHash(instance.tangle, hash);
if (transaction.getType() == TransactionViewModel.PREFILLED_SLOT || transaction.snapshotIndex() == 0) {
inclusionStates[count] = -1;
} else if (transaction.snapshotIndex() > maxTipsIndex) {
inclusionStates[count] = -1;
} else if (transaction.snapshotIndex() < maxTipsIndex) {
inclusionStates[count] = 1;
}
count++;
}
}
Set<Hash> analyzedTips = new HashSet<>();
Map<Integer, Integer> sameIndexTransactionCount = new HashMap<>();
Map<Integer, Queue<Hash>> sameIndexTips = new HashMap<>();
for (final Hash tip : tips) {
TransactionViewModel transactionViewModel = TransactionViewModel.fromHash(instance.tangle, tip);
if (transactionViewModel.getType() == TransactionViewModel.PREFILLED_SLOT) {
return ErrorResponse.create("One of the tips absents");
}
int snapshotIndex = transactionViewModel.snapshotIndex();
sameIndexTips.putIfAbsent(snapshotIndex, new LinkedList<>());
sameIndexTips.get(snapshotIndex).add(tip);
}
for (int i = 0; i < inclusionStates.length; i++) {
if (inclusionStates[i] == 0) {
TransactionViewModel transactionViewModel = TransactionViewModel.fromHash(instance.tangle, transactions.get(i));
int snapshotIndex = transactionViewModel.snapshotIndex();
sameIndexTransactionCount.putIfAbsent(snapshotIndex, 0);
sameIndexTransactionCount.put(snapshotIndex, sameIndexTransactionCount.get(snapshotIndex) + 1);
}
}
for (Integer index : sameIndexTransactionCount.keySet()) {
Queue<Hash> sameIndexTip = sameIndexTips.get(index);
if (sameIndexTip != null) {
// has tips in the same index level
if (!exhaustiveSearchWithinIndex(sameIndexTip, analyzedTips, transactions, inclusionStates, sameIndexTransactionCount.get(index), index)) {
return ErrorResponse.create("The subtangle is not solid");
}
}
}
final boolean[] inclusionStatesBoolean = new boolean[inclusionStates.length];
for (int i = 0; i < inclusionStates.length; i++) {
inclusionStatesBoolean[i] = inclusionStates[i] == 1;
}
{
return GetInclusionStatesResponse.create(inclusionStatesBoolean);
}
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class TipsManager method randomWalk.
Hash randomWalk(final Set<Hash> visitedHashes, final Map<Hash, Long> diff, final Hash start, final Hash extraTip, final Map<Hash, Long> ratings, final int maxDepth, final Set<Hash> maxDepthOk, Random rnd) throws Exception {
Hash tip = start, tail = tip;
Hash[] tips;
Set<Hash> tipSet;
Set<Hash> analyzedTips = new HashSet<>();
int traversedTails = 0;
TransactionViewModel transactionViewModel;
int approverIndex;
double ratingWeight;
double[] walkRatings;
List<Hash> extraTipList = null;
if (extraTip != null) {
extraTipList = Collections.singletonList(extraTip);
}
Map<Hash, Long> myDiff = new HashMap<>(diff);
Set<Hash> myApprovedHashes = new HashSet<>(visitedHashes);
while (tip != null) {
transactionViewModel = TransactionViewModel.fromHash(tangle, tip);
tipSet = transactionViewModel.getApprovers(tangle).getHashes();
if (transactionViewModel.getCurrentIndex() == 0) {
if (transactionViewModel.getType() == TransactionViewModel.PREFILLED_SLOT) {
log.info("Reason to stop: transactionViewModel == null");
messageQ.publish("rtsn %s", transactionViewModel.getHash());
break;
} else if (!transactionValidator.checkSolidity(transactionViewModel.getHash(), false)) {
log.info("Reason to stop: !checkSolidity");
messageQ.publish("rtss %s", transactionViewModel.getHash());
break;
} else if (belowMaxDepth(transactionViewModel.getHash(), maxDepth, maxDepthOk)) {
log.info("Reason to stop: belowMaxDepth");
break;
} else if (!ledgerValidator.updateDiff(myApprovedHashes, myDiff, transactionViewModel.getHash())) {
log.info("Reason to stop: !LedgerValidator");
messageQ.publish("rtsv %s", transactionViewModel.getHash());
break;
} else if (transactionViewModel.getHash().equals(extraTip)) {
log.info("Reason to stop: transactionViewModel==extraTip");
messageQ.publish("rtsd %s", transactionViewModel.getHash());
break;
}
// set the tail here!
tail = tip;
traversedTails++;
}
if (tipSet.size() == 0) {
log.info("Reason to stop: TransactionViewModel is a tip");
messageQ.publish("rtst %s", tip);
break;
} else if (tipSet.size() == 1) {
Iterator<Hash> hashIterator = tipSet.iterator();
if (hashIterator.hasNext()) {
tip = hashIterator.next();
} else {
tip = null;
}
} else {
// walk to the next approver
tips = tipSet.toArray(new Hash[tipSet.size()]);
if (!ratings.containsKey(tip)) {
serialUpdateRatings(myApprovedHashes, tip, ratings, analyzedTips, extraTip);
analyzedTips.clear();
}
walkRatings = new double[tips.length];
double maxRating = 0;
long tipRating = ratings.get(tip);
for (int i = 0; i < tips.length; i++) {
// transition probability = ((Hx-Hy)^-3)/maxRating
walkRatings[i] = Math.pow(tipRating - ratings.getOrDefault(tips[i], 0L), -3);
maxRating += walkRatings[i];
}
ratingWeight = rnd.nextDouble() * maxRating;
for (approverIndex = tips.length; approverIndex-- > 1; ) {
ratingWeight -= walkRatings[approverIndex];
if (ratingWeight <= 0) {
break;
}
}
tip = tips[approverIndex];
if (transactionViewModel.getHash().equals(tip)) {
log.info("Reason to stop: transactionViewModel==itself");
messageQ.publish("rtsl %s", transactionViewModel.getHash());
break;
}
}
}
log.info("Tx traversed to find tip: " + traversedTails);
messageQ.publish("mctn %d", traversedTails);
return tail;
}
Aggregations