-
Notifications
You must be signed in to change notification settings - Fork 14
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
Convert to a Flutter FFI plugin #1
Comments
There's also https://github.com/corrosion-rs/corrosion 👀 |
@jeandudey I tested it but I found it an overkill and it doesn't even work for Android. I think for the Linux build it's enough to do vanilla cmake like:
Android should work with: https://github.com/mozilla/rust-android-gradle |
The CypherStack team managed to get a cargo-built rust plugin working in flutter_libepiccash, so I am referencing that repo while following your first link to try and get this building as a Flutter FFI plugin. It should work on iOS, Android, linux and mac desktop, and I think I even got it working on Windows (Monero was a blocker for Windows so the plugin mentioned before didn't undergo extensive testing and use on that platform) I can only test Android and linux and Windows desktop platforms |
Thanks @sneurlax! We can test on iOS/macOS |
OK I have got it building but not tested working on android and linux in https://github.com/sneurlax/flutter_libtor/tree/flutter-plugin I just renamed the repo to flutter_libtor to match other Stack Wallet plugins for our use because I'll be testing the tor-ffi plugin as part of that, but after getting it working I'll make a branch with the changes necessary so y'all don't have to rename anything on your end and can look over the changes without them being attached with a repo name change You can follow README.md and run the scripts in eg scripts/android or scripts/linux to test, maybe it will be easier for you to test if either works than it will be for me to get the example app working? |
Thank you @sneurlax. So with this approach you still need to manually run the script? I'd prefer for this to build automatically (as long as user has cargo and other dependencies) by triggering cargo (or the scripts themselves) from cmake/cocoapods like in the Flutter FFI template. Imagine if we publish this on pub.dev and user does an |
Yes, you have to manually run the script. That's how CypherStack's plugins are set up. That's a very good point and that makes sense, I'll try to do that now but I'm not familiar with it. If the Flutter FFI template does it, though, I should be able to follow that example and get it building automatically. Not sure if I can get to that today or tomorrow, have something else needing addressing |
I was working along these lines and got linux working, but while addressing android I found https://github.com/fzyzcjy/flutter_rust_bridge and hope it offers a better approach overall |
Their approach is outlined in https://cjycode.com/flutter_rust_bridge/library/platform_setup.html#how-it-works:
Basically they suggest building the binaries on the CI and uploading somewhere. Flutter plugin build then fetches the binaries from the internet. I'm not sure if this approach works for us (Foundation Devices) since repoducible builds is one of our aims. With this apporach if the user wanted to verify the build he'd have to build the rust libs himself and then change the code to point to whereever he put those binaries. Seems pretty involved and I'm not even sure if it would work. @sneurlax give me like a week to retry the trigger-the-script-from-cmake-gradle-cocoa-whatever approach again and I'll report back here. Executing a custom command in the build process, how hard can it be? (famous last words) |
How we are approaching this is that there are two scripts, build and download, basically. We will still default to building it from source, but the download script downloads tagged binaries from github releases. If your builds are reproducible and will produce the same binary as a tagged release, I only see upsides to this approach: you don't have to build, but if you do, you can verify that the output is identical. Reproducibility is still an outstanding issue for us, so not all local builds will match tagged releases, but if yours are reproducible, then downloading and verifying should be just as safe as building locally, right? We're missing that feature but offering downloading binaries as an option for the convenience of higher-level developers that don't want to bother with sometimes-lengthy builds (we build Monero from source... twice, ha!) As to
you have the build and download script put their outputs in the same place: wherever they'd go to get built or bundled into your binary, package, etc.
We have been wanting to follow the example of isar, which wraps rust as a dart ffi plugin and is distributed as tagged binaries per-platform similar to the approach described by flutter_rust_bridge... I'm not sure if they've achieved reproducibility, but the number of contributors they have communicates to me that their system for modifying the source and testing the binaries is coherent, at least Let me know how I can help. For the time being I'm going to test and see how flutter_rust_bridge works if all downloading is disabled and we just build from source every time (that's gotta be possible... right?) |
After some thinking I'd say you are right. It's totally okay to have the default be to download - as long as the "power-user" can still build from source locally. As the CI would probably just be GH actions it would be obvious what source the binaries are built from (as long as you trust GitHub - but we all implicitly do here). Since the approach in your branch is somewhat similar to what I have closed #3 but maybe it can be used later on, in case we decide to do some cool way of triggering the local build (maybe with build flavours?). |
PS I forked this and pushed changes on top of your #ffi-plugin branch pushing things forward a bit. I generated C headers and dart bindings and I think this is ready to be used, but I had trouble testing. I'll have to revisit it. I wanted to see if libtor (vs libtor-sys) would be any better, but it wasn't much better... |
Here's another example of a rust plugin done well: https://github.com/LtbLightning/bdk-flutter I am just trying to use the generated dart bindings now 🤞 |
OK! I got it building and apparently working on a fork of your ffi-plugin branch in the tor branch of stack_wallet. when I use
so it seems to be working, but I need to test it better. The scripts need cleaning and they don't run automatically yet. I'd like to polish this package up a bit and maybe get the example app running if that'd be helpful--what would you say are the next steps here? |
One thing I notice is that I'm going to need to configure the directory used for tor files, as right now they're put into ~/Documents by default |
By all means! As long as |
Like you said if we could get a simple start/stop Tor example app running that would be grand. |
I got the start/stop Tor example up, but am wondering how to actually use it :P I'll get the example app working vs how I'm demoing use now: cypherstack#2 I'll post here again later when I get the standalone example working |
I updated the ffi-plugin branch's flutter example app to show start/stop: https://github.com/sneurlax/tor/blob/ffi-plugin/example/lib/main.dart |
I'm looking into usage beyond start/stop, got any tips? will try connecting to daemon as socks5 proxy tomorrow I still need to make/fix and demonstrate builds for android |
also note that I got another Rust-to-Dart example working well in https://github.com/sneurlax/libxmr after having gone through this process a key takeway is to generate C bindings from Rust, not C++ |
I connected to it as a normal, authenticated socks5 proxy and successfully showed a Tor exit node ip, so at this point I'm going to work on adding a configuration model I am having issues with host lookups for .onion services |
We connect to .onion services through BDK and that "just works" by passing the socks proxy parameters. What client are you using? |
I had to make a custom client in order to support sockets over the socks5 proxy: https://github.com/cypherstack/tor/blob/main/example/lib/socks_socket.dart but this doesn't necessarily address .onion lookups; I'll have to look at it again. Right now we're focusing on trying to connect to clearnet nodes through the proxy vs .onion-hosted nodes @julian-CStack made significant progress removing the requirement for manual or scripted building using cargokit, but an open issue prevents some platforms from working. That code is here: https://github.com/cypherstack/tor/tree/no_scripts_updated_cargokit but when it works, it's really cool to just flutter run it and go. The author of cargokit has already filed an issue and a fix, so we should eventually be able to remove all the manual setup instructions and scripts alike Now we need a way to stop the daemon. Got any suggestions for approaching that @icota ? I haven't even really looked into Arti's rust or API since the change, but I'll dive in--just wanted to report progress on removing the manual build steps and replacing scripted setups and see if you had an easy stop method handy |
@sneurlax one way to stop the "daemon" would be to Let's investigate and compare notes |
Just a small heads-up, Cargokit now has workaround for the pub bug so the symlink is resolved beforehand. I also added github action that builds example project for all possible platforms / configurations to detect regressions like this earlier. |
Thank you @knopp! @icota we have Linux, iOS, and Android working now thanks to @julian-CStack, but macOS uses a precompiled binary right now. I haven't tested Windows yet, but it should work and here's that PR I'll be testing Windows next but like I said, it should work if you want to give it a try :) I haven't worked on adding a stop or status function, stopping could save lots of battery so that will probably be next. I'm tracking it in issues over on our fork |
@knopp and @julian-CStack helpfully resolved the macOS build issue, so we will make another PR for that once it's polished. I've yet to test Windows, still working on fixing certain aspects of our usage of this plugin |
macOS just uses a recompiled binary currently, otherwise this issue could be closed or it could be closed by #17 (which currently has issues to resolve of its own) |
#20 solved the macOS precompiled binary issue. So this should be good or close to publishing, right? The only issue might be the SOCKSSocket class, which I did find has an issue: cypherstack#24 I had to write it custom because many other packages I tried wouldn't work for our use case (raw socket use to connect to ElectrumX). It could and maybe should be spun out as a separate package. We moved it into the main lib dir and exported it so that we wouldn't have to manually sync fixes between repos, rather just using one source for the class, but it probably ought to get published as a standalone package because--as far as I tested--none of the top 6 or so major SOCKS5 Dart packages support HTTP, HTTPS, and socket connections (at least insofar as we needed). It isn't even needed except for its use in the example app. I had to put a lot of work into that to make sure our use case was covered tho. You could also just remove it and not use it in the example even |
As per https://codelabs.developers.google.com/codelabs/flutter-ffigen#2
Shoehorning cargo into a cmake/cocoapods build might be a challenge
The text was updated successfully, but these errors were encountered: