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

[mobile] Mobile RPCs #3282

Open
wants to merge 10 commits into
base: master
from

Conversation

@halseth
Copy link
Collaborator

commented Jul 9, 2019

This PR adds the necessary APIs and build scripts in order to compile lnd for mobile platforms.

Building mobile libraries

Prerequisites

gomobile

Follow gomobile in order to intall gomobile and dependencies.

Remember to run gomobile init! (otherwise the lnd build might just hang).

falafel

Install falafel:

go get -u -v github.com/halseth/falafel

Building lnd for iOS

make ios

Building lnd for Android

make android

make mobile will build both iOS and Android libs.

Libraries

After the build has succeeded, the libraries will be found in mobile/build/ios/Lndmobile.framework and mobile/build/android/Lndmobile.aar. Reference your platforms' SDK documentation for how to add the library to your project.

API docs

TODO

@halseth halseth force-pushed the halseth:mobile-rpcs branch from f54fe43 to 03728a1 Jul 9, 2019

@cfromknecht cfromknecht self-requested a review Jul 9, 2019

func Start(extraArgs string, callback Callback) {
// Add the extra arguments to os.Args, as that will be parsed during
// startup.
os.Args = append(os.Args, strings.Fields(extraArgs)...)

This comment has been minimized.

Copy link
@ottosuess

ottosuess Jul 10, 2019

Contributor

splitting the extraArgs string breaks if I want to pass a path that contains a space.
e.g. /Library/Application\ Support

This comment has been minimized.

Copy link
@halseth

halseth Jul 19, 2019

Author Collaborator

Can you check if this helps: 22f7b0c

This comment has been minimized.

Copy link
@ottosuess

ottosuess Jul 19, 2019

Contributor

seems like it's working 🙌
haven't done a lot of testing though.

@halseth halseth force-pushed the halseth:mobile-rpcs branch from 03728a1 to 986c8ff Jul 10, 2019

@halseth halseth force-pushed the halseth:mobile-rpcs branch 2 times, most recently from 98bdf6b to a68752c Jul 10, 2019

@cfromknecht

This comment has been minimized.

Copy link
Collaborator

commented Jul 11, 2019

@halseth didn't get a chance to review the autogenerated code :(

@halseth

This comment has been minimized.

Copy link
Collaborator Author

commented Jul 11, 2019

@cfromknecht added a temp commit with the generated API!

// NOTE: This method produces a stream of responses, and the receive stream can
// be called zero or more times. After EOF error is returned, no more responses
// will be produced.
func SendPayment(msg []byte, rStream RecvStream) {

This comment has been minimized.

Copy link
@ottosuess

ottosuess Jul 11, 2019

Contributor

same name & package as the SendPayment method in lightning_api_generated.go.
maybe add a prefix to the methods generated by sub-services?

This comment has been minimized.

Copy link
@sergioabril

sergioabril Jul 11, 2019

@ottosuess agree. But as @halseth suggested somewhere else, you can try setting usePrefex=1 on gen_bindings.sh

(Haven't tried though, I manually changed names)

This comment has been minimized.

Copy link
@halseth

halseth Jul 19, 2019

Author Collaborator

Made it possible to add directly to make (73cb325):

make ios tags="routerrpc" prefix=1
@ottosuess

This comment has been minimized.

Copy link
Contributor

commented Jul 11, 2019

Would be cool to have a way to inject custom protoc plugins like protoc-gen-swift.

At zap we have a custom "falafel" plugin to generate swift apis that i'd like to inject somehow.


# Generate APIs by passing the parsed protos to the falafel plugin.
opts="package_name=$pkg,target_package=$target_pkg,listeners=lightning=lightningLis walletunlocker=walletUnlockerLis,mem_rpc=1"
protoc -I/usr/local/include -I. \

This comment has been minimized.

Copy link
@wbobeirne

wbobeirne Jul 17, 2019

Just thought I'd mention that I didn't have this command, had to run brew install protobuf to get it. Might be worth adding it as a prerequisite to the docs.

This comment has been minimized.

Copy link
@halseth

halseth Jul 19, 2019

Author Collaborator

Thanks, fixed: 7d01dc5

@halseth

This comment has been minimized.

Copy link
Collaborator Author

commented Jul 19, 2019

Would be cool to have a way to inject custom protoc plugins like protoc-gen-swift.

At zap we have a custom "falafel" plugin to generate swift apis that i'd like to inject somehow.

I think this is a pro-level feature for now, so can be done by modifying gen_bindings directly 😄

@halseth halseth force-pushed the halseth:mobile-rpcs branch 2 times, most recently from 3afc538 to 5aded27 Jul 19, 2019

halseth added some commits Jan 24, 2019

make+mobile: define gen_bindings.sh
gen_bindings uses falafel to generate Go bindings from the lnrpc
protos.

halseth added some commits Jan 24, 2019

lnd+cmd/lnd/main: add ListenerCfg to Main
ListenerCfg allows passing custom listeners to the main method, to be
used for the wallet unlocker and rpc server. If these are set these will
be used instead of the regular RPC listeners.

@halseth halseth force-pushed the halseth:mobile-rpcs branch from 5aded27 to 3760f29 Jul 24, 2019

@wpaulino wpaulino added this to the 0.8.0 milestone Jul 25, 2019

)

// Start starts lnd in a new goroutine.
//

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Jul 30, 2019

Member

How is lnd meant to be torn down? Or is the assumption everything will die as soon as the parent process does?

Is it possible for us to receive signals on the mobile systems as we do right now on the current base operating systems? Certain sub-systems like the tower client rely on being notified for a critical shutdown vs a regular one.

// extraArgs can be used to pass command line arguments to lnd that will
// override what is found in the config file. Example:
// extraArgs = "--bitcoin.testnet --lnddir=\"/tmp/folder name/\" --profile=5050"
func Start(extraArgs string, callback Callback) {

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Jul 30, 2019

Member

Why not pass them in as a []string? That would let us get rid of this parsing code.

// We call the main method with the custom in-memory listeners called
// by the mobile APIs, such that the grpc server will use these.
cfg := lnd.ListenerCfg{
WalletUnlocker: walletUnlockerLis,

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Jul 30, 2019

Member

Commit ordering wise, these variables don't yet exist.

}
}()

// TODO(halseth): callback when RPC server is running.

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Jul 30, 2019

Member

Care to elaborate on this?

// We wait until the user provides a password over RPC. In case lnd is
// started with the --noseedbackup flag, we use the default password
// for wallet encryption.
if !cfg.NoSeedBackup {
params, err := waitForWalletPassword(
cfg.RPCListeners, cfg.RESTListeners, serverOpts,
restDialOpts, restProxyDest, tlsCfg,
cfg.RPCListeners, cfg.RESTListeners, restDialOpts,

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Jul 30, 2019

Member

Do we still need to pass in the raw listeners if we have this new function closure? Also will REST on mobile be disabled by default?

subServerCgs *subRPCServerConfigs, restDialOpts []grpc.DialOption,
restProxyDest string, atpl *autopilot.Manager,
invoiceRegistry *invoices.InvoiceRegistry, tower *watchtower.Standalone,
tlsCfg *tls.Config, getListeners func() ([]net.Listener, func(),

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Jul 30, 2019

Member

This is a bit cluttered now, perhaps we should make a new type for this function closure type?


// RPCListener can be set to the listener to use for the RPC server. If
// nil a regular network listener will be created.
RPCListener net.Listener

This comment has been minimized.

Copy link
@Roasbeef

Roasbeef Jul 30, 2019

Member

Do we have any example code w.r.t how these are set and initialized in a mobile setting?

@valentinewallace
Copy link
Collaborator

left a comment

Awesome, can't wait to get this in!! 🎆 👍

[]grpc.ServerOption, error) {

// If we have chosen to start with a dedicated listener for the
// wallet unlocker, we we return it directly, and empty server

This comment has been minimized.

Copy link
@valentinewallace

valentinewallace Jul 31, 2019

Collaborator

nit: s/we we/we

@@ -0,0 +1,13 @@
[Application Options]
debuglevel=info
no-macaroons=1

This comment has been minimized.

Copy link
@valentinewallace

valentinewallace Jul 31, 2019

Collaborator

Wonder if most mobile clients won't use macaroons 🤔 Feels weird to "suggest" it haha

return grpcListeners, cleanup, serverOpts, nil
}

// walletUnlockerListeneres is a closure we'll hand to the wallet

This comment has been minimized.

Copy link
@valentinewallace

valentinewallace Jul 31, 2019

Collaborator

nit: s/walletUnlockerListeneres/walletUnlockerListeners

req proto.Message) (proto.Message, error) {

// Get the gRPC client.
client, close, err := getAutopilotClient()

This comment has been minimized.

Copy link
@halseth

halseth Aug 1, 2019

Author Collaborator

close is a reserved keyword

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants
You can’t perform that action at this time.