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

Cli port input #736

Merged
merged 8 commits into from
Dec 12, 2018
Merged

Cli port input #736

merged 8 commits into from
Dec 12, 2018

Conversation

beidouz
Copy link
Contributor

@beidouz beidouz commented Nov 29, 2018

Notice

It is not allowed to submit your PR to the master branch directly, please submit your PR to the master-pre-merge branch.

Description

Please include a brief summary of the change that this pull request proposes. Include any relevant motivation and context. List any dependencies required for this change.

  • Allow running the kernel with a given port number.

Fixes Issue #725 .

Type of change

Insert x into the following checkboxes to confirm (eg. [x]):

  • Bug fix.
  • New feature.
  • Enhancement.
  • Unit test.
  • Breaking change (a fix or feature that causes existing functionality to not work as expected).
  • Requires documentation update.

Testing

Please describe the tests you used to validate this pull request. Provide any relevant details for test configurations as well as any instructions to reproduce these results.

Verification

Insert x into the following checkboxes to confirm (eg. [x]):

  • I have self-reviewed my own code and conformed to the style guidelines of this project.
  • New and existing tests pass locally with my changes.
  • I have added tests for my fix or feature.
  • I have made appropriate changes to the corresponding documentation.
  • My code generates no new warnings.
  • Any dependent changes have been made.

@beidouz beidouz added this to the 0.3.3 milestone Nov 29, 2018
@beidouz beidouz self-assigned this Nov 29, 2018
Copy link
Contributor

@aion-kelvin aion-kelvin left a comment

Choose a reason for hiding this comment

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

Hey, this looks mostly good. Thanks for the thorough tests. I have a two small suggestions below.

I noticed that if you set the port value to something invalid, i.e. empty string, or a number that is invalid, the kernel starts up, prints an error message, then continues running. I noticed we do this a lot in the kernel -- serious errors often don't cause the kernel to stop. I think failing to set the port number should not allow the kernel to start up. Any thoughts on this @arajasek @AlexandraRoatis @AionJayT ?

@@ -354,7 +354,7 @@ public void toXML(final String[] args, File file) {
override = true;
String[] subArgsArr = arg.replace("--p2p=", "").split(",");
if (subArgsArr.length == 2) {
this.getNet().getP2p().setIp(subArgsArr[0]);
if (!subArgsArr[0].equals("")) this.getNet().getP2p().setIp(subArgsArr[0]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you run the code formatter with our formatting guidelines? I think we put the code of the if inside { } or at least on a different line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

will do, thanks!

Copy link
Contributor

Choose a reason for hiding this comment

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

still missing the correct formatting

if (cond) {
    cmd; 
}

modAionImpl/src/org/aion/zero/impl/cli/Cli.java Outdated Show resolved Hide resolved
@AlexandraRoatis
Copy link
Contributor

@aion-kelvin I agree in the general case, but here I think we should opt for setting the port to the default 30303 value when given an incorrect value as input.

@aion-kelvin
Copy link
Contributor

@aion-kelvin I agree in the general case, but here I think we should opt for setting the port to the default 30303 value when given an incorrect value as input.

I'm ok with that. @beidouz could we implement it this way? Also, make sure it doesn't write to the config file if the port is detected to be not valid. It should also print an error/warning.

@beidouz beidouz force-pushed the cli-port-input branch 2 times, most recently from acf02cd to 68cd950 Compare December 3, 2018 22:06
Copy link
Collaborator

@AionJayT AionJayT left a comment

Choose a reason for hiding this comment

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

LGTM

@@ -231,6 +231,20 @@ public ReturnType call(final String[] args, Cfg cfg) {

// 5. options that can be influenced by the -d and -n arguments

if (options.getPort() != null) {
int port_number = Integer.parseInt(options.getPort());
Copy link
Contributor

Choose a reason for hiding this comment

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

parseInt throws an exception when given a string that is not a number. This should be handled without crashing the kernel. For example ./aion.sh -p test will show a NumberFormatException instead of properly notifying the user that an incorrect value has been given as parameter.

To solve this issue you can surround the statement with a try-catch and print the adequate message inside the catch, or set a boolean flag to true and check for the flag in the if statement below.

Copy link
Contributor

Choose a reason for hiding this comment

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

I've noticed a tangentially-related issue that I think we should fix in this review. Linux can be configured to require root permissions for opening certain ports. By default, ports <= 1024 are need root, but it could be configured to be anything. Example:

sergiu@aion-XPS-8930:~/repos/aion2$ ./aion.sh -p 140
[...]
18-12-05 14:28:41.107 INFO  GEN  [main]: loaded block <num=24, root=2c0448b8... l=32>
18-12-05 14:28:41.171 ERROR P2P  [main]: tcp-server-socket-exception.
java.net.SocketException: Permission denied
        at java.base/sun.nio.ch.Net.bind0(Native Method)
        at java.base/sun.nio.ch.Net.bind(Net.java:461)
        at java.base/sun.nio.ch.Net.bind(Net.java:453)
        at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:227)
        at java.base/sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:80)
        at org.aion.p2p.impl1.P2pMgr.run(P2pMgr.java:194)
        at org.aion.zero.impl.AionHub.initializeHub(AionHub.java:205)
        at org.aion.zero.impl.AionHub.<init>(AionHub.java:125)
        at org.aion.zero.impl.blockchain.AionImpl.<init>(AionImpl.java:77)
        at org.aion.zero.impl.blockchain.AionImpl.<init>(AionImpl.java:55)
        at org.aion.zero.impl.blockchain.AionImpl$Holder.<clinit>(AionImpl.java:68)
        at org.aion.zero.impl.blockchain.AionImpl.inst(AionImpl.java:72)
        at org.aion.zero.impl.blockchain.AionFactory.create(AionFactory.java:34)
        at org.aion.Aion.main(Aion.java:223)
18-12-05 14:28:41.175 INFO  GEN  [main]: <node-started endpoint=p2p://32b3fee1-a64d-4b05-baca-0f7101394b63@0.0.0.0:140>
18-12-05 14:28:41.178 INFO  CONS [main]: <sealing-disabled>

Then the kernel continues running. I don't think the input validation of our code should check for this (there's other things we can't anticipate i.e. they specified a port that's already in use). Instead, can we put a try/catch around the code that opens the port and print out an error if the port can't be opened?

+ ", switching to the current port configuration: \n");
} else {
// update port in the config file
cfg.toXML(new String[] {"--p2p=" + "," + options.getPort()}, configFile);
Copy link
Contributor

Choose a reason for hiding this comment

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

This line will modify the initial config file. You can verify that config/mainnet/config.xml will have the value of the port. It also ends up writing the id in the initial file, which is not the desired outcome. To avoid these side-effects you can set the port value inside the cfg object and set the overwrite flag to true. Writing to file will be triggered correctly below due to the overwrite flag.

Additionally, you can see in the tests (e.g. options -p 12345) that the config file is overwritten twice (not necessary).

@@ -354,7 +354,7 @@ public void toXML(final String[] args, File file) {
override = true;
String[] subArgsArr = arg.replace("--p2p=", "").split(",");
if (subArgsArr.length == 2) {
this.getNet().getP2p().setIp(subArgsArr[0]);
if (!subArgsArr[0].equals("")) this.getNet().getP2p().setIp(subArgsArr[0]);
Copy link
Contributor

Choose a reason for hiding this comment

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

still missing the correct formatting

if (cond) {
    cmd; 
}

System.out.println(
"\nport out of range: "
+ port_number
+ ", switching to the current port configuration: \n");
Copy link
Contributor

Choose a reason for hiding this comment

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

please add here what port will be used

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for add default port

@@ -231,6 +231,20 @@ public ReturnType call(final String[] args, Cfg cfg) {

// 5. options that can be influenced by the -d and -n arguments

if (options.getPort() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this option can work with -c, --config as well. The if (options.getPort() != null) {...} statement can be moved above the if (options.getConfig() != null) {...} statement. This will require adding more test cases as well.

new Object[] {
new String[] {opPort, "-12345"}, RUN, expPathOnError, expPortOnError
});
// with testing port number
Copy link
Contributor

Choose a reason for hiding this comment

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

we also need here a string value for the port that is not a number, e.g. test

Copy link
Contributor Author

Choose a reason for hiding this comment

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

added

@@ -861,6 +875,9 @@ TaskPriority getBreakingTaskPriority(Arguments options) {
if (options.getDirectory() != null) {
skippedTasks.add("--datadir");
}
if (options.getPort() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please add some tests that use the port option in the CliTest.testCheckArguments as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for adding some tests for the input validation

assertThat(cfg.getKeystoreDir()).isEqualTo(new File(expectedPath, "keystore"));
// test port is updated
assertThat(Integer.toString(cfg.getNet().getP2p().getPort())).isEqualTo(expectedPort);

Copy link
Contributor

Choose a reason for hiding this comment

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

This method should also check that the initial config file port is unchanged.

Copy link
Contributor

@aion-kelvin aion-kelvin left a comment

Choose a reason for hiding this comment

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

Hey, looks good so far. After my initial review, I realized there's one more thing we should do to make our error handling for ports better (details below).

@@ -231,6 +231,20 @@ public ReturnType call(final String[] args, Cfg cfg) {

// 5. options that can be influenced by the -d and -n arguments

if (options.getPort() != null) {
int port_number = Integer.parseInt(options.getPort());
Copy link
Contributor

Choose a reason for hiding this comment

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

style: port_number should be portNumber

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍

System.out.println(
"\nport out of range: "
+ port_number
+ ", switching to the current port configuration: \n");
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for add default port

@@ -861,6 +875,9 @@ TaskPriority getBreakingTaskPriority(Arguments options) {
if (options.getDirectory() != null) {
skippedTasks.add("--datadir");
}
if (options.getPort() != null) {
Copy link
Contributor

Choose a reason for hiding this comment

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

+1 for adding some tests for the input validation

@@ -231,6 +231,20 @@ public ReturnType call(final String[] args, Cfg cfg) {

// 5. options that can be influenced by the -d and -n arguments

if (options.getPort() != null) {
int port_number = Integer.parseInt(options.getPort());
Copy link
Contributor

Choose a reason for hiding this comment

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

I've noticed a tangentially-related issue that I think we should fix in this review. Linux can be configured to require root permissions for opening certain ports. By default, ports <= 1024 are need root, but it could be configured to be anything. Example:

sergiu@aion-XPS-8930:~/repos/aion2$ ./aion.sh -p 140
[...]
18-12-05 14:28:41.107 INFO  GEN  [main]: loaded block <num=24, root=2c0448b8... l=32>
18-12-05 14:28:41.171 ERROR P2P  [main]: tcp-server-socket-exception.
java.net.SocketException: Permission denied
        at java.base/sun.nio.ch.Net.bind0(Native Method)
        at java.base/sun.nio.ch.Net.bind(Net.java:461)
        at java.base/sun.nio.ch.Net.bind(Net.java:453)
        at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:227)
        at java.base/sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:80)
        at org.aion.p2p.impl1.P2pMgr.run(P2pMgr.java:194)
        at org.aion.zero.impl.AionHub.initializeHub(AionHub.java:205)
        at org.aion.zero.impl.AionHub.<init>(AionHub.java:125)
        at org.aion.zero.impl.blockchain.AionImpl.<init>(AionImpl.java:77)
        at org.aion.zero.impl.blockchain.AionImpl.<init>(AionImpl.java:55)
        at org.aion.zero.impl.blockchain.AionImpl$Holder.<clinit>(AionImpl.java:68)
        at org.aion.zero.impl.blockchain.AionImpl.inst(AionImpl.java:72)
        at org.aion.zero.impl.blockchain.AionFactory.create(AionFactory.java:34)
        at org.aion.Aion.main(Aion.java:223)
18-12-05 14:28:41.175 INFO  GEN  [main]: <node-started endpoint=p2p://32b3fee1-a64d-4b05-baca-0f7101394b63@0.0.0.0:140>
18-12-05 14:28:41.178 INFO  CONS [main]: <sealing-disabled>

Then the kernel continues running. I don't think the input validation of our code should check for this (there's other things we can't anticipate i.e. they specified a port that's already in use). Instead, can we put a try/catch around the code that opens the port and print out an error if the port can't be opened?

@beidouz beidouz force-pushed the cli-port-input branch 3 times, most recently from 6432825 to 0d22910 Compare December 7, 2018 23:00
Copy link
Contributor

@AlexandraRoatis AlexandraRoatis left a comment

Choose a reason for hiding this comment

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

Good job!

Copy link
Contributor

@aion-kelvin aion-kelvin left a comment

Choose a reason for hiding this comment

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

Hey, thanks for your work.

One observation: if I use ./aion.sh -p 140 it will pass the basic checks but then fail to open the socket. However, after passing the basic checks, the config.xml is already updated. If no other reviewers have a problem with this, I'm ok with leaving this the way it is because I don't think the P2pMgr (the thing opening socket, which is the place you catch the socket opening error case) should go edit a config file to set it back.

Also have one minor suggestion for formatting below.

Other than that, looks good to me!

@@ -240,6 +245,8 @@ public String getDirectory() {
return directory;
}

public String getPort() { return port; }
Copy link
Contributor

Choose a reason for hiding this comment

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

public String getPort() {
return port;
}

@AlexandraRoatis AlexandraRoatis merged commit 3fff193 into master-pre-merge Dec 12, 2018
@AionJayT AionJayT deleted the cli-port-input branch January 9, 2019 21:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants