-
Notifications
You must be signed in to change notification settings - Fork 114
Architecture
MultiBit HD is designed in a series of well defined layers following the n-tier architecture pattern (view, services, persistence). These are arranged as a Maven reactor with the following modules:
-
core
- containing all services and access to the Bitcoin network -
brit
- containing the BRIT support code to enable distributed payments to be taken securely -
swing
- containing all the user interface elements -
install
- containing all the code required to build the JWrapper installer
There are many unit, integration and functional tests within each of these modules. We have approached MultiBit HD using Test Driven Development (TDD) from the Extreme Programming (XP) agile methodology.
Each module follows a deterministic build approach so that we are in a position to certify the hashes of each build artifact before it enters the code signing stage. At present this is restricted to the creation of the JARs but once we have finalised the builds environment we will issue details on how to replicate our build process precisely.
Each module is described in more detail below. As always with constantly moving software it is strongly advisable to work back from the code itself since documentation will always be lagging.
Core provides the basis for the entire wallet and is strongly linked to the bitcoinj library. Core adds to bitcoinj by providing wallet-specific services and events at a higher level such as persistence for contacts, payment information, history and so on.
We use Google's Protocol Buffers for all our serialisation requirements because we find that it is more robust than the standard Java approach. All the serialised data is AES256 encrypted before it leaves the application.
BRIT is a deceptively simple distributed micropayment collection facility suitable for a wide range of applications. Since the client code is independent of a Bitcoin wallet (it only needs cryptographic primitives) it has been placed into its own module to allow for easier re-use by third parties.
Core relies on BRIT so it currently remains directly within the MultiBit HD project but it is likely that it will be separated out when the artifacts are pushed to Maven Central or similar repository.
For more information on BRIT you should explore the BRIT Server project.
After much deliberation we settled on the use of Swing for our user interface.
There is a vast amount of support for Swing. The code is near bullet-proof for most use cases and it fully supports internationalization which is a key requirement for MultiBit HD. Also, many of the supporting libraries for Swing pre-date 2009 making it much harder for dependency chain attacks to take place.
With some effort Swing can be made to look quite modern. In Java 7 the Nimbus look and feel became integrated with the JDK. It provides a modern 2D rendered UI that is the same across all platforms. It is highly customisable through simple themes and provides consistent painting behaviour across platforms. For example to paint a button red in Swing using the Mac-only Aqua theme requires complex custom ButtonUI code. Using Nimbus ensures that we don't have this or similar problems and ensures that the themes can be consistently applied.
Swing also allows us to smoothly integrate with the native platform which puts it ahead of JavaFX until at least Q4 2014 and is essential for Bitcoin URI (see BIP 21) support in the platform
package.
The Swing module contains by far the most code but it all follows relatively straightforward patterns. All components (button, labels etc) are provided through dedicated factories (Buttons
, Labels
) and so on. This approach ensures that multiple languages and Java Accessibility can be integrated much more easily following the DRY and KISS principles. Many custom components have been created and these are all available in the views/components
package.
The standard Model View Controller (MVC) model is used to describe the main screens and a custom multi-panel dialog (Wizard) is used for all interactions. The "click button to get a wizard" approach was chosen as it received the best results in our user testing in terms of helping people to achieve their goals quickly without dedicated training. Remember MultiBit HD is intended for a worldwide mainstream audience.
All Swing layouts are handled by the MiG Layout library which offers a comprehensive solution to the problem of intuitive presentation of components in a flexible manner.
MultiBit HD uses Font Awesome for common iconography. These are applied to Swing components using the Decorator pattern using AwesomeDecorator
.
In order to provide regression testing we use the FEST test library. This allows the entire MultiBit HD user interface to be tested automatically in a variety of languages and under different conditions. It is arranged as "requirements" and "use cases" so that user interface code can be re-used in different ways as part of larger requirements.
We strongly urge any new developers to run up MultiBitHDFestTest
(it presents itself as a JUnit test) to get an idea of what MultiBit HD can do.
Providing a consistent and pleasing user experience during the installation process is crucial and the JWrapper project delivers in this respect. Many OS vendors are moving away from providing a JVM by default which in many cases forces the user to visit a third party website to obtain a suitable JVM for their platform. This can lead to an unpleasant and inconsistent result and as such we have moved to integrate standard JVMs as part of our installer.
This approach ensures that once MultiBit HD is verified through a digital signature and installed then further installations can occur safely without the user having to do much more than provide a manual confirmation on an alert. This greatly increases the likelihood of an authentic update taking place and thus improves the overall security for the user.
Much of the installer code is held outside of version control. This is because the JVMs are huge and the JWrapper JAR is around 20Mb. As a result developers interested in producing their own installers should refer to the instructions in the Installer module README to get set up.