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

An event driven Bisq stack with interaction over localhost or TOR websocket #8

Closed
citkane opened this issue Mar 5, 2018 · 9 comments
Assignees

Comments

@citkane
Copy link

citkane commented Mar 5, 2018

This is a "proof of concept proposal" that assembles a number of "in progress" modules into a modified application stack architecture. All modules work in a Regtest environment.

Move all business logic and data models into a common module

https://github.com/citkane/bisq-business
Slack: #business-logic

This presently has basic logic and methods to set up a bisq user, create offers and fulfill trade through to completion. It already works with bisq-engine to provide logic for REST endpoints, and awaits minor refactoring to some gui packages to become a drop-in provider there also.

Provide a bootable, shade'able shell module which provides REST endpoints to localhost

https://github.com/citkane/bisq-engine
Slack: #engine

Business logic and further functionality drops into the shell by modular packing. Theoretically, it is possible to build any distribute-able, run-able jar purely from the POM and by providing correct REST interface classpaths to drop-in sub-modules.

Provide a packaging wrapper to the shaded.jar that can receive a websocket data-stream from TOR and translate it to calls to localhost REST/API interfaces.

https://github.com/citkane/bisq-front
Slack: #front

At the moment this is providing a web GUI to drive basic Bisq trading. This is just one usage, and the GUI needs to be factored out into a package of it's own.

it will further provide the security model for access control to the data stream and will be also be able to direct communication on localhost between Bisq and other third party logic, such as automated trading bots, automated payment API's or network reporting tools.

Given that, once the encrypted websocket is established, data transfer over TOR becomes use-ably fast as the connection is held open and TOR does not seek new routes until the connection is closed. This can be used to transmit both events and data.

With this in mind, and a bit of work to for bisq-engine to provide event broadcasting, the javaFX gui can be plausibly refactored to work as is as a remote thin client, or remain as an integrated desktop interface under ONE architecture and codebase. The road is now also open for mobile apps and web front-ends.

@citkane citkane changed the title An event driven Bisq stack with remote UI over localhost or TOR websocket An event driven Bisq stack with interaction over localhost or TOR websocket Mar 5, 2018
@citkane
Copy link
Author

citkane commented Mar 6, 2018

Usage examples

1 - You are developing a new Bisq module

Let us imagine a fictional Bisq module called Foo which eg, interacts with the network to do some analysis and reporting about valuable insight. Maybe you also want it to provide a report template to be served over html.

Step one

  • create an empty Maven project and declare a dependency to bisq-engine.
  • declare any additional Bisq modules / dependencies you may need.
  • point Maven to engine's main classpath

At this point you can do mvn clean install and have a runnable jar with command line options to launch a Bisq node tailored to Foo's needs:

  • With / without desktop GUI
  • With / without http server on localhost at specified port.The http endpoint will already serve a documented Swagger interface for existing API endpoints.
  • (TODO) flags for a wider range of boot-strap scenarios. (eg, maybe Foo needs to be a seeednode)

Step two

  • construct Foo's business logic. You will already have all the low level services at io.bisq.business.Data and a wealth of pre-existing logic constructors at io.bisq.business.actions.
  • use the pre-existing formatters and validators under io.bisq.business
  • build any additional logic, formatting or validation Foo may need under the io.bisq.business classpaths.
  • (TODO) Run required additional boot logic by overriding a container class that engine will supply.
  • provide additional REST endpoints for Foo by extending the io.bisq.engine.api class. This will be automatically documented by Swagger if the existing Spring annotation pattern is maintained.

You will now have a deployable module, ready for testing.

Step three

  • Test
  • Issue pull requests to bisq-business to provide your new logic routines to the whole stack.
  • Refactor Foo to exclude classes that have been merged into bisq-business

You are now ready to provide Foo as a deployable Bisq module.

2 - A professional trader needs Bisq automation and reporting

Let us imagine a trader who has a wide portfolio of coin assets. They need to maintain 3 Bisq instances on different base markets and already have an automated trading logic routine that they have written and maintain in the fictional language called "NotJava". They have called this Bar.

Additionally, they would like to go on holiday, or business trips, and monitor their portfolio via a remote interface. If they see that Bar is not agreeing with their gut instinct, they want to be able to intervene manually.

(bisq-front is currently at proof of concept, so these steps are feasible but fictional)

Step one

  • Install bisq-front by preferred method (Docker, git pull, deployable OS package, etc)
  • Browse to http port where there is GUI setup interface
  • Select 3 Bisq nodes for the needed base markets
  • Specify if you want a desktop GUI for initial setup and funding
  • Select that you need a TOR hidden service for remote access.
  • Specify that you also want this to also be a TOR relay / exit / etc. node.
  • Select that you want a full BTC node to be installed, from which you will fund your trades
  • Select that you also want to be a "Eclaire" lightning node
  • Select any additional modules you want installed in your stack (maybe you also want to run a market info node and earn some BSQ)

Step two

  • Hit install
  • Bisq front returns with needed data, eg .onion address's, api ports for each Bisq node, etc.
  • Browse to bisq-front admin interface / additional modules and point it to Bar
  • Tell Bisq front that this is a "NotJava" module and you would like to run it with the following arguments.
  • Tell bisq-front about what input / outputs Bar uses and then map them to Bisq API endpoints from dropdowns.
  • Hit save

A happy trader is up and running.

@blabno
Copy link

blabno commented Mar 7, 2018

I agree that we should have some business objects performing actions in a stateless manner, i.e. instead of operating with stateful CreateOfferDataModel, there should be some service or manager that accepts just those 8 input params (paymentAccountId, currency, amount, price, etc.).
However, it should reside in the core module.

@blabno
Copy link

blabno commented Mar 7, 2018

As to API I think it should be just a loadable extension like in Arquillian. It works on top of Service Provider Interfaces https://docs.oracle.com/javase/tutorial/ext/basics/spi.html
JavaFX also should be loaded that way.

@blabno
Copy link

blabno commented Mar 7, 2018

I don't see much point in hiding REST API behind WebSockets. WebSockets could be some addition used to get real-time updates on asynchronous events, but most of the traffic should go directly to the API (over TOR of course).
API should be secured at least with a password (without any username) transmitted as request header (never as cookie).
Ideally API should generate auth tokens that have expire after some short amount of time (i.e. 1h). Tokens could be generated as a result of successfull signin with password.

@citkane
Copy link
Author

citkane commented Mar 7, 2018

@blabno
The architecture is that all business logic, for all Bisq modules, is in one place. This is agnostic.

Whether the javaFx GUI or the API is trying to create an offer is irrelevant. Bisq must run the same code from the same place. This works. What needs refinement is sequencing logic (which is handled in viewmodels for the gui). If the request is coming from elsewhere, it needs an io.bisq.business.actions method to say for eg.:

  • format and validate inputs
  • check if user has enough BTC
  • fund wallet and listen for network return
  • commit offer
  • close listeners

Please have a look here: https://github.com/citkane/bisq-business/tree/master/business/src/main/java/io/bisq/business/actions . We can discuss on Friday why this is already working statefully, but what we do not want to do is get tangled up in re-building logic which already exists, is tested and works for a few years already.

Let us forget about the semantic of API for this paragraph. We are looking for REST endpoints. This is provided by Spring, which is already an integral part of the overall Bisq architecture. engine provides the classpath for these, Spring takes care of the auto-discovery, and Swagger takes care of the documentation. Please take a look at how simple these become here: https://github.com/citkane/bisq-engine/tree/master/engine/src/main/java/io/bisq/engine/app/api. Spring Boot provides the optional http server, bundled into the shaded jar.

Any dev creating a Bisq module should be able to provide an API easily, out of the Bisq box, by declaring very simple REST endpoints on the bisq.io.engine.api classpath and calling business logic from io.bisq.business. We do not want to get core involved in any of this and we do not want to load any more dependencies or create any more layers.

We want to constrain any possibility of connection to Bisq to localhost only. The security model lies outside of a Bisq shaded jar. If we try to be absolute about the security model and open a Bisq module to the outside world, we are inviting a world of pain.

There is an architecture that makes things simpler, more re-useable and easier to maintain. This is what I am proposing here.

@blabno
Copy link

blabno commented Mar 7, 2018

What kind of auto-discovery is spring supposed to do?

Why constrain to localhost, this won't grant much security? It won't protect you against <img src="http://localhost:8080/bisq-api/give-me-all-your-money"/>

@citkane
Copy link
Author

citkane commented Mar 7, 2018

Spring isn't supposed to do anything, it just does it. It uses @beans, which automatically configure in the java compilation and make it possible for a dev to manage a wide range of powerful options through annotations.

For eg, we define the REST classpath here: https://github.com/citkane/bisq-engine/blob/master/engine/src/main/java/io/bisq/engine/app/SwaggerConfig.java

This is why the REST methods are so clean and simple.

<img src="http://localhost:8080/bisq-api/give-me-all-your-money"/>

is not going to give me anything unless I am sitting at a browser running on 'localhost', which is the same as having access to the GUI running on localhost, which is why wallets should be encrypted.

So, we can use the existing Bisq logic to check any API call for wallet encryption, the same as we check if TAC's have been accepted here: https://github.com/citkane/bisq-business/blob/fd8498ccf535f363cebd9677d3780ec2cc660689/business/src/main/java/io/bisq/business/Handlers.java#L47

@citkane
Copy link
Author

citkane commented Mar 7, 2018

@blabno , just to be clear, all of the above is functional. You can clone it, compile it and test it.

@cbeams
Copy link
Member

cbeams commented Apr 6, 2018

Closing due to inactivity and, per the guidance in #11, the fact that this proposal isn't really something discrete that can be approved or rejected. Nothing wrong, by the way—examples like this one help show us how we need to refine proposals to make it a manageable process for everyone.

What I liked about this proposal is the raw initiative that it took to put together. What I didn't like is that it proposed too much, and demanded too much of me to be able to form a decision about it. There were multiple new components involved, and the whole thing was overwhelming. I couldn't justify digging into it at the expense of everything else I needed to do, and I (for better or worse) assumed that because it was so broad in scope, and because it was submitted by someone who has not contributed to Bisq before, that it almost certainly would not be something I'd give a 👍 to as-is. The net effect was that I ignored this proposal. Perhaps that is the same experience others had, I don't know.

I think that successful proposals from new(er) contributors will be small and well-defined ones. The more experience, track record and reputation one has, the more it becomes reasonable to request (and actually get) other contributors' attention with more ambitious proposals like this one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants