m2049r / xmrwallet

monerujo: An Android Monero Wallet
https://www.monerujo.io/
Apache License 2.0
617 stars 273 forks source link

Call setName() using async network helper to avoid making network request over main thread #828

Closed j-berman closed 2 years ago

j-berman commented 2 years ago

This PR fixes #818 & #827 (app crashes when manually inputting a node without a name)

Reproducing

  1. Start a Monero node on your local wifi network using the following flags --rpc-bind-ip 0.0.0.0 --confirm-external-bind.
  2. Get the local IP of the machine running your node (on linux, input the command hostname -I and note the first IP address).
  3. On your mobile, make sure you're on the same wifi network as your node.
  4. In Monerujo, add a new node, input your IP from step 2, port 18081, leave all other fields blank, then hit TEST.

Here's the error I get before the app crashes:

2022-03-24 18:35:02.620 31085-31085/com.m2049r.xmrwallet.alpha.test.debug E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.m2049r.xmrwallet.alpha.test.debug, PID: 31085
    android.os.NetworkOnMainThreadException
        at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1605)
        at java.net.Inet6AddressImpl.getHostByAddr(Inet6AddressImpl.java:162)
        at java.net.InetAddress$1.getHostByAddr(InetAddress.java:286)
        at java.net.InetAddress.getHostFromNameService(InetAddress.java:656)
        at java.net.InetAddress.getHostName(InetAddress.java:565)
        at com.m2049r.xmrwallet.data.Node$Address.getHostName(Node.java:63)
        at com.m2049r.xmrwallet.data.Node.setDefaultName(Node.java:311)
        at com.m2049r.xmrwallet.data.Node.setName(Node.java:325)
        at com.m2049r.xmrwallet.NodeFragment$EditDialog.applyChanges(NodeFragment.java:418)
        at com.m2049r.xmrwallet.NodeFragment$EditDialog.test(NodeFragment.java:451)
        at com.m2049r.xmrwallet.NodeFragment$EditDialog.access$1300(NodeFragment.java:373)
        at com.m2049r.xmrwallet.NodeFragment$EditDialog$1.lambda$onShow$0$com-m2049r-xmrwallet-NodeFragment$EditDialog$1(NodeFragment.java:522)
        at com.m2049r.xmrwallet.NodeFragment$EditDialog$1$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:8160)
        at android.widget.TextView.performClick(TextView.java:16222)
        at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
        at android.view.View.performClickInternal(View.java:8137)
        at android.view.View.access$3700(View.java:888)
        at android.view.View$PerformClick.run(View.java:30236)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8528)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
2022-03-24 18:35:02.745 31085-31085/com.m2049r.xmrwallet.alpha.test.debug I/Process: Sending signal. PID: 31085 SIG: 9

Explanation

From StackOverflow:

This exception is thrown when an application attempts to perform a networking operation on its main thread.

For reference, here is the offending line. Explanation for what that line is doing:

The getHostName() method Java InetAddress returns the host name of a corresponding IP address. If this InetAddress was created with a host name, this host name will be remembered and returned else a reverse name lookup will be performed and the result will be returned based on the system configured name lookup service.

Solution

Seems this was the solution in place before onion support, and looks like it was removed in an accidental regression? So just bringing that code back in this PR :)