MetacoSA / NBitcoin

Comprehensive Bitcoin library for the .NET framework.
MIT License
1.88k stars 847 forks source link

Unable to find libc (Android, Unity, C#) #299

Closed EstebanGameDevelopment closed 6 years ago

EstebanGameDevelopment commented 7 years ago

Hi,

It's been 2 days that I'm stuck trying to look for a solution, so I'm really worried since the deadline is getting closer.

I'm included NBitcoin in my Unity project. Everything runs fine in the editor but when I deploy an APK file to run it on Android I get always this error:

10-30 18:05:59.269 885 903 E Unity : Unable to find libc 10-30 18:05:59.541 885 903 E Unity : EntryPointNotFoundException: getdomainname 10-30 18:05:59.541 885 903 E Unity : at (wrapper managed-to-native) System.Net.NetworkInformation.CommonUnixIPGlobalProperties:getdomainname (byte[],int) 10-30 18:05:59.541 885 903 E Unity : at System.Net.NetworkInformation.CommonUnixIPGlobalProperties.get_DomainName () [0x0000b] in :0 10-30 18:05:59.541 885 903 E Unity : at System.Net.CookieContainer..ctor () [0x0003f] in :0 10-30 18:05:59.541 885 903 E Unity : at System.Net.Http.HttpClientHandler.get_CookieContainer () [0x0000d] in :0 10-30 18:05:59.541 885 903 E Unity : at System.Net.Http.HttpClientHandler.CreateWebRequest (System.Net.Http.HttpRequestMessage request) [0x000e4] in :0 10-30 18:05:59.541 885 903 E Unity : at System.Net.Http.HttpClientHandler+c__async0.MoveNext () [0x0006a] in :0 10-30 18:05:59.541 885 903 E Unity : --- End of stack trace from previous location where exception was thrown --- 10-30 18:05:59.541 885 903 E Unity : at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <8cdd91c3618b427b905eb298374eee86>:0 10-30 18:05:59.541 885 903 E Unity : at System.Runtime.CompilerServices.TaskAwaiter.Th

Any help that you could provide me it would be really appreciated.

Thanks.

NicolasDorier commented 7 years ago

You are using Unity 4.6 right ? I think this has more to do with a Unity issue than NBitcoin, have you checked on unity forum?

NicolasDorier commented 7 years ago

If the issue is only about getdomainname, I may do something, but I am wondering if this is the case. May I see the whole stacktrace? What function are you calling?

NicolasDorier commented 7 years ago

Relevant: https://forum.unity.com/threads/httpclient.460748/ seems indeed a unity issue. Let me know what function you are calling, will try to find workaround. (not guaranteed)

EstebanGameDevelopment commented 7 years ago

Thanks for replying Nicolas!

I've isolated the problem and it only happens when I try to use QBit Ninja. Accessing only to NBitCoin works fine in Android. I need to do a mobile app where users can sell their 360 videos, I think that maybe I can have some basic functionality without the help of QBit Ninja.. I've found this documentation (https://www.codeproject.com/Articles/835098/NBitcoin-Build-Them-All#simple). My main doubt right now is just what I need to look in the response of transactionBuilder.Verify(tx) to identify if the transaction was succesfull or not. Any help you could give me would be extraordinary appreciated.

Thanks.

NicolasDorier commented 7 years ago

@EstebanGameDevelopment can you try with the new version I just pushed? v1.0.3.42 . It might solve your issue

EstebanGameDevelopment commented 7 years ago

Thanks a lot for the help Nicolas! It's great when you find professional people who reply, you are one of a kind!

Yes, the problem with the "libc.so" is now solved, but the ball is on the roof of Unity, because there is a problem with mono v2.X only supporting SHA1, so I get this error:

TlsException: Invalid certificate received from server. Error code: 0xffffffff800b010a Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (System.IAsyncResult asyncResult) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (System.IAsyncResult ar, System.Boolean ignoreEmpty) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (System.IAsyncResult result) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Rethrow as IOException: The authentication or decryption has failed. Mono.Security.Protocol.Tls.SslClientStream.EndNegotiateHandshake (System.IAsyncResult result) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (System.IAsyncResult asyncResult) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Rethrow as IOException: The authentication or decryption has failed. Mono.Security.Protocol.Tls.SslStreamBase.EndRead (System.IAsyncResult asyncResult) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Mono.Net.Security.Private.LegacySslStream.EndAuthenticateAsClient (System.IAsyncResult asyncResult) (at <344dc4d3f1ad41809df78607b6121a41>:0) Mono.Net.Security.Private.LegacySslStream.AuthenticateAsClient (System.String targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, System.Boolean checkCertificateRevocation) (at <344dc4d3f1ad41809df78607b6121a41>:0) Mono.Net.Security.MonoTlsStream.CreateStream (System.Byte[] buffer) (at <344dc4d3f1ad41809df78607b6121a41>:0) System.Net.WebConnection.CreateStream (System.Net.HttpWebRequest request) (at <344dc4d3f1ad41809df78607b6121a41>:0) Rethrow as WebException: Error: TrustFailure (The authentication or decryption has failed.) System.Net.HttpWebRequest.EndGetResponse (System.IAsyncResult asyncResult) (at <344dc4d3f1ad41809df78607b6121a41>:0) System.Threading.Tasks.TaskFactory1[TResult].FromAsyncCoreLogic (System.IAsyncResult iar, System.Func2[T,TResult] endFunction, System.Action1[T] endAction, System.Threading.Tasks.Task1[TResult] promise, System.Boolean requiresSynchronization) (at <9c9f068c46c64ffd91fda7af157b4d15>:0)

So, if it were up to Unity to solve the problem, then I wouldn't be getting any solution anytime soon.

I'll try to work without QBit Ninja. It's a pain in the ass because I hate to reinvent the wheel, but I will try to focus only in what I need.

Again, if you got any tutorial that can help me out without using QBit Ninja it would be great.

Thanks.

EstebanGameDevelopment commented 7 years ago

Ok, it seems that I was wrong, it won't work anyway, as soon as you access to the "Get" of the transaction it breaks with the TlsException error. I will have to consider PayPal to pay to the video creators and when Unity manages to fix the problem with SHA-256 I will go back to Bitcoin.

BlockrTransactionRepository blockr = new BlockrTransactionRepository();
        NBitcoin.uint256 check = new NBitcoin.uint256("4ebf7f7ca0a5dafd10b9bd74d8cb93a6eb0831bcb637fec8e8aabf842f1c2688");
        Transaction aliceFunding = blockr.Get(check);
NicolasDorier commented 7 years ago

Blockr is dead do not use it!

NicolasDorier commented 7 years ago

The problem seems to be caused by https, nothing related to SHA-256, you can access qbit through http by passing the uri in the constructor http://api.qbit.ninja/ . Can you give a try?

EstebanGameDevelopment commented 7 years ago

Yes, the problem with the uri in the constructor is solved.

Now the problem is back to another DLL (MonoPosixHelper), here is the log on Android device when accessing to the transactions with QBitNinja.

It still complains about "libc" but it's not the same Exception as before so I understand that "libc" not found is not an issue.

> 11-03 11:25:36.204  1337  1352 E Unity   : Unable to find libc
> 11-03 11:25:36.358  3147  3656 D EnterpriseController: netId is 0
> 11-03 11:25:36.358  3147  3656 D Netd    : getNetworkForDns: using netid 670 for uid 10391
> 11-03 11:25:36.358  3147  3656 D DnsProxyListener: DNSDBG::dns addrinfo af 0
> 11-03 11:25:36.442  3664  3692 I art     : Starting a blocking GC Explicit
> 11-03 11:25:36.663  3664  3692 I art     : Explicit concurrent mark sweep GC freed 14188(766KB) AllocSpace objects, 3(60KB) LOS objects, 17% free, 75MB/91MB, paused 1.797ms total 220.930ms
> 11-03 11:25:36.927  1337  1434 E Unity   : Unable to find MonoPosixHelper
> 11-03 11:25:37.028  1337  1352 E Unity   : DllNotFoundException: MonoPosixHelper
> 11-03 11:25:37.028  1337  1352 E Unity   :   at (wrapper managed-to-native) System.IO.Compression.DeflateStreamNative:CreateZStream (System.IO.Compression.CompressionMode,bool,System.IO.Compression.DeflateStreamNative/UnmanagedReadOrWrite,intptr)
> 11-03 11:25:37.028  1337  1352 E Unity   :   at System.IO.Compression.DeflateStreamNative.Create (System.IO.Stream compressedStream, System.IO.Compression.CompressionMode mode, System.Boolean gzip) [0x0004a] in <344dc4d3f1ad41809df78607b6121a41>:0 
> 11-03 11:25:37.028  1337  1352 E Unity   :   at System.IO.Compression.DeflateStream..ctor (System.IO.Stream compressedStream, System.IO.Compression.CompressionMode mode, System.Boolean leaveOpen, System.Boolean gzip) [0x0002d] in <344dc4d3f1ad41809df78607b6121a41>:0 
> 11-03 11:25:37.028  1337  1352 E Unity   :   at System.IO.Compression.DeflateStream..ctor (System.IO.Stream stream, System.IO.Compression.CompressionMode mode, System.Boolean leaveOpen, System.Int32 windowsBits) [0x00000] in <344dc4d3f1ad41809df78607b6121a41>:0 
> 11-03 11:25:37.028  1337  1352 E Unity   :   at (wrapper remoting-invoke-with-check) System.IO.Compression.DeflateStream:.ctor (System.IO.Stream,System.IO.Compression.Compre
> 
EstebanGameDevelopment commented 7 years ago

In order to help, I post here the code related only to the NBitcoin for Unity:

Download Unity Project: UnityNBitcoin

There are 3 instructions images in the package to just run the whole project without understanding too much about Unity so any programmer who is not familiar with the tool will be able to jump on board without any problems.

NicolasDorier commented 7 years ago

I can't try, I don't have unity. I think I can get rid of this exception as well. I'll release a new version soon so you can deactivate compression. This seems the problem now.

NicolasDorier commented 7 years ago

Ok can you try the following and tell me if it works. (new version 1.0.3.43)

QBitNinjaClient client =...;
client.SetHttpMessageHandler(new HttpClientHandler() { UseCookies = false }, false);
// use client
EstebanGameDevelopment commented 7 years ago

It looks like it doesn't find the SetHttpMessageHandler on the latest build

A screenshot of Visual Studio with the latest version ..43

NicolasDorier commented 7 years ago

That is very strange, can you see the method through intellisense ?

EstebanGameDevelopment commented 7 years ago

Ok, it needed from "System.Net.Http.dll"

Now the ball is on my roof because it displays this message in the Unity editor:

Loading script assembly "Assets/Plugins/Bitcoin/System.Net.Http.dll" failed!

I will tell you something as soon as I get or not a solution

EstebanGameDevelopment commented 7 years ago

I've imported the last "System.Net.Http.dll"(4.3.3) and I'm afraid we are back to square one. Unable to find "libc" when I run the app in Android device

> 11-03 17:48:47.405 16886 16901 E Unity   : Unable to find libc
> 11-03 17:48:47.460 16886 16901 E Unity   : EntryPointNotFoundException: getdomainname
> 11-03 17:48:47.460 16886 16901 E Unity   :   at (wrapper managed-to-native) System.Net.NetworkInformation.CommonUnixIPGlobalProperties:getdomainname (byte[],int)
> 11-03 17:48:47.460 16886 16901 E Unity   :   at System.Net.NetworkInformation.CommonUnixIPGlobalProperties.get_DomainName () [0x0000b] in <344dc4d3f1ad41809df78607b6121a41>:0 
> 11-03 17:48:47.460 16886 16901 E Unity   :   at System.Net.CookieContainer..ctor () [0x0003f] in <344dc4d3f1ad41809df78607b6121a41>:0 
> 11-03 17:48:47.460 16886 16901 E Unity   :   at System.Net.Http.HttpClientHandler..ctor () [0x0006f] in <56203551693747c19246346a733913ee>:0 
> 11-03 17:48:47.460 16886 16901 E Unity   :   at QBitNinja.Client.QBitNinjaClient..cctor () [0x00000] in <52314d84ca7340b6b72e7385bbe5a77c>:0 
> 11-03 17:48:47.460 16886 16901 E Unity   : Rethrow as TypeInitializationException: The type initializer for 'QBitNinja.Client.QBitNinjaClient' threw an exception.
> 11-03 17:48:47.460 16886 16901 E Unity   :   at (wrapper managed-to-native) System.Object:__icall_wrapper_mono_generic_class_init (intptr)
> 11-03 17:48:47.460 16886 16901 E Unity   :   at BitCoinController.TestBasicTransactions () [0x0000a] in <dc9ab04499784006809eda2da456c61c>:0 
> 11-03 17:48:47.460 16886 16901 E Unity   :   at BitCoinController.Start () [0x00006] in <dc9ab04499784006809eda2da456c61c>:0 
NicolasDorier commented 7 years ago

mmmh the original error should not appear. If UseCookie is at false, this should not happen.

NicolasDorier commented 7 years ago

Can you confirm you did not forgot the UseCookie to false ?

NicolasDorier commented 7 years ago

OK so update to version 1.0.3.44:

Remove the imported System.Net.Http.dll. Remove client.SetHttpMessageHandler(new HttpClientHandler() { UseCookies = false }, false);.

Add

QBitNinjaClient.SetCompression(false);
QBitNinjaClient client = ...;

In your code, try to make sure that QBitNinjaClient.SetCompression is called once, there is performance issues to call it too much time.

EstebanGameDevelopment commented 7 years ago

Ok, with SetCompression(false), it seems that somewhere else stills tries to create a deflated stream

> 11-03 21:31:56.744 10844 10861 E Unity   : DllNotFoundException: MonoPosixHelper
> 11-03 21:31:56.744 10844 10861 E Unity   :   at (wrapper managed-to-native) System.IO.Compression.DeflateStreamNative:CreateZStream (System.IO.Compression.CompressionMode,bool,System.IO.Compression.DeflateStreamNative/UnmanagedReadOrWrite,intptr)
> 11-03 21:31:56.744 10844 10861 E Unity   :   at System.IO.Compression.DeflateStreamNative.Create (System.IO.Stream compressedStream, System.IO.Compression.CompressionMode mode, System.Boolean gzip) [0x0004a] in <344dc4d3f1ad41809df78607b6121a41>:0 
> 11-03 21:31:56.744 10844 10861 E Unity   :   at System.IO.Compression.DeflateStream..ctor (System.IO.Stream compressedStream, System.IO.Compression.CompressionMode mode, System.Boolean leaveOpen, System.Boolean gzip) [0x0002d] in <344dc4d3f1ad41809df78607b6121a41>:0 
> 11-03 21:31:56.744 10844 10861 E Unity   :   at System.IO.Compression.DeflateStream..ctor (System.IO.Stream stream, System.IO.Compression.CompressionMode mode, System.Boolean leaveOpen, System.Int32 windowsBits) [0x00000] in <344dc4d3f1ad41809df78607b6121a41>:0 
> 11-03 21:31:56.744 10844 10861 E Unity   :   at (wrapper remoting-invoke-with-check) System.IO.Compression.DeflateStream:.ctor (System.IO.Stream,System.IO.Compression.Compre
> 
NicolasDorier commented 7 years ago

did you called SetCompression BEFORE creating the QBitNinjaClient ? Can I see your code, it should really not happen. Can you give me the full stack trace?

I don't see why DeflateStream would be called, with compression off, it should just not happen. I may do another version with System.IO.Compression completely so that I am sure it works... but I'd like to know why it is called.

EstebanGameDevelopment commented 7 years ago

My bad, you were right, I wrote the call SetCompression(false) in another place, it was friday night and I was pretty tired.

Now that I'm starting the day fresh I can say everything is working fine. I can call to QBitNinjaClient to perform all the operations of this example.

I've updated the ZIP file of the project so any other Unity programmers can benefit from the awesome work we have done. The project is ready to make a build for Android device, you only have to remember to write the password "testtest" in the process of building:

Download UnityNBitcoin Basic Example Project

Also, here is the APK if you have an Android device and you want to test the behaviour of NBitcoin on your device.

Download APK UnityNBitcoin

Now it's time for me to start the real deal, make it work for my project.

Thanks a lot Nicolas!!!

NicolasDorier commented 7 years ago

Hey can you make a small PR on https://github.com/MetacoSA/QBitNinja in the README to document the peculiarity of Unity?

EstebanGameDevelopment commented 7 years ago

I'm working with SourceTree and it seems that I don't have permissions to commit and push the README. Anyway the only thing that should be explained is:

Unity

In order for the API to work in Unity for Android devices you should:

  • QBitNinjaClient.SetCompression(false); Because it's missing the DLL MonoPosixHelper from the build
  • QBitNinjaClient client = new QBitNinjaClient("http://api.qbit.ninja/", NBitcoin.Network.Main); Because Mono v2.X only supporting SHA1, not SHA256
  • Scripting Runtime Version: Select "Experimental (.NET 4.6 Equivalent)"
NicolasDorier commented 7 years ago

You can directly edit the README under github, and easily do a PR, can you ?

EstebanGameDevelopment commented 7 years ago

Done!! 👍

I don't have permissions to upload files, so feel free if you want to upload the Unity sample I made to the repository

NicolasDorier commented 7 years ago

You changed it on your private repo, but you did not created the pull request.

NicolasDorier commented 6 years ago

Solved.