-
Notifications
You must be signed in to change notification settings - Fork 370
sort milestone candidates before analyzing #1660
sort milestone candidates before analyzing #1660
Conversation
public static List<TransactionViewModel> loadAsSortedList(Tangle tangle, Indexable hash) throws Exception { | ||
Address hashes = (Address)tangle.load(Address.class, hash); | ||
return hashes.set.stream() | ||
.map(item -> fromHash(tangle,item)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you map with a fromHash
call as you've done here, a tvm will always be created, which invalidates the tvm != null
call below when sorting. What happens in this case is that the stream will throw an exception once the sorting hits a transaction that doesn't exist in the db (as is the case when a milestone has been removed from pruning). To fix this issue locally I replaced the mapping with:
.map(
item -> {
try {
if(tangle.exists(Transaction.class, item)) {
return fromHash(tangle, item);
} else {
return null;
}
}catch(Exception e){
return null;
}
})
This will make sure that if the transaction does not exist, a tvm will not be created for it. Of course this means that you will either need to not include these transactions in the collection before you analyse it in the LatestMilestoneTrackerImpl
or have line 314 include a null check before trying to add to the queue's.
i.e
if (tvm != null && seenMilestoneCandidates.add(tvm)) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@achabill if you apply a change like this the code should pass. As is however it throws an exception the first time it encounters a pruned milestone. Which is the case in the regression test.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok.
I may be forced to look into #1447 now... |
* Constructor for an {@link Address} set controller from an existing {@link Address} set. | ||
* The resulting hash list is sorted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doc is unclear to me. This is not a java constructor...
Maybe write:
"Loads all transaction that mutate a certain address. It sorts them by the attachment timestamp"
* The resulting hash list is sorted | ||
* | ||
* @param tangle The tangle reference for the database to find the {@link Address} set in | ||
* @param hash The hash identifier for the {@link Address} set that needs to be found |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* @param hash The hash identifier for the {@link Address} set that needs to be found | |
* @param hash The address we are loading the transactions for |
* | ||
* @param tangle The tangle reference for the database to find the {@link Address} set in | ||
* @param hash The hash identifier for the {@link Address} set that needs to be found | ||
* @return The {@link AddressViewModel} controller generated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are returning a list of transactions (actually transaction controllers unfortunately)
* @return The {@link AddressViewModel} controller generated | ||
* @throws Exception Thrown if the database cannot load an {@link Address} set from the reference {@link Hash} | ||
*/ | ||
public static List<TransactionViewModel> loadAsSortedList(Tangle tangle, Indexable hash) throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just note (no need to change):
Usually it is best to use an interface like Indexable
in method parameters.
In this case it would probably best to use something more specific like AddressHash
because you are not going to be using other subtypes of Indexable
in this method.
However at the moment casting will be neccessary to change this...
So this is just a point to think of before we start refactoring...
if (tangle.exists(Transaction.class, item)) { | ||
return TransactionViewModel.fromHash(tangle, item); | ||
} | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why return null? Why not do a .filter(item -> (tangle.exists(Transaction.class, item))
so you won't have nulls in your list
} | ||
return null; | ||
} catch (Exception e) { | ||
return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are you swallowing exceptions? this shouldn't be happening
} catch (Exception e) { | ||
return null; | ||
} | ||
}).sorted(Comparator.comparing(tvm -> tvm != null ? tvm.getTransaction().attachmentTimestamp : 0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess sorting by attachmentTimestamp is fine
maybe add a comment that this was an arbitrary choice (you also have timestamp which is part of the bundle essence)
@acha-bill still waiting on you to respond to Gal's review before I can review myself |
Address hashes = (Address) tangle.load(Address.class, hash); | ||
return hashes.set.stream().filter(hash1 -> { | ||
try { | ||
return TransactionViewModel.exists(tangle, hash1); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
}).map(item -> { | ||
try { | ||
return TransactionViewModel.fromHash(tangle, item); | ||
} catch (Exception e) { | ||
throw new RuntimeException(e); | ||
} | ||
}).sorted(Comparator.comparing(TransactionViewModel::getAttachmentTimestamp)) | ||
.collect(Collectors.toList()); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't run it, but the following compiles and looks nicer:
public static List<TransactionViewModel> loadAsSortedList(Tangle tangle, Indexable hash) throws Exception {
Address hashes = (Address) tangle.load(Address.class, hash);
return hashes.set.stream()
.filter(ThrowingPredicate.unchecked(hash1 -> TransactionViewModel.exists(tangle, hash1)))
.map(ThrowingFunction.unchecked(item -> TransactionViewModel.fromHash(tangle, item)))
.sorted(Comparator.comparing(TransactionViewModel::getAttachmentTimestamp))
.collect(Collectors.toList());
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good and test just passed
waiting for @DyrellC to approve before I merge
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good 👍
@karimodm |
…lidification (iotaledger#1660)" This reverts commit b658b88.
…lidification (iotaledger#1660)" (iotaledger#1747) This reverts commit b658b88.
Description
Sort milestone candidates before analyzing to increase the likely hood of a new milestone being seen early.
Part of #1655
Type of change
Checklist: