use of com.iota.iri.model.Hash in project iri by iotaledger.
the class BundleValidator method loadTransactionsFromTangle.
private static Map<Hash, TransactionViewModel> loadTransactionsFromTangle(Tangle tangle, TransactionViewModel tail) {
final Map<Hash, TransactionViewModel> bundleTransactions = new HashMap<>();
final Hash bundleHash = tail.getBundleHash();
try {
TransactionViewModel tx = tail;
long i = 0, end = tx.lastIndex();
do {
bundleTransactions.put(tx.getHash(), tx);
tx = tx.getTrunkTransaction(tangle);
} while (i++ < end && tx.getCurrentIndex() != 0 && tx.getBundleHash().equals(bundleHash));
} catch (Exception e) {
e.printStackTrace();
}
return bundleTransactions;
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class LedgerValidator method updateConsistentHashes.
/**
* Descends through transactions, trunk and branch, beginning at {tip}, until it reaches a transaction marked as
* confirmed, or until it reaches a transaction that has already been added to the transient consistent set.
* @param tip
* @throws Exception
*/
private void updateConsistentHashes(final Set<Hash> visitedHashes, Hash tip, int index) throws Exception {
final Queue<Hash> nonAnalyzedTransactions = new LinkedList<>(Collections.singleton(tip));
Hash hashPointer;
while ((hashPointer = nonAnalyzedTransactions.poll()) != null) {
final TransactionViewModel transactionViewModel2 = TransactionViewModel.fromHash(tangle, hashPointer);
if ((transactionViewModel2.snapshotIndex() == 0 || transactionViewModel2.snapshotIndex() > index)) {
if (visitedHashes.add(hashPointer)) {
nonAnalyzedTransactions.offer(transactionViewModel2.getTrunkTransactionHash());
nonAnalyzedTransactions.offer(transactionViewModel2.getBranchTransactionHash());
}
}
}
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class LedgerValidator method updateSnapshot.
public boolean updateSnapshot(MilestoneViewModel milestoneVM) throws Exception {
TransactionViewModel transactionViewModel = TransactionViewModel.fromHash(tangle, milestoneVM.getHash());
milestone.latestSnapshot.rwlock.writeLock().lock();
try {
final int transactionSnapshotIndex = transactionViewModel.snapshotIndex();
boolean hasSnapshot = transactionSnapshotIndex != 0;
if (!hasSnapshot) {
Hash tail = transactionViewModel.getHash();
Map<Hash, Long> currentState = getLatestDiff(new HashSet<>(), tail, milestone.latestSnapshot.index(), true);
hasSnapshot = currentState != null && Snapshot.isConsistent(milestone.latestSnapshot.patchedDiff(currentState));
if (hasSnapshot) {
updateSnapshotMilestone(milestoneVM.getHash(), milestoneVM.index());
StateDiffViewModel stateDiffViewModel;
stateDiffViewModel = new StateDiffViewModel(currentState, milestoneVM.getHash());
if (currentState.size() != 0) {
stateDiffViewModel.store(tangle);
}
milestone.latestSnapshot.apply(currentState, milestoneVM.index());
}
}
return hasSnapshot;
} finally {
milestone.latestSnapshot.rwlock.writeLock().unlock();
}
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class Milestone method init.
public void init(final SpongeFactory.Mode mode, final LedgerValidator ledgerValidator, final boolean revalidate) throws Exception {
this.ledgerValidator = ledgerValidator;
AtomicBoolean ledgerValidatorInitialized = new AtomicBoolean(false);
(new Thread(() -> {
while (!ledgerValidatorInitialized.get()) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
while (!shuttingDown) {
long scanTime = System.currentTimeMillis();
try {
final int previousLatestMilestoneIndex = latestMilestoneIndex;
Set<Hash> hashes = AddressViewModel.load(tangle, coordinator).getHashes();
{
// Update Milestone
{
// find new milestones
for (Hash hash : hashes) {
if (analyzedMilestoneCandidates.add(hash)) {
TransactionViewModel t = TransactionViewModel.fromHash(tangle, hash);
if (t.getCurrentIndex() == 0) {
final Validity valid = validateMilestone(mode, t, getIndex(t));
switch(valid) {
case VALID:
MilestoneViewModel milestoneViewModel = MilestoneViewModel.latest(tangle);
if (milestoneViewModel != null && milestoneViewModel.index() > latestMilestoneIndex) {
latestMilestone = milestoneViewModel.getHash();
latestMilestoneIndex = milestoneViewModel.index();
}
break;
case INCOMPLETE:
analyzedMilestoneCandidates.remove(t.getHash());
break;
case INVALID:
// Do nothing
break;
}
}
}
}
}
}
if (previousLatestMilestoneIndex != latestMilestoneIndex) {
messageQ.publish("lmi %d %d", previousLatestMilestoneIndex, latestMilestoneIndex);
log.info("Latest milestone has changed from #" + previousLatestMilestoneIndex + " to #" + latestMilestoneIndex);
}
Thread.sleep(Math.max(1, RESCAN_INTERVAL - (System.currentTimeMillis() - scanTime)));
} catch (final Exception e) {
log.error("Error during Latest Milestone updating", e);
}
}
}, "Latest Milestone Tracker")).start();
(new Thread(() -> {
try {
ledgerValidator.init();
ledgerValidatorInitialized.set(true);
} catch (Exception e) {
log.error("Error initializing snapshots. Skipping.", e);
}
while (!shuttingDown) {
long scanTime = System.currentTimeMillis();
try {
final int previousSolidSubtangleLatestMilestoneIndex = latestSolidSubtangleMilestoneIndex;
if (latestSolidSubtangleMilestoneIndex < latestMilestoneIndex) {
updateLatestSolidSubtangleMilestone();
}
if (previousSolidSubtangleLatestMilestoneIndex != latestSolidSubtangleMilestoneIndex) {
messageQ.publish("lmsi %d %d", previousSolidSubtangleLatestMilestoneIndex, latestSolidSubtangleMilestoneIndex);
messageQ.publish("lmhs %s", latestSolidSubtangleMilestone);
log.info("Latest SOLID SUBTANGLE milestone has changed from #" + previousSolidSubtangleLatestMilestoneIndex + " to #" + latestSolidSubtangleMilestoneIndex);
}
Thread.sleep(Math.max(1, RESCAN_INTERVAL - (System.currentTimeMillis() - scanTime)));
} catch (final Exception e) {
log.error("Error during Solid Milestone updating", e);
}
}
}, "Solid Milestone Tracker")).start();
}
use of com.iota.iri.model.Hash in project iri by iotaledger.
the class Milestone method validateMilestone.
private Validity validateMilestone(SpongeFactory.Mode mode, TransactionViewModel transactionViewModel, int index) throws Exception {
if (index < 0 || index >= 0x200000) {
return INVALID;
}
if (MilestoneViewModel.get(tangle, index) != null) {
// Already validated.
return VALID;
}
final List<List<TransactionViewModel>> bundleTransactions = BundleValidator.validate(tangle, transactionViewModel.getHash());
if (bundleTransactions.size() == 0) {
return INCOMPLETE;
} else {
for (final List<TransactionViewModel> bundleTransactionViewModels : bundleTransactions) {
// if (Arrays.equals(bundleTransactionViewModels.get(0).getHash(),transactionViewModel.getHash())) {
if (bundleTransactionViewModels.get(0).getHash().equals(transactionViewModel.getHash())) {
// final TransactionViewModel transactionViewModel2 = StorageTransactions.instance().loadTransaction(transactionViewModel.trunkTransactionPointer);
final TransactionViewModel transactionViewModel2 = transactionViewModel.getTrunkTransaction(tangle);
if (transactionViewModel2.getType() == TransactionViewModel.FILLED_SLOT && transactionViewModel.getBranchTransactionHash().equals(transactionViewModel2.getTrunkTransactionHash()) && transactionViewModel.getBundleHash().equals(transactionViewModel2.getBundleHash())) {
final int[] trunkTransactionTrits = transactionViewModel.getTrunkTransactionHash().trits();
final int[] signatureFragmentTrits = Arrays.copyOfRange(transactionViewModel.trits(), TransactionViewModel.SIGNATURE_MESSAGE_FRAGMENT_TRINARY_OFFSET, TransactionViewModel.SIGNATURE_MESSAGE_FRAGMENT_TRINARY_OFFSET + TransactionViewModel.SIGNATURE_MESSAGE_FRAGMENT_TRINARY_SIZE);
final int[] merkleRoot = ISS.getMerkleRoot(mode, ISS.address(mode, ISS.digest(mode, Arrays.copyOf(ISS.normalizedBundle(trunkTransactionTrits), ISS.NUMBER_OF_FRAGMENT_CHUNKS), signatureFragmentTrits)), transactionViewModel2.trits(), 0, index, NUMBER_OF_KEYS_IN_A_MILESTONE);
if (testnet || (new Hash(merkleRoot)).equals(coordinator)) {
new MilestoneViewModel(index, transactionViewModel.getHash()).store(tangle);
return VALID;
} else {
return INVALID;
}
}
}
}
}
return INVALID;
}
Aggregations