diff --git a/app/src/awallet/java/com/alphawallet/app/repository/EthereumNetworkRepository.java b/app/src/awallet/java/com/alphawallet/app/repository/EthereumNetworkRepository.java index 1c19e72c9..62f614268 100644 --- a/app/src/awallet/java/com/alphawallet/app/repository/EthereumNetworkRepository.java +++ b/app/src/awallet/java/com/alphawallet/app/repository/EthereumNetworkRepository.java @@ -8,7 +8,17 @@ import com.alphawallet.app.entity.ContractLocator; import com.alphawallet.app.entity.NetworkInfo; import com.alphawallet.app.service.TickerServiceInterface; -import java.util.*; +import org.web3j.protocol.Web3j; +import org.web3j.protocol.core.methods.response.EthBlockNumber; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import io.reactivex.Single; +import io.reactivex.schedulers.Schedulers; public class EthereumNetworkRepository extends EthereumNetworkBase { @@ -18,6 +28,44 @@ public class EthereumNetworkRepository extends EthereumNetworkBase { super(preferenceRepository, tickerService, new NetworkInfo[0], true); context = ctx; + + //test main-net node see if we need to switch to backup. + fetchLatestBlockNumber() + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.io()) + .subscribe(this::gotBlock, this::onBlockError) + .isDisposed(); + } + + private void gotBlock(BigInteger blockNumber) + { + if (blockNumber.equals(BigInteger.ZERO)) //return of block zero signifies an error + { + useBackupNode = true; + } + } + + private void onBlockError(Throwable throwable) + { + //no connection, use backup + useBackupNode = true; + } + + private Single fetchLatestBlockNumber() + { + return Single.fromCallable(() -> { + try + { + Web3j web3j = TokenRepository.getWeb3jService(MAINNET_ID); + EthBlockNumber blk = web3j.ethBlockNumber() + .send(); + return blk.getBlockNumber(); + } + catch (Exception e) + { + return BigInteger.ZERO; + } + }); } public static void setChainColour(View view, int chainId) diff --git a/app/src/main/java/com/alphawallet/app/entity/tokens/Token.java b/app/src/main/java/com/alphawallet/app/entity/tokens/Token.java index f2a265f96..ea26b1369 100644 --- a/app/src/main/java/com/alphawallet/app/entity/tokens/Token.java +++ b/app/src/main/java/com/alphawallet/app/entity/tokens/Token.java @@ -138,6 +138,7 @@ public class Token implements Parcelable, Comparable nonIconifiedWebviewHeight = in.readInt(); iconifiedWebviewHeight = in.readInt(); nameWeight = in.readInt(); + ticker = in.readParcelable(TokenTicker.class.getClassLoader()); balanceChanged = false; if (readType <= ContractType.CREATION.ordinal()) @@ -209,6 +210,7 @@ public class Token implements Parcelable, Comparable dest.writeInt(nonIconifiedWebviewHeight); dest.writeInt(iconifiedWebviewHeight); dest.writeInt(nameWeight); + dest.writeParcelable(ticker, flags); } public void setRealmBalance(RealmToken realmToken) diff --git a/app/src/main/java/com/alphawallet/app/repository/EthereumNetworkBase.java b/app/src/main/java/com/alphawallet/app/repository/EthereumNetworkBase.java index a4668b136..cc79999ff 100644 --- a/app/src/main/java/com/alphawallet/app/repository/EthereumNetworkBase.java +++ b/app/src/main/java/com/alphawallet/app/repository/EthereumNetworkBase.java @@ -41,7 +41,7 @@ public abstract class EthereumNetworkBase implements EthereumNetworkRepositoryTy /* constructing URLs from BuildConfig. In the below area you will see hardcoded key like da3717... These hardcoded keys are fallbacks used by AlphaWallet forks. */ - public static final String BACKUP_INFURA_KEY = "da3717f25f824cc1baa32d812386d93f"; + public static final String BACKUP_INFURA_KEY = BuildConfig.InfuraAPI; public static final String MAINNET_FALLBACK_RPC_URL = "https://mainnet.infura.io/v3/" + BuildConfig.InfuraAPI; public static final String MAINNET_RPC_URL = !BuildConfig.AmberdataAPI.startsWith("obtain") ? "https://rpc.web3api.io?x-api-key=" + BuildConfig.AmberdataAPI : MAINNET_FALLBACK_RPC_URL; public static final String CLASSIC_RPC_URL = "https://ethereumclassic.network"; @@ -78,6 +78,7 @@ public abstract class EthereumNetworkBase implements EthereumNetworkRepositoryTy public static final String GOERLI_BLOCKSCOUT = "eth/goerli"; final Map networkMap; + protected static boolean useBackupNode = false; final NetworkInfo[] NETWORKS; static final NetworkInfo[] DEFAULT_NETWORKS = new NetworkInfo[] { @@ -316,7 +317,8 @@ public abstract class EthereumNetworkBase implements EthereumNetworkRepositoryTy switch (networkId) { case MAINNET_ID: - return MAINNET_RPC_URL; + if (useBackupNode) return MAINNET_FALLBACK_RPC_URL; + else return MAINNET_RPC_URL; case KOVAN_ID: return KOVAN_RPC_URL; case ROPSTEN_ID: @@ -477,4 +479,9 @@ public abstract class EthereumNetworkBase implements EthereumNetworkRepositoryTy { return null; } + + public boolean shouldUseBackupNode() + { + return useBackupNode; + } } diff --git a/app/src/main/java/com/alphawallet/app/repository/EthereumNetworkRepositoryType.java b/app/src/main/java/com/alphawallet/app/repository/EthereumNetworkRepositoryType.java index 33abf43d5..e1141966b 100644 --- a/app/src/main/java/com/alphawallet/app/repository/EthereumNetworkRepositoryType.java +++ b/app/src/main/java/com/alphawallet/app/repository/EthereumNetworkRepositoryType.java @@ -42,6 +42,7 @@ public interface EthereumNetworkRepositoryType { void refreshTickers(); boolean checkTickers(); + boolean shouldUseBackupNode(); List getAllKnownContracts(List networkFilters); Single getBlankOverrideTokens(Wallet wallet); diff --git a/app/src/main/java/com/alphawallet/app/repository/TokenRepository.java b/app/src/main/java/com/alphawallet/app/repository/TokenRepository.java index 523faadd5..dafbdcc16 100644 --- a/app/src/main/java/com/alphawallet/app/repository/TokenRepository.java +++ b/app/src/main/java/com/alphawallet/app/repository/TokenRepository.java @@ -91,7 +91,7 @@ public class TokenRepository implements TokenRepositoryType { private static final int CONTRACT_BALANCE_NULL = -2; private final Map web3jNodeServers; - private final AWEnsResolver ensResolver; + private AWEnsResolver ensResolver; public TokenRepository( EthereumNetworkRepositoryType ethereumNetworkRepository, @@ -105,12 +105,12 @@ public class TokenRepository implements TokenRepositoryType { this.context = context; web3jNodeServers = new ConcurrentHashMap<>(); - ensResolver = new AWEnsResolver(TokenRepository.getWeb3jService(EthereumNetworkRepository.MAINNET_ID)); } private void buildWeb3jClient(NetworkInfo networkInfo) { - HttpService publicNodeService = new HttpService(networkInfo.rpcServerUrl, okClient, false); + String rpcServerUrl = ethereumNetworkRepository.shouldUseBackupNode() ? networkInfo.backupNodeUrl : networkInfo.rpcServerUrl; + HttpService publicNodeService = new HttpService(rpcServerUrl, okClient, false); EthereumNetworkRepository.addRequiredCredentials(networkInfo.chainId, publicNodeService); web3jNodeServers.put(networkInfo.chainId, Web3j.build(publicNodeService)); } @@ -380,6 +380,7 @@ public class TokenRepository implements TokenRepositoryType { @Override public Single resolveENS(int chainId, String ensName) { + if (ensResolver == null) ensResolver = new AWEnsResolver(TokenRepository.getWeb3jService(EthereumNetworkRepository.MAINNET_ID)); return ensResolver.resolveENSAddress(ensName); } diff --git a/app/src/main/java/com/alphawallet/app/ui/ConfirmationActivity.java b/app/src/main/java/com/alphawallet/app/ui/ConfirmationActivity.java index d038a007b..61c080b8d 100644 --- a/app/src/main/java/com/alphawallet/app/ui/ConfirmationActivity.java +++ b/app/src/main/java/com/alphawallet/app/ui/ConfirmationActivity.java @@ -13,45 +13,46 @@ import android.view.View; import android.widget.Button; import android.widget.TextView; +import com.alphawallet.app.C; +import com.alphawallet.app.R; import com.alphawallet.app.entity.ConfirmationType; import com.alphawallet.app.entity.ErrorEnvelope; import com.alphawallet.app.entity.FinishReceiver; import com.alphawallet.app.entity.GasSettings; -import com.alphawallet.app.entity.PinAuthenticationCallbackInterface; import com.alphawallet.app.entity.SignAuthenticationCallback; -import com.alphawallet.app.entity.tokens.Token; import com.alphawallet.app.entity.TransactionData; import com.alphawallet.app.entity.Wallet; +import com.alphawallet.app.entity.tokens.Token; import com.alphawallet.app.repository.EthereumNetworkBase; import com.alphawallet.app.repository.EthereumNetworkRepository; -import com.alphawallet.app.util.BalanceUtils; -import com.alphawallet.app.util.Utils; -import com.alphawallet.app.web3.entity.Web3Transaction; - -import dagger.android.AndroidInjection; -import com.alphawallet.token.tools.Numeric; -import com.alphawallet.app.C; -import com.alphawallet.app.R; import com.alphawallet.app.repository.TokenRepository; import com.alphawallet.app.router.HomeRouter; +import com.alphawallet.app.util.BalanceUtils; +import com.alphawallet.app.util.Utils; import com.alphawallet.app.viewmodel.ConfirmationViewModel; import com.alphawallet.app.viewmodel.ConfirmationViewModelFactory; import com.alphawallet.app.viewmodel.GasSettingsViewModel; +import com.alphawallet.app.web3.entity.Web3Transaction; import com.alphawallet.app.widget.AWalletAlertDialog; import com.alphawallet.app.widget.SignTransactionDialog; +import com.alphawallet.token.tools.Numeric; + import org.web3j.utils.Convert; -import javax.inject.Inject; import java.math.BigDecimal; import java.math.BigInteger; -import static com.alphawallet.token.tools.Convert.getEthString; +import javax.inject.Inject; + +import dagger.android.AndroidInjection; + import static com.alphawallet.app.C.ETH_SYMBOL; import static com.alphawallet.app.C.PRUNE_ACTIVITY; import static com.alphawallet.app.entity.ConfirmationType.ETH; import static com.alphawallet.app.entity.ConfirmationType.WEB3TRANSACTION; import static com.alphawallet.app.entity.Operation.SIGN_DATA; import static com.alphawallet.app.widget.AWalletAlertDialog.ERROR; +import static com.alphawallet.token.tools.Convert.getEthString; public class ConfirmationActivity extends BaseActivity implements SignAuthenticationCallback { @@ -159,7 +160,7 @@ public class ConfirmationActivity extends BaseActivity implements SignAuthentica switch (confirmationType) { case ETH: - amountString = "-" + BalanceUtils.subunitToBase(amount.toBigInteger(), decimals).toPlainString(); + amountString = "-" + BalanceUtils.getScaledValueWithLimit(amount, decimals); symbolText.setText(symbol); transactionBytes = null; break; @@ -167,7 +168,7 @@ public class ConfirmationActivity extends BaseActivity implements SignAuthentica contractAddrText.setVisibility(View.VISIBLE); contractAddrLabel.setVisibility(View.VISIBLE); contractAddrText.setText(contractAddress); - amountString = "-" + BalanceUtils.subunitToBase(amount.toBigInteger(), decimals).toPlainString(); + amountString = "-" + BalanceUtils.getScaledValueWithLimit(amount, decimals); symbolText.setText(symbol); transactionBytes = TokenRepository.createTokenTransferData(to, amount.toBigInteger()); break; @@ -247,7 +248,7 @@ public class ConfirmationActivity extends BaseActivity implements SignAuthentica transactionBytes = viewModel.getERC721TransferBytes(to, contractAddress, amountStr, chainId); break; default: - amountString = "-" + BalanceUtils.subunitToBase(amount.toBigInteger(), decimals).toPlainString(); + amountString = "-" + BalanceUtils.getScaledValueWithLimit(amount, decimals); symbolText.setText(symbol); transactionBytes = null; break; diff --git a/app/src/main/java/com/alphawallet/app/ui/DappBrowserFragment.java b/app/src/main/java/com/alphawallet/app/ui/DappBrowserFragment.java index 83ae84357..18d7742a0 100644 --- a/app/src/main/java/com/alphawallet/app/ui/DappBrowserFragment.java +++ b/app/src/main/java/com/alphawallet/app/ui/DappBrowserFragment.java @@ -673,7 +673,7 @@ public class DappBrowserFragment extends Fragment implements OnSignTransactionLi private void setupWeb3() { web3.setActivity(getActivity()); web3.setChainId(networkInfo.chainId); - web3.setRpcUrl(networkInfo.rpcServerUrl); + web3.setRpcUrl(viewModel.shouldUseBackupNode() ? networkInfo.backupNodeUrl : networkInfo.rpcServerUrl); web3.setWalletAddress(new Address(wallet.address)); web3.setWebChromeClient(new WebChromeClient() { diff --git a/app/src/main/java/com/alphawallet/app/viewmodel/DappBrowserViewModel.java b/app/src/main/java/com/alphawallet/app/viewmodel/DappBrowserViewModel.java index b8e4d553e..a394fd7ec 100644 --- a/app/src/main/java/com/alphawallet/app/viewmodel/DappBrowserViewModel.java +++ b/app/src/main/java/com/alphawallet/app/viewmodel/DappBrowserViewModel.java @@ -327,4 +327,9 @@ public class DappBrowserViewModel extends BaseViewModel { intent.putExtra(WALLET, defaultWallet.getValue()); ctx.startActivity(intent); } + + public boolean shouldUseBackupNode() + { + return ethereumNetworkRepository.shouldUseBackupNode(); + } }