Skip to content
This repository was archived by the owner on Aug 23, 2020. It is now read-only.

Commit fa79533

Browse files
author
Gal Rogozinski
committed
Merge branch 'release-v1.8.4'
2 parents cff4f90 + 344b7d6 commit fa79533

File tree

3 files changed

+97
-41
lines changed

3 files changed

+97
-41
lines changed

changelog.txt

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,34 @@
1+
1.8.4
2+
3+
Hotfix: Ensure proper creation of solid entrypoints (#1702)
4+
5+
1.8.3
6+
7+
There is an edge case where IRI didn't account for a transaction that was shared between two distinct bundles.
8+
Once it marked it as "counted" in one bundle, it was ignored for the next bundle. This lead to a corrupt ledger state.
9+
10+
Hotfix: Gyros - take transaction reattachments into account (#1699)
11+
12+
1.8.2
13+
14+
Change: The alpha value is now 0 by default, streamlining the tip selection process which will reduce memory and cpu load. This is done by skipping cumulative weight calculations. (Issue #1567)
15+
16+
Fix: correct data setting into Hash object (#1589)
17+
Fix: Persistables merge and load functionality
18+
Documentation: Fix broken link of online documentation (#1623)
19+
Documentation: Update README.md (#1617)
20+
Fix: always set the domain field of a neighbor (#1604)
21+
Change: Use mocked SnapshotProvider (#1531)
22+
Fix: Fixes regression introduced through the bundle validator refactor (#1588)
23+
Documentation: Document Persistable and Indexable (#1169)
24+
Feature: Adds progress bar and estimated time until the node is synced (#1575)
25+
Change: Curl improvement
26+
Change: Bundle validator refactor
27+
Change: Use maven assembly plugin to create one jar with all dependencies (#1573)
28+
Documentation: Document Persistence Provider (#1157)
29+
Documentation: Updated links to official documentation (#1560)
30+
31+
132
1.8.1
233

334
- Feature: Improved CW Calculation (#1451)

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
<groupId>com.iota</groupId>
77
<artifactId>iri</artifactId>
8-
<version>1.8.3</version>
8+
<version>1.8.4</version>
99
<name>IRI</name>
1010
<description>IOTA Reference Implementation</description>
1111

src/main/java/com/iota/iri/service/snapshot/impl/SnapshotServiceImpl.java

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -510,7 +510,7 @@ private void persistLocalSnapshot(SnapshotProvider snapshotProvider, Snapshot ne
510510

511511
/**
512512
* <p>
513-
* This method determines if a transaction is orphaned.
513+
* This method determines if a transaction is orphaned when none of its approvers is confirmed by a milestone.
514514
* </p>
515515
* <p>
516516
* Since there is no hard definition for when a transaction can be considered to be orphaned, we define orphaned in
@@ -522,14 +522,14 @@ private void persistLocalSnapshot(SnapshotProvider snapshotProvider, Snapshot ne
522522
* a relatively safe way to determine if a subtangle "above" a transaction got orphaned.
523523
* </p>
524524
*
525-
* @param tangle Tangle object which acts as a database interface
526-
* @param transaction transaction that shall be checked
527-
* @param referenceTransaction transaction that acts as a judge to the other transaction
525+
* @param tangle Tangle object which acts as a database interface
526+
* @param transaction transaction that shall be checked
527+
* @param referenceTransaction transaction that acts as a judge to the other transaction
528528
* @param processedTransactions transactions that were visited already while trying to determine the orphaned status
529529
* @return true if the transaction got orphaned and false otherwise
530530
* @throws SnapshotException if anything goes wrong while determining the orphaned status
531531
*/
532-
private boolean isOrphaned(Tangle tangle, TransactionViewModel transaction,
532+
private boolean isProbablyOrphaned(Tangle tangle, TransactionViewModel transaction,
533533
TransactionViewModel referenceTransaction, Set<Hash> processedTransactions) throws SnapshotException {
534534

535535
AtomicBoolean nonOrphanedTransactionFound = new AtomicBoolean(false);
@@ -553,29 +553,27 @@ private boolean isOrphaned(Tangle tangle, TransactionViewModel transaction,
553553

554554
/**
555555
* <p>
556-
* This method checks if a transaction is a solid entry point for the targetMilestone.
557-
* </p>
558-
* <p>
559-
* A transaction is considered a solid entry point if it has non-orphaned approvers.
556+
* We determine whether future milestones will approve {@param transactionHash}. This should aid in determining
557+
* solid entry points.
560558
* </p>
561559
* <p>
562560
* To check if the transaction has non-orphaned approvers we first check if any of its approvers got confirmed by a
563561
* future milestone, since this is very cheap. If none of them got confirmed by another milestone we do the more
564-
* expensive check from {@link #isOrphaned(Tangle, TransactionViewModel, TransactionViewModel, Set)}.
562+
* expensive check from {@link #isProbablyOrphaned(Tangle, TransactionViewModel, TransactionViewModel, Set)}.
565563
* </p>
566564
* <p>
567565
* Since solid entry points have a limited life time and to prevent potential problems due to temporary errors in
568-
* the database, we assume that the checked transaction is a solid entry point if any error occurs while determining
569-
* its status. This is a storage <=> reliability trade off, since the only bad effect of having too many solid entry
570-
* points) is a bigger snapshot file.
566+
* the database, we assume that the checked transaction is not orphaned if any error occurs while determining its
567+
* status, thus adding solid entry points. This is a storage <=> reliability trade off, since the only bad effect of
568+
* having too many solid entry points) is a bigger snapshot file.
571569
* </p>
572570
*
573-
* @param tangle Tangle object which acts as a database interface
571+
* @param tangle Tangle object which acts as a database interface
574572
* @param transactionHash hash of the transaction that shall be checked
575573
* @param targetMilestone milestone that is used as an anchor for our checks
576574
* @return true if the transaction is a solid entry point and false otherwise
577575
*/
578-
private boolean isSolidEntryPoint(Tangle tangle, Hash transactionHash, MilestoneViewModel targetMilestone) {
576+
private boolean isNotOrphaned(Tangle tangle, Hash transactionHash, MilestoneViewModel targetMilestone) {
579577
Set<TransactionViewModel> unconfirmedApprovers = new HashSet<>();
580578

581579
try {
@@ -592,7 +590,7 @@ private boolean isSolidEntryPoint(Tangle tangle, Hash transactionHash, Milestone
592590
Set<Hash> processedTransactions = new HashSet<>();
593591
TransactionViewModel milestoneTransaction = TransactionViewModel.fromHash(tangle, targetMilestone.getHash());
594592
for (TransactionViewModel unconfirmedApprover : unconfirmedApprovers) {
595-
if (!isOrphaned(tangle, unconfirmedApprover, milestoneTransaction, processedTransactions)) {
593+
if (!isProbablyOrphaned(tangle, unconfirmedApprover, milestoneTransaction, processedTransactions)) {
596594
return true;
597595
}
598596
}
@@ -610,51 +608,66 @@ private boolean isSolidEntryPoint(Tangle tangle, Hash transactionHash, Milestone
610608
* This method analyzes the old solid entry points and determines if they are still not orphaned.
611609
* </p>
612610
* <p>
613-
* It simply iterates through the old solid entry points and checks them one by one. If an old solid entry point
614-
* is found to still be relevant it is added to the passed in map.
611+
* It simply iterates through the old solid entry points and checks them one by one. If an old solid entry point is
612+
* found to still be relevant it is added to the passed in map.
615613
* </p>
616-
*
617-
* @param tangle Tangle object which acts as a database interface
614+
*
615+
* @see #processNewSolidEntryPoints to understand the definition for solid entry points
616+
* @param tangle Tangle object which acts as a database interface
618617
* @param snapshotProvider data provider for the {@link Snapshot}s that are relevant for the node
619-
* @param targetMilestone milestone that is used to generate the solid entry points
618+
* @param targetMilestone milestone that is used to generate the solid entry points
620619
* @param solidEntryPoints map that is used to collect the solid entry points
621620
*/
622621
private void processOldSolidEntryPoints(Tangle tangle, SnapshotProvider snapshotProvider,
623-
MilestoneViewModel targetMilestone, Map<Hash, Integer> solidEntryPoints) {
622+
MilestoneViewModel targetMilestone, Map<Hash, Integer> solidEntryPoints) throws SnapshotException {
624623

625624
ProgressLogger progressLogger = new IntervalProgressLogger(
626625
"Taking local snapshot [analyzing old solid entry points]", log)
627626
.start(snapshotProvider.getInitialSnapshot().getSolidEntryPoints().size());
627+
try {
628+
Snapshot initialSnapshot = snapshotProvider.getInitialSnapshot();
629+
Map<Hash, Integer> orgSolidEntryPoints = initialSnapshot.getSolidEntryPoints();
630+
for (Map.Entry<Hash, Integer> solidPoint : orgSolidEntryPoints.entrySet()) {
631+
Hash hash = solidPoint.getKey();
632+
int milestoneIndex = solidPoint.getValue();
633+
if (!Hash.NULL_HASH.equals(hash)
634+
&& targetMilestone.index() - milestoneIndex <= SOLID_ENTRY_POINT_LIFETIME
635+
&& isNotOrphaned(tangle, hash, targetMilestone)) {
636+
TransactionViewModel tvm = TransactionViewModel.fromHash(tangle, hash);
637+
addTailsToSolidEntryPoints(milestoneIndex, solidEntryPoints, tvm);
638+
solidEntryPoints.put(hash, milestoneIndex);
639+
}
628640

629-
Snapshot initialSnapshot = snapshotProvider.getInitialSnapshot();
630-
initialSnapshot.getSolidEntryPoints().forEach((hash, milestoneIndex) -> {
631-
if (!Hash.NULL_HASH.equals(hash) && targetMilestone.index() - milestoneIndex <= SOLID_ENTRY_POINT_LIFETIME
632-
&& isSolidEntryPoint(tangle, hash, targetMilestone)) {
633-
634-
solidEntryPoints.put(hash, milestoneIndex);
641+
progressLogger.progress();
635642
}
636-
637-
progressLogger.progress();
638-
});
639-
640-
progressLogger.finish();
643+
} catch (Exception e) {
644+
throw new SnapshotException(
645+
"Couldn't process old solid entry point for target milestone " + targetMilestone.index(), e);
646+
} finally {
647+
progressLogger.finish();
648+
}
641649
}
642650

643651
/**
644652
* <p>
645653
* This method retrieves the new solid entry points of the snapshot reference given by the target milestone.
646654
* </p>
647655
* <p>
656+
* A transaction is considered a solid entry point if it is a bundle tail that can be traversed down from a
657+
* non-orphaned transaction that was approved by a milestone that is above the last local snapshot. Or if it is a
658+
* bundle tail of a non-orphaned transaction that was approved by a milestone that is above the last local snapshot.
659+
*
648660
* It iterates over all unprocessed milestones and analyzes their directly and indirectly approved transactions.
649-
* Every transaction is checked for being a solid entry point and added to the passed in map (if it was found to be
650-
* one).
661+
* Every transaction is checked for being not orphaned and the appropriate SEP is added to {@param SolidEntryPoints}
651662
* </p>
652-
*
653-
* @param tangle Tangle object which acts as a database interface
663+
*
664+
*
665+
* @param tangle Tangle object which acts as a database interface
654666
* @param snapshotProvider data provider for the {@link Snapshot}s that are relevant for the node
655-
* @param targetMilestone milestone that is used to generate the solid entry points
667+
* @param targetMilestone milestone that is used to generate the solid entry points
656668
* @param solidEntryPoints map that is used to collect the solid entry points
657669
* @throws SnapshotException if anything goes wrong while determining the solid entry points
670+
* @see #isNotOrphaned(Tangle, Hash, MilestoneViewModel)
658671
*/
659672
private void processNewSolidEntryPoints(Tangle tangle, SnapshotProvider snapshotProvider,
660673
MilestoneViewModel targetMilestone, Map<Hash, Integer> solidEntryPoints) throws SnapshotException {
@@ -675,8 +688,9 @@ private void processNewSolidEntryPoints(Tangle tangle, SnapshotProvider snapshot
675688
currentMilestone.getHash(),
676689
currentTransaction -> currentTransaction.snapshotIndex() >= currentMilestone.index(),
677690
currentTransaction -> {
678-
if (isSolidEntryPoint(tangle, currentTransaction.getHash(), targetMilestone)) {
679-
solidEntryPoints.put(currentTransaction.getHash(), targetMilestone.index());
691+
if (isNotOrphaned(tangle, currentTransaction.getHash(), targetMilestone)) {
692+
addTailsToSolidEntryPoints(targetMilestone.index(), solidEntryPoints,
693+
currentTransaction);
680694
}
681695
}
682696
);
@@ -696,4 +710,15 @@ private void processNewSolidEntryPoints(Tangle tangle, SnapshotProvider snapshot
696710
throw new SnapshotException("could not generate the solid entry points for " + targetMilestone, e);
697711
}
698712
}
713+
714+
private void addTailsToSolidEntryPoints(int milestoneIndex, Map<Hash, Integer> solidEntryPoints,
715+
TransactionViewModel currentTransaction) throws TraversalException {
716+
// if tail
717+
if (currentTransaction.getCurrentIndex() == 0) {
718+
solidEntryPoints.put(currentTransaction.getHash(), milestoneIndex);
719+
} else {
720+
Set<? extends Hash> tails = DAGHelper.get(tangle).findTails(currentTransaction);
721+
tails.forEach(tail -> solidEntryPoints.put(tail, milestoneIndex));
722+
}
723+
}
699724
}

0 commit comments

Comments
 (0)