Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor capabilities and other P2P-related stuff #2469

Merged
merged 14 commits into from
Mar 6, 2019

Conversation

freimair
Copy link
Member

@freimair freimair commented Feb 26, 2019

Got rid of the Capability ordinals being used all over the place - a first and major step towards a cleaner, more readable Bisq code base where Bugs have less places to hide. (Done in my intention to clean up the p2p part)

Doing that I even managed to remove some 60 loc: some stats using github.com/AlDanial/cloc v 1.80

EDIT: after a quick chat with @ManfredKarrer I did some more refactoring...

_ files blank comment code
same 0 0 1087 3842
modified 32 0 7 208
added 1 18 37 114
removed 0 40 5 304

Note

this is a fairly big change where functionality should remain the same. However, this needs thorough testing.
My suggestion is that every reviewer of this PR should have a testing session with me where we do the basic things such as a simple trade so major bugs are discovered before merging.
In-depth testing is done anyhow before the next release...

@freimair freimair changed the title Refactor capabilities [WIP] Refactor capabilities Feb 27, 2019
@ManfredKarrer ManfredKarrer added this to the v0.9.6 milestone Mar 1, 2019
github.com/AlDanial/cloc v 1.80  T=0.19 s (5.3 files/s, 5.3 lines/s)
-------------------------------------------------------------------------------
                             files          blank        comment           code
-------------------------------------------------------------------------------
 same                            0              0            913           3405
 modified                       28              0              6            145
 added                           1             18             36             58
 removed                         0              9              3            103
-------------------------------------------------------------------------------
@freimair freimair changed the title [WIP] Refactor capabilities Refactor capabilities and other P2P-related stuff Mar 6, 2019
Copy link
Member

@ManfredKarrer ManfredKarrer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

In Peer the EqualsAndHashCode should include a super call. I will push that afterwards.
IntelliJ reports such issues with static code analysis (colored bg), otherwise I would not have spotted it as well ;-)
@EqualsAndHashCode(exclude = {"date"}, callSuper = true)

I tested just lightly. As that comes with many "risky" changes we have to observe well if there are any issues reported which might be connected to the topics of that PR.

@@ -39,47 +38,43 @@
@Getter
@EqualsAndHashCode(exclude = {"date"}) // failedConnectionAttempts is transient and therefore excluded anyway
@Slf4j
public final class Peer implements NetworkPayload, PersistablePayload, SupportedCapabilitiesListener {
public final class Peer extends Capabilities implements NetworkPayload, PersistablePayload, SupportedCapabilitiesListener {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing call to super in @EqualsAndHashCode

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extension feels not really right to me here. A peer "has capabilities" and not "is capabilities".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same with SharedModel in Connection class..

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aggreed. but peer.isCapabilitySupported(...) and connection.isCapabilitySupported(...) feels quite right. Having them implement some sort of HasCapabilities interface would result in peer.getCapabilities().isCapabilitySupported(...) which imho is confusing.

// TODO got even worse after refactoring
List<Integer> current = Capabilities.toIntList(Capabilities.app);
current.add(Capability.SEED_NODE.ordinal());
Capabilities.app.resetCapabilities(Capabilities.fromIntList(current));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not add a method for appending a capability? Check to not add duplicates can be done with capability object itself rather then ordinal, no (missing here but was at another class where it was added after checking if not already there)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

first, there is a TODO and second, we need that kind of code exactly once. and once more for the monitor.

} else {
return msg instanceof CapabilityRequiringPayload && sharedModel.isCapabilitySupported(((CapabilityRequiringPayload) msg).getRequiredCapabilities());
return true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The noCapabilityRequiredOrCapabilityIsSupported is very hard to understand (was worse before). Maybe we should use that refactoring moment for improving the method so it becomes more easier.
I would need more time to review the corrtectness (compared to the old version), but would prefer to invest that time in a improved method version.

Copy link
Member Author

@freimair freimair Mar 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I thought about changing stuff around but it quickly gets dirty.

Most beautiful would be that we do not need the method at all but instead can use a connection.isCapabilitySupported(msg) or isCapabilitySupported(msg) directly. However, the class hierarchy has grown overly complicated over time and such a solution is not possible as things stand now (would result in a diamond pattern if Java would allow for that).

Even looks worse if depicted like that:
messages

I even tried to use java8/9 defaults in interfaces and create some sort of mixins. Nasty stuff. Definitely needs cleanup! Small steps...

/**
* The global set of capabilities, i.e. the capabilities if the local app.
*/
public static final Capabilities app = new Capabilities();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a more descriptive name here. When I read Capabilities.app it was not very clear what it means.
Also does not need to be static?
Should the class extend HashSet instead of using the field capabilities - as that is basically what it holds?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should make it a Guice instance scoped as singleton?
And then use it in peer and shared model as parameter passed to the constructor (I know there is missing guice and passing is painful)... So maybe keeping the Capabilities.app static is less painful?
But then maybe its better to move it to another class which reflects that it holds the global capability state of the app?

Copy link
Member Author

@freimair freimair Mar 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a more descriptive name here. When I read Capabilities.app it was not very clear what it means.

make a suggestion

Also does not need to be static?

yes, as it holds the capabilities of the running Bisq itself and is used in multiple places all over the code.

Should the class extend HashSet instead of using the field capabilities - as that is basically what it holds?

see below

@Setter
private static List<Integer> supportedCapabilities = new ArrayList<>();
public void resetCapabilities(Capabilities capabilities) {
resetCapabilities(capabilities.capabilities);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

capabilities.capabilities reads strange. If we would use a HashSet as super class i think it becomes more natural.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes I thought about that but having Set as superclass adds all the methods as well and well, makes the whole Capabilities class superfluous which then results in handling capabilities like a set. I do not know if we want that.

resetCapabilities(capabilities.capabilities);
}

public void resetCapabilities(Collection<Capability> capabilities) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would replaceCapabilities be better than resetCapabilities? With reset I would expect more the clear funtion rather then the additional add.

Copy link
Member Author

@freimair freimair Mar 7, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm interesting. A setCapabilities seems to me clear as it replaces all capabilities, a resetCaps indicates more strongly, that the capabilities are going to be replaced. I would understand a clearCapabilities as a clear without add.

Again, in a collection of event logs, a reset clears the log.

Hm. setCapabilities or simply set?

@ManfredKarrer ManfredKarrer merged commit 73eea79 into bisq-network:master Mar 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants