Skip to content

Commit

Permalink
Merge pull request #208 from breadwallet/feature/CORE-523
Browse files Browse the repository at this point in the history
CORE-523: Address Concurrency Issues (#1)
  • Loading branch information
Ed Gamble authored Sep 12, 2019
2 parents dc37946 + d194e8b commit c0ceb46
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ final class NetworkDiscovery {

/* package */
interface Callback {
void update(ImmutableMultimap<String, WalletManagerMode> updatedSupportedModes,
ImmutableMap<String, WalletManagerMode> updatedDefaultModes);
void discovered(Network network);
void complete(List<com.breadwallet.crypto.Network> networks);
}
Expand All @@ -49,8 +47,6 @@ void update(ImmutableMultimap<String, WalletManagerMode> updatedSupportedModes,
static void discoverNetworks(BlockchainDb query,
boolean isMainnet,
List<com.breadwallet.crypto.blockchaindb.models.bdb.Currency> appCurrencies,
ImmutableMultimap<String, WalletManagerMode> supportedModes,
ImmutableMap<String, WalletManagerMode> defaultModes,
Callback callback) {
List<com.breadwallet.crypto.Network> networks = new ArrayList<>();

Expand All @@ -65,12 +61,13 @@ static void discoverNetworks(BlockchainDb query,
}
}

// filter the returned blockchainModels to only include supported blockchains
blockchainModels = filterBlockchains(supportedBlockchains, blockchainModels);
ImmutableMultimap<String, WalletManagerMode> updatedSupportedModes = getUpdateSupportedModes(blockchainModels, supportedModes);
ImmutableMap<String, WalletManagerMode> updatedDefaultModes = getUpdatedDefaultModes(blockchainModels, defaultModes);
blockchainModels = mergeBlockchains(supportedBlockchains, blockchainModels);

callback.update(updatedSupportedModes, updatedDefaultModes);
// merge the supported blockchainModels into the supported blockchains (deferring to blockchainModels),
// to ensure that if blockchainModels does not include a support blockchain, it is still present after
// the merge
blockchainModels = mergeBlockchains(supportedBlockchains, blockchainModels);

for (Blockchain blockchainModel : blockchainModels) {
String blockchainModelId = blockchainModel.getId();
Expand Down Expand Up @@ -207,39 +204,6 @@ private static Collection<Blockchain> mergeBlockchains(Collection<Blockchain> su
return mergedMap.values();
}

private static ImmutableMultimap<String, WalletManagerMode> getUpdateSupportedModes(Collection<Blockchain> remotes,
ImmutableMultimap<String, WalletManagerMode> supportedModes) {
ImmutableMultimap.Builder<String, WalletManagerMode> builder = new ImmutableMultimap.Builder<>();
builder.putAll(supportedModes);

for (Blockchain b: remotes) {
Collection<WalletManagerMode> modes = supportedModes.get(b.getId());
if (null == modes || modes.isEmpty()) {
builder.put(b.getId(), WalletManagerMode.API_ONLY);

} else if (!modes.contains(WalletManagerMode.API_ONLY)) {
builder.put(b.getId(), WalletManagerMode.API_ONLY);
}
}

return builder.build();
}

private static ImmutableMap<String, WalletManagerMode> getUpdatedDefaultModes(Collection<Blockchain> remotes,
ImmutableMap<String, WalletManagerMode> defaultModes) {
ImmutableMap.Builder<String, WalletManagerMode> builder = new ImmutableMap.Builder<>();
builder.putAll(defaultModes);

for (Blockchain b: remotes) {
WalletManagerMode mode = defaultModes.get(b.getId());
if (null == mode) {
builder.put(b.getId(), WalletManagerMode.API_ONLY);
}
}

return builder.build();
}

private static void getBlockChains(CountUpAndDownLatch latch,
BlockchainDb query,
boolean isMainnet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,14 +214,21 @@ final class System implements com.breadwallet.crypto.System {
///
/// Wallet Manager Modes
///

/// Every blockchain supports `API_ONLY`; blockchains with built-in P2P support (BTC, BCH,
/// and ETH) may support `P2P_ONLY`. Intermediate modes (API_WITH_P2P_SUBMIT,
/// P2P_WITH_API_SYNC) are suppored on a case-by-case basis.
/// Blockchains with built-in P2P support (BTC, BCH, and ETH) may support `.p2p_only`.
/// Intermediate modes (.api_with_p2p_submit, .p2p_with_api_sync) are suppored on a case-by-case
/// basis. API mode is supported if BRD infrastructure supports that blockchain (for example,
/// BCH is not at the moment)
///
/// It is possible that the `API_ONLY` mode does not work - for exmaple, the BDB is down. In
/// It is possible that the `.api_only` mode does not work - for exmaple, the BDB is down. In
/// that case it is an App issue to report and resolve the issue by: waiting out the outage;
/// selecting another mode if available.
///
/// These values are updated whenever the BDB support updates. However, a given WalletKit
/// distribution in the wild might be out of date with the current BDB support. That can mean
/// that some API mode is missing here that a new BDB support (like when BCH comes online) or
/// that a mode has disappeared (maybe a blockchain is dropped). These cases are not
/// destructive.
///

private static final ImmutableMultimap<String, WalletManagerMode> SUPPORTED_MODES;

Expand Down Expand Up @@ -350,8 +357,6 @@ private static Optional<System> getSystem(Pointer context) {
private final List<WalletManager> walletManagers;

boolean isNetworkReachable;
private ImmutableMultimap<String, WalletManagerMode> supportedModes;
private ImmutableMap<String, WalletManagerMode> defaultModes;

private System(ScheduledExecutorService executor,
SystemListener listener,
Expand Down Expand Up @@ -382,22 +387,13 @@ private System(ScheduledExecutorService executor,
this.walletManagers = new ArrayList<>();

this.isNetworkReachable = DEFAULT_IS_NETWORK_REACHABLE;
this.supportedModes = SUPPORTED_MODES;
this.defaultModes = DEFAULT_MODES;

announceSystemEvent(new SystemCreatedEvent());
}

@Override
public void configure(List<Currency> appCurrencies) {
NetworkDiscovery.discoverNetworks(query, isMainnet, appCurrencies, supportedModes, defaultModes, new NetworkDiscovery.Callback() {
@Override
public void update(ImmutableMultimap<String, WalletManagerMode> supportedModes,
ImmutableMap<String, WalletManagerMode> defaultModes) {
System.this.supportedModes = supportedModes;
System.this.defaultModes = defaultModes;
}

NetworkDiscovery.discoverNetworks(query, isMainnet, appCurrencies, new NetworkDiscovery.Callback() {
@Override
public void discovered(Network network) {
if (addNetwork(network)) {
Expand Down Expand Up @@ -567,12 +563,12 @@ public boolean supportsAddressScheme(com.breadwallet.crypto.Network network, Add

@Override
public WalletManagerMode getDefaultWalletManagerMode(com.breadwallet.crypto.Network network) {
return defaultModes.getOrDefault(network.getUids(), WalletManagerMode.API_ONLY);
return DEFAULT_MODES.getOrDefault(network.getUids(), WalletManagerMode.API_ONLY);
}

@Override
public List<WalletManagerMode> getSupportedWalletManagerModes(com.breadwallet.crypto.Network network) {
ImmutableCollection<WalletManagerMode> supported = supportedModes.get(network.getUids());
ImmutableCollection<WalletManagerMode> supported = SUPPORTED_MODES.get(network.getUids());
return supported.isEmpty() ? Collections.singletonList(WalletManagerMode.API_ONLY) : supported.asList();
}

Expand Down
Loading

0 comments on commit c0ceb46

Please sign in to comment.