-
Notifications
You must be signed in to change notification settings - Fork 370
White flag #1806
base: white-flag
Are you sure you want to change the base?
White flag #1806
Conversation
return null; | ||
} | ||
if (!milestoneService.isTransactionConfirmed(transactionViewModel, milestoneIndex)) { | ||
Stack<Hash> stack = new Stack<>(); |
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.
Please implement stack with a Deque
It is a much more efficient implementation...
Stack
relies on Vector
which is quite obsolete
See the javadocs of the Stack
class:
* <p>A more complete and consistent set of LIFO stack operations is
* provided by the {@link Deque} interface and its implementations, which
* should be used in preference to this class. For example:
* <pre> {@code
* Deque<Integer> stack = new ArrayDeque<Integer>();}</pre>
if(isConsistent){ | ||
state = currentState; | ||
}else{ | ||
transactionViewModel.isConflicting(tangle, initialSnapshot, true); |
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.
Can you change to setConflicting
is
is the prefix of a boolean java getter
final Hash address = bundleTransactionViewModel.getAddressHash(); | ||
final Long value = currentState.get(address); | ||
currentState.put(address, value == null ? bundleTransactionViewModel.value() | ||
: Math.addExact(value, bundleTransactionViewModel.value())); |
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.
If an overflow exception is thrown here then we would like to make sure the bundle is ignored
/** | ||
* This flag indicates whether the transaction is conflicting and was ignored in balance computation | ||
*/ | ||
public boolean conflicting = false; |
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.
Since you branched off dev
this is correct
But we know that soon this should turn Atomic
or volatile
So might as well do it now so we won't forget...
Technically volatile
suffices here but since in 1.9.0 we made everything Atomic
we made as well make it atomic
|
||
boolean approvedTrunk = (trunk.snapshotIndex() > 0) && (trunk.snapshotIndex() != milestoneIndex); | ||
boolean approvedBranch = (branch.snapshotIndex() > 0) && (branch.snapshotIndex() != milestoneIndex); | ||
if ((trunk.isEmpty() || visitedTransactions.contains(trunk.getHash()) || approvedTrunk) && |
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.
One should note that an empty transaction is the same as the genesis transaction (genesis transaction has all 9's trytes, and all 9s Hash). Then it is fine...
If the transaction was empty because the trunk tx is simply missing (not solid) then we have a problem...
I know you went according to the RFC, I just added a comment on it as well...
/** | ||
* Checks if a transaction is empty. | ||
* @return True if empty. False otherwise. | ||
*/ | ||
public boolean isEmpty(){ | ||
return Arrays.equals(getBytes(), new byte[SIZE]); | ||
} | ||
|
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.
Currently we are just check for TransactionViewModel.PREFILLED_SLOT
I am not saying that this is smart (I didn't make this weird design)
But it will be more awful if we have more than one way to do this check...
So I wouldn't have this method now
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 the one comment about labelling/commenting, otherwise it looks like it passes muster. The updated regression test is a nice touch as well.
|
||
boolean approvedTrunk = (trunkTransactionViewModel.snapshotIndex() > 0) && (trunkTransactionViewModel.snapshotIndex() != milestoneIndex); | ||
boolean approvedBranch = (branchTransactionViewModel.snapshotIndex() > 0) && (branchTransactionViewModel.snapshotIndex() != milestoneIndex); | ||
if ((trunkTransactionViewModel.getType() == TransactionViewModel.PREFILLED_SLOT || visitedTransactions.contains(trunkTransactionViewModel.getHash()) || approvedTrunk) && |
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.
Perhaps providing labels for these conditions as booleans instead of rewriting them in the if and else statements here could help to declutter this section. There are a lot of conditions being thrown around very close together here that could make it harder to follow. For example another boolean for each the trunk and branch types to be reused below in the else statement. More descriptive labels or a few extra comments could go a long way towards making the logic easier for others to follow.
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.
Some more changes please
boolean isLeafTrunk = isEmptyTrunk || visitedTransactions.contains(trunkTransactionViewModel.getHash()) || isApprovedTrunk; | ||
boolean isLeafBranch = isEmptyBranch || visitedTransactions.contains(branchTransactionViewModel.getHash()) || isApprovedBranch; |
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.
hmm I think that here we let way for confirming non solids...
I am pretty sure that if we reach an empty trunk it means we have a non-valid subtangle
The exception here is that if it is the genesis transaction, then it should be fine (but tip-sel should not allow it and we should test for it)
@@ -87,3 +87,47 @@ Feature: Test transaction confirmation | |||
| keys | values | type | | |||
| states | False | boolListMixed | | |||
|
|||
Scenario: Conflicting bundles are ignored |
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.
Maybe add a scenario for invalid bundles
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.
Already done in my PR, theyre in the disabled regression tests file in machine 3
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.
was just about to tag you here @kwek20 but I see you are very alert :-)
//Don't confirm non-solid txs. | ||
Hash genesisHash = Hash.NULL_HASH; | ||
if(isEmptyTrunk && !allowGenesisReference){ | ||
return null; | ||
} | ||
//proceed only if empty trunk or branch is genesis | ||
if((isEmptyTrunk && !trunkTransactionViewModel.getHash().equals(genesisHash))|| | ||
(isEmptyBranch && !branchTransactionViewModel.getHash().equals(genesisHash))){ | ||
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.
- In the event that trunk or branch have a non
9s
hash then this is wrong - I believe (I think I missed it in the last review so my bad) that the
9s
genesis hash is in thesolidEntryPointsSet
So I think the flag is unnecessary (because we should always allow genesis reference)
I think we should always return null if it is PREFILLED_SLOT
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.
Since we return null
if branch
or trunk
is PREFILLED_SLOT
.
Is this the only definition of a leaf
?
boolean isLeafTrunk = visitedTransactions.contains(trunkTransactionViewModel.getHash()) || isApprovedTrunk;
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.
Yes, when visitedTransactions
contain all SEPs and genesis
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 was having one last look before publishing this on Discord.
I think you can still take the opportunity to:
- Extract private methods to make
generateBalanceDiff
more readable - Add a unit test that mocks a tangle with conflicts and generates the balance diff
No need to rush to do it this sprint because we might get external feedback
}else if(!isLeafBranch) { | ||
stack.addFirst(branchTransactionViewModel.getHash()); | ||
} | ||
}catch(Exception e){ |
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.
}catch(Exception e){ | |
} catch(Exception e) { |
Description
Ability to confirm conflicting bundle while applying only the first to the ledger.
The order of bundles is determined by a topological sort via DFS preferring trunk first.
Fixes #1684
Type of change
How Has This Been Tested?
Checklist: