Introduce explicit wallet and useragent params in WalletFacade

Previously, WalletFacade relied on "appName" to derive all information
related to the location of the bitcoinj wallet, the prefix of that
wallet, and the useragent name that will be used for bitcoin version
messages.

Now explicit parameters have been exposed for each of these, making for
a clearer and more configurable arrangement. The values associated with
each parameter still default to the value of "appName" (usually
"Bitsquare", "Bitsquare-Alice", or similar), however the assignment of
these defaults is now done in BitsquareEnvironment#defaultProperties
PropertySource. This approach allows for overriding any or all of these
parameters in any of the property sources that have higher precedence
than the default set, (e.g. in system environment variables, the
bitsquare.properties file, etc).

As a result of these changes, WalletFacade now has no awareness whatsover
of the Bitsquare "application", which is as it should be. This change
removes a conceptual tangle, and what would have become a code-level
tangle had we tried to replace the use of @Named("appName") with a
reference to BitsquareEnvironment#APP_NAME_KEY.

This begins a series of such changes, in which references to "appName"
will be eliminated in favor of similar explicit parameters.
This commit is contained in:
Chris Beams 2014-11-11 10:29:25 +01:00
parent fd033faae3
commit 8f76a1d37b
No known key found for this signature in database
GPG key ID: 3D214F8F5BC5ED73
3 changed files with 50 additions and 20 deletions

View file

@ -18,6 +18,7 @@
package io.bitsquare.app; package io.bitsquare.app;
import io.bitsquare.BitsquareException; import io.bitsquare.BitsquareException;
import io.bitsquare.btc.WalletFacade;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
@ -69,6 +70,10 @@ public class BitsquareEnvironment extends StandardEnvironment {
private PropertySource<?> defaultProperties(String appName) { private PropertySource<?> defaultProperties(String appName) {
return new PropertiesPropertySource(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME, new Properties() {{ return new PropertiesPropertySource(BITSQUARE_DEFAULT_PROPERTY_SOURCE_NAME, new Properties() {{
setProperty(APP_NAME_KEY, appName); setProperty(APP_NAME_KEY, appName);
setProperty(WalletFacade.DIR_KEY, AppDirectory.dir(appName).toString());
setProperty(WalletFacade.PREFIX_KEY, appName);
setProperty(WalletFacade.USERAGENT_NAME_KEY, appName);
setProperty(WalletFacade.USERAGENT_VERSION_KEY, "0.1");
}}); }});
} }

View file

@ -26,8 +26,13 @@ import org.bitcoinj.params.TestNet3Params;
import com.google.inject.Injector; import com.google.inject.Injector;
import java.io.File;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import static com.google.inject.name.Names.named;
import static io.bitsquare.btc.WalletFacade.*;
public class BitcoinModule extends BitsquareModule { public class BitcoinModule extends BitsquareModule {
public static final String BITCOIN_NETWORK_KEY = "bitcoin.network"; public static final String BITCOIN_NETWORK_KEY = "bitcoin.network";
@ -39,10 +44,15 @@ public class BitcoinModule extends BitsquareModule {
@Override @Override
protected void configure() { protected void configure() {
bind(WalletFacade.class).asEagerSingleton(); File walletDir = new File(env.getRequiredProperty(WalletFacade.DIR_KEY));
bind(FeePolicy.class).asEagerSingleton(); bind(File.class).annotatedWith(named(WalletFacade.DIR_KEY)).toInstance(walletDir);
bind(BlockChainFacade.class).asEagerSingleton(); bindConstant().annotatedWith(named(WalletFacade.PREFIX_KEY)).to(env.getRequiredProperty(WalletFacade.PREFIX_KEY));
bindConstant().annotatedWith(named(USERAGENT_NAME_KEY)).to(env.getRequiredProperty(USERAGENT_NAME_KEY));
bindConstant().annotatedWith(named(USERAGENT_VERSION_KEY)).to(env.getRequiredProperty(USERAGENT_VERSION_KEY));
bind(NetworkParameters.class).toInstance(network()); bind(NetworkParameters.class).toInstance(network());
bind(FeePolicy.class).asEagerSingleton();
bind(WalletFacade.class).asEagerSingleton();
bind(BlockChainFacade.class).asEagerSingleton();
} }
@Override @Override

View file

@ -57,6 +57,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.Service; import com.google.common.util.concurrent.Service;
import java.io.File;
import java.io.Serializable; import java.io.Serializable;
import java.math.BigInteger; import java.math.BigInteger;
@ -84,8 +85,6 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import lighthouse.files.AppDirectory;
import static org.bitcoinj.script.ScriptOpCodes.OP_RETURN; import static org.bitcoinj.script.ScriptOpCodes.OP_RETURN;
/** /**
@ -94,37 +93,53 @@ import static org.bitcoinj.script.ScriptOpCodes.OP_RETURN;
*/ */
public class WalletFacade { public class WalletFacade {
private static final Logger log = LoggerFactory.getLogger(WalletFacade.class); private static final Logger log = LoggerFactory.getLogger(WalletFacade.class);
private static final String LOCK_NAME = "lock";
public static final String DIR_KEY = "wallet.dir";
public static final String PREFIX_KEY = "wallet.prefix";
public static final String USERAGENT_NAME_KEY = "bitcoin.useragent.name";
public static final String USERAGENT_VERSION_KEY = "bitcoin.useragent.version";
private final ReentrantLock lock = Threading.lock("lock");
private final NetworkParameters params;
private WalletAppKit walletAppKit;
private final FeePolicy feePolicy;
private final CryptoFacade cryptoFacade;
private final Persistence persistence;
private final String appName;
private final List<AddressConfidenceListener> addressConfidenceListeners = new CopyOnWriteArrayList<>(); private final List<AddressConfidenceListener> addressConfidenceListeners = new CopyOnWriteArrayList<>();
private final List<TxConfidenceListener> txConfidenceListeners = new CopyOnWriteArrayList<>(); private final List<TxConfidenceListener> txConfidenceListeners = new CopyOnWriteArrayList<>();
private final List<BalanceListener> balanceListeners = new CopyOnWriteArrayList<>(); private final List<BalanceListener> balanceListeners = new CopyOnWriteArrayList<>();
private final ReentrantLock lock = Threading.lock(LOCK_NAME);
private final NetworkParameters params;
private final FeePolicy feePolicy;
private final CryptoFacade cryptoFacade;
private final Persistence persistence;
private final File walletDir;
private final String walletPrefix;
private final String userAgentName;
private final String userAgentVersion;
private WalletAppKit walletAppKit;
private Wallet wallet; private Wallet wallet;
private WalletEventListener walletEventListener; private WalletEventListener walletEventListener;
private AddressEntry registrationAddressEntry; private AddressEntry registrationAddressEntry;
private AddressEntry arbitratorDepositAddressEntry; private AddressEntry arbitratorDepositAddressEntry;
private @GuardedBy(LOCK_NAME) List<AddressEntry> addressEntryList = new ArrayList<>();
@GuardedBy("lock")
private List<AddressEntry> addressEntryList = new ArrayList<>();
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor // Constructor
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@Inject @Inject
public WalletFacade(NetworkParameters params, FeePolicy feePolicy, CryptoFacade cryptoFacade, public WalletFacade(NetworkParameters params, FeePolicy feePolicy,
Persistence persistence, @Named("appName") String appName) { CryptoFacade cryptoFacade, Persistence persistence,
@Named(DIR_KEY) File walletDir,
@Named(PREFIX_KEY) String walletPrefix,
@Named(USERAGENT_NAME_KEY) String userAgentName,
@Named(USERAGENT_VERSION_KEY) String userAgentVersion) {
this.params = params; this.params = params;
this.feePolicy = feePolicy; this.feePolicy = feePolicy;
this.cryptoFacade = cryptoFacade; this.cryptoFacade = cryptoFacade;
this.persistence = persistence; this.persistence = persistence;
this.appName = appName; this.walletDir = walletDir;
this.walletPrefix = walletPrefix;
this.userAgentName = userAgentName;
this.userAgentVersion = userAgentVersion;
} }
@ -141,7 +156,7 @@ public class WalletFacade {
Threading.USER_THREAD = executor; Threading.USER_THREAD = executor;
// If seed is non-null it means we are restoring from backup. // If seed is non-null it means we are restoring from backup.
walletAppKit = new WalletAppKit(params, AppDirectory.dir(appName).toFile(), appName) { walletAppKit = new WalletAppKit(params, walletDir, walletPrefix) {
@Override @Override
protected void onSetupCompleted() { protected void onSetupCompleted() {
// Don't make the user wait for confirmations for now, as the intention is they're sending it // Don't make the user wait for confirmations for now, as the intention is they're sending it
@ -195,7 +210,7 @@ public class WalletFacade {
walletAppKit.setDownloadListener(downloadListener) walletAppKit.setDownloadListener(downloadListener)
.setBlockingStartup(false) .setBlockingStartup(false)
.setUserAgent(appName, "0.1"); .setUserAgent(userAgentName, userAgentVersion);
/* /*
// TODO restore from DeterministicSeed // TODO restore from DeterministicSeed