From 721370eb39b95e045491c23bb04bc5f8be0ae9a7 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Wed, 13 Mar 2024 11:46:35 -0700 Subject: [PATCH] fix(dashpay): hide all entrypoints to dashpay related features (#1255) --- .../org/dash/wallet/common/Configuration.java | 4 ++ .../src/de/schildbach/wallet/Constants.java | 1 + .../schildbach/wallet/WalletApplication.java | 2 +- .../wallet/service/CoinJoinService.kt | 62 ++++++++++++------- .../service/platform/PlatformSyncService.kt | 6 ++ .../schildbach/wallet/ui/SettingsActivity.kt | 8 +++ .../wallet/ui/main/MainViewModel.kt | 15 +++-- .../wallet/ui/main/WalletActivityExt.kt | 4 ++ .../wallet/ui/main/WalletFragment.kt | 8 +++ .../schildbach/wallet/ui/more/MoreFragment.kt | 5 ++ .../de/schildbach/wallet/util/TimeUtils.kt | 12 ++-- 11 files changed, 90 insertions(+), 37 deletions(-) diff --git a/common/src/main/java/org/dash/wallet/common/Configuration.java b/common/src/main/java/org/dash/wallet/common/Configuration.java index 14f21b1eda..8d43b21c45 100644 --- a/common/src/main/java/org/dash/wallet/common/Configuration.java +++ b/common/src/main/java/org/dash/wallet/common/Configuration.java @@ -233,6 +233,10 @@ public boolean getRemindBackupSeed() { return prefs.getBoolean(PREFS_KEY_REMIND_BACKUP_SEED, true); } + public void setLastRestoreTime() { + prefs.edit().putLong(PREFS_KEY_LAST_RESTORE, System.currentTimeMillis()); + } + public long getLastRestoreTime() { return prefs.getLong(PREFS_KEY_LAST_RESTORE, 0); } diff --git a/wallet/src/de/schildbach/wallet/Constants.java b/wallet/src/de/schildbach/wallet/Constants.java index a1ddb2619b..a7c22c15c8 100644 --- a/wallet/src/de/schildbach/wallet/Constants.java +++ b/wallet/src/de/schildbach/wallet/Constants.java @@ -128,6 +128,7 @@ public final class Constants { /** Bitcoinj global context. */ public static final Context CONTEXT = new Context(NETWORK_PARAMETERS); + public static final boolean DASHPAY_DISABLED = true; public final static class Files { diff --git a/wallet/src/de/schildbach/wallet/WalletApplication.java b/wallet/src/de/schildbach/wallet/WalletApplication.java index a11c05cd49..3321464106 100644 --- a/wallet/src/de/schildbach/wallet/WalletApplication.java +++ b/wallet/src/de/schildbach/wallet/WalletApplication.java @@ -824,7 +824,7 @@ public void resetBlockchainState() { public void resetBlockchain() { // reset the extensions - if (wallet.getKeyChainExtensions().containsKey(AuthenticationGroupExtension.EXTENSION_ID)) { + if (wallet != null && wallet.getKeyChainExtensions().containsKey(AuthenticationGroupExtension.EXTENSION_ID)) { AuthenticationGroupExtension authenticationGroupExtension = (AuthenticationGroupExtension) wallet.getKeyChainExtensions().get(AuthenticationGroupExtension.EXTENSION_ID); authenticationGroupExtension.reset(); } diff --git a/wallet/src/de/schildbach/wallet/service/CoinJoinService.kt b/wallet/src/de/schildbach/wallet/service/CoinJoinService.kt index 34ed887c8d..f3e825795a 100644 --- a/wallet/src/de/schildbach/wallet/service/CoinJoinService.kt +++ b/wallet/src/de/schildbach/wallet/service/CoinJoinService.kt @@ -67,6 +67,7 @@ import org.bitcoinj.wallet.WalletEx import org.bouncycastle.crypto.params.KeyParameter import org.dash.wallet.common.WalletDataProvider import org.dash.wallet.common.data.NetworkStatus +import org.dash.wallet.common.data.entity.BlockchainState import org.dash.wallet.common.services.BlockchainStateProvider import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -156,10 +157,12 @@ class CoinJoinMixingService @Inject constructor( private val uiCoroutineScope = CoroutineScope(Dispatchers.Main) private var blockChain: AbstractBlockChain? = null + private var blockchainState: BlockchainState = BlockchainState() private val isBlockChainSet: Boolean get() = blockChain != null private var networkStatus: NetworkStatus = NetworkStatus.UNKNOWN - private var isSynced = false + + // private var isSynced = false private var hasAnonymizableBalance: Boolean = false private var timeSkew: Long = 0L private var activeSessions = 0 @@ -203,9 +206,16 @@ class CoinJoinMixingService @Inject constructor( .distinctUntilChanged() .onEach { blockChainState -> val isSynced = blockChainState.isSynced() - if (isSynced != this.isSynced) { + if (isSynced != this.blockchainState.isSynced()) { val networkStatus = blockchainStateProvider.getNetworkStatus() - updateState(config.getMode(), timeSkew, hasAnonymizableBalance, networkStatus, isSynced, blockChain) + updateState( + config.getMode(), + timeSkew, + hasAnonymizableBalance, + networkStatus, + blockChainState, + blockChain + ) } // this will trigger mixing as new blocks are mined and received tx's are confirmed if (isSynced) { @@ -250,16 +260,16 @@ class CoinJoinMixingService @Inject constructor( } suspend fun updateTimeSkewInternal(timeSkew: Long) { - updateState(config.getMode(), timeSkew, hasAnonymizableBalance, networkStatus, isSynced, blockChain) + updateState(config.getMode(), timeSkew, hasAnonymizableBalance, networkStatus, blockchainState, blockChain) } private suspend fun updateBalance(balance: Coin) { CoinJoinClientOptions.setAmount(balance) - log.info("coinjoin: total balance: ${balance.toFriendlyString()}") + // log.info("coinjoin: total balance: ${balance.toFriendlyString()}") val walletEx = walletDataProvider.wallet as WalletEx - log.info("coinjoin: mixed balance: ${walletEx.coinJoinBalance.toFriendlyString()}") + // log.info("coinjoin: mixed balance: ${walletEx.coinJoinBalance.toFriendlyString()}") val anonBalance = walletEx.getAnonymizableBalance(false, false) - log.info("coinjoin: anonymizable balance {}", anonBalance.toFriendlyString()) + // log.info("coinjoin: anonymizable balance {}", anonBalance.toFriendlyString()) val hasPartiallyMixedCoins = (walletEx.denominatedBalance - walletEx.coinJoinBalance).isGreaterThan(Coin.ZERO) val hasAnonymizableBalance = anonBalance.isGreaterThan(CoinJoin.getSmallestDenomination()) @@ -268,7 +278,7 @@ class CoinJoinMixingService @Inject constructor( } else { // if the client manager is not running, just say canDenominate is true // The first round of execution will determine if mixing can happen - log.info("coinjoin: client manager is not running, canDemoninate=true") + // log.info("coinjoin: client manager is not running, canDemoninate=true") true } @@ -279,7 +289,7 @@ class CoinJoinMixingService @Inject constructor( } log.info( - "coinjoin: mixing can occur: $hasBalanceLeftToMix = balance: (${anonBalance.isGreaterThan( + "coinjoin: can mix balance: $hasBalanceLeftToMix = balance: (${anonBalance.isGreaterThan( CoinJoin.getSmallestDenomination() )} && canDenominate: $canDenominate) || partially-mixed: $hasPartiallyMixedCoins" ) @@ -288,7 +298,7 @@ class CoinJoinMixingService @Inject constructor( getCurrentTimeSkew(), hasBalanceLeftToMix, networkStatus, - isSynced, + blockchainState, blockchainStateProvider.getBlockChain() ) } @@ -298,31 +308,31 @@ class CoinJoinMixingService @Inject constructor( timeSkew: Long, hasAnonymizableBalance: Boolean, networkStatus: NetworkStatus, - isSynced: Boolean, + blockchainState: BlockchainState, blockChain: AbstractBlockChain? ) { updateMutex.lock() - log.info( - "coinjoin-old-state: ${this.mode}, ${this.timeSkew}ms, ${this.hasAnonymizableBalance}, ${this.networkStatus}, synced: ${this.isSynced} ${blockChain != null}" - ) +// log.info( +// "coinjoin-old-state: ${this.mode}, ${this.timeSkew}ms, ${this.hasAnonymizableBalance}, ${this.networkStatus}, synced: ${this.blockchainState.isSynced()} ${blockChain != null}" +// ) try { setBlockchain(blockChain) log.info( - "coinjoin-new-state: $mode, $timeSkew ms, $hasAnonymizableBalance, $networkStatus, synced: $isSynced, ${blockChain != null}" + "coinjoin-state: $mode, $timeSkew ms, $hasAnonymizableBalance, $networkStatus, synced: ${blockchainState.isSynced()}, ${blockChain != null}" ) // log.info("coinjoin-Current timeskew: ${getCurrentTimeSkew()}") this.networkStatus = networkStatus this.hasAnonymizableBalance = hasAnonymizableBalance - this.isSynced = isSynced + this.blockchainState = blockchainState this.mode = mode this.timeSkew = timeSkew - if (mode == CoinJoinMode.NONE || !isInsideTimeSkewBounds(timeSkew)) { + if (mode == CoinJoinMode.NONE || !isInsideTimeSkewBounds(timeSkew) || blockchainState.replaying) { updateMixingState(MixingStatus.NOT_STARTED) } else { configureMixing() if (hasAnonymizableBalance) { - if (networkStatus == NetworkStatus.CONNECTED && isBlockChainSet && isSynced) { + if (networkStatus == NetworkStatus.CONNECTED && isBlockChainSet && blockchainState.isSynced()) { updateMixingState(MixingStatus.MIXING) } else { updateMixingState(MixingStatus.PAUSED) @@ -334,7 +344,6 @@ class CoinJoinMixingService @Inject constructor( updateProgress() } finally { updateMutex.unlock() - log.info("updateMutex is unlocked") } } @@ -345,7 +354,7 @@ class CoinJoinMixingService @Inject constructor( try { val previousMixingStatus = _mixingState.value _mixingState.value = mixingStatus - log.info("coinjoin-updateMixingState: $previousMixingStatus -> $mixingStatus") + log.info("coinjoin-mixing: $previousMixingStatus -> $mixingStatus") when { mixingStatus == MixingStatus.MIXING && previousMixingStatus != MixingStatus.MIXING -> { @@ -365,11 +374,11 @@ class CoinJoinMixingService @Inject constructor( } private suspend fun updateBlockChain(blockChain: AbstractBlockChain?) { - updateState(mode, timeSkew, hasAnonymizableBalance, networkStatus, isSynced, blockChain) + updateState(mode, timeSkew, hasAnonymizableBalance, networkStatus, blockchainState, blockChain) } private suspend fun updateNetworkStatus(networkStatus: NetworkStatus) { - updateState(mode, timeSkew, hasAnonymizableBalance, networkStatus, isSynced, blockChain) + updateState(mode, timeSkew, hasAnonymizableBalance, networkStatus, blockchainState, blockChain) } private suspend fun updateMode(mode: CoinJoinMode) { @@ -379,7 +388,7 @@ class CoinJoinMixingService @Inject constructor( } updateBalance(walletDataProvider.wallet!!.getBalance(Wallet.BalanceType.AVAILABLE)) val currentTimeSkew = getCurrentTimeSkew() - updateState(mode, currentTimeSkew, hasAnonymizableBalance, networkStatus, isSynced, blockChain) + updateState(mode, currentTimeSkew, hasAnonymizableBalance, networkStatus, blockchainState, blockChain) } private var mixingProgressTracker: MixingProgressTracker = object : MixingProgressTracker() { @@ -416,6 +425,9 @@ class CoinJoinMixingService @Inject constructor( override fun onTransactionProcessed(tx: Transaction?, type: CoinJoinTransactionType?, sessionId: Int) { super.onTransactionProcessed(tx, type, sessionId) log.info("coinjoin-tx {} in session {} {}", type, sessionId, tx?.txId) + coroutineScope.launch { + updateProgress() + } } } @@ -556,6 +568,7 @@ class CoinJoinMixingService @Inject constructor( val asyncStart = coroutineScope.async(Dispatchers.IO) { // though coroutineScope is on a Context propogated thread, we still need this org.bitcoinj.core.Context.propagate(walletDataProvider.wallet!!.context) + (walletDataProvider.wallet as WalletEx).coinJoin.refreshUnusedKeys() coinJoinManager?.initMasternodeGroup(blockChain) clientManager.doAutomaticDenominating() } @@ -633,7 +646,8 @@ class CoinJoinMixingService @Inject constructor( coroutineScope.launch { activeSessions = if (this@CoinJoinMixingService::clientManager.isInitialized) { clientManager.sessionsStatus?.count { poolStatus -> - poolStatus == PoolStatus.CONNECTING || poolStatus == PoolStatus.CONNECTED || poolStatus == PoolStatus.MIXING + poolStatus == PoolStatus.CONNECTING || poolStatus == PoolStatus.CONNECTED || + poolStatus == PoolStatus.MIXING } ?: 0 } else { 0 diff --git a/wallet/src/de/schildbach/wallet/service/platform/PlatformSyncService.kt b/wallet/src/de/schildbach/wallet/service/platform/PlatformSyncService.kt index d04122de63..1464386825 100644 --- a/wallet/src/de/schildbach/wallet/service/platform/PlatformSyncService.kt +++ b/wallet/src/de/schildbach/wallet/service/platform/PlatformSyncService.kt @@ -26,6 +26,7 @@ import com.google.common.base.Preconditions import com.google.common.base.Stopwatch import com.google.common.util.concurrent.SettableFuture import com.google.zxing.BarcodeFormat +import de.schildbach.wallet.Constants import de.schildbach.wallet.WalletApplication import de.schildbach.wallet.database.dao.DashPayContactRequestDao import de.schildbach.wallet.database.dao.DashPayProfileDao @@ -1020,6 +1021,7 @@ class PlatformSynchronizationService @Inject constructor( // this will enable notifications, since platform information has been synced config.set(DashPayConfig.LAST_SEEN_NOTIFICATION_TIME, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7)) } + log.info("PreBlockDownload: $preDownloadBlocksFuture") preDownloadBlocksFuture?.set(true) preDownloadBlocks.set(false) } @@ -1062,6 +1064,10 @@ class PlatformSynchronizationService @Inject constructor( lastPreBlockStage = PreBlockStage.None preDownloadBlocksFuture = future log.info("PreDownloadBlocks: starting") + if (Constants.DASHPAY_DISABLED) { + finishPreBlockDownload() + return@launch + } // first check to see if there is a blockchain identity if (blockchainIdentityDataDao.load() == null) { diff --git a/wallet/src/de/schildbach/wallet/ui/SettingsActivity.kt b/wallet/src/de/schildbach/wallet/ui/SettingsActivity.kt index 9ef3421661..ad94fef54e 100644 --- a/wallet/src/de/schildbach/wallet/ui/SettingsActivity.kt +++ b/wallet/src/de/schildbach/wallet/ui/SettingsActivity.kt @@ -28,6 +28,7 @@ import androidx.core.content.ContextCompat import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import dagger.hilt.android.AndroidEntryPoint +import de.schildbach.wallet.Constants import de.schildbach.wallet.WalletBalanceWidgetProvider import de.schildbach.wallet.service.CoinJoinMode import de.schildbach.wallet.service.MixingStatus @@ -163,11 +164,13 @@ class SettingsActivity : LockScreenActivity() { binding.coinjoinSubtitleIcon.isVisible = false binding.progressBar.isVisible = false binding.balance.isVisible = false + binding.coinjoinProgress.isVisible = false } else { if (viewModel.coinJoinMixingStatus == MixingStatus.FINISHED) { binding.coinjoinSubtitle.text = getString(R.string.coinjoin_progress_finished) binding.coinjoinSubtitleIcon.isVisible = false binding.progressBar.isVisible = false + binding.coinjoinProgress.isVisible = false } else { @StringRes val statusId = when(viewModel.coinJoinMixingStatus) { MixingStatus.NOT_STARTED -> R.string.coinjoin_not_started @@ -181,11 +184,16 @@ class SettingsActivity : LockScreenActivity() { binding.coinjoinSubtitleIcon.isVisible = true binding.progressBar.isVisible = viewModel.coinJoinMixingStatus == MixingStatus.MIXING binding.coinjoinProgress.text = getString(R.string.percent, viewModel.mixingProgress.toInt()) + binding.coinjoinProgress.isVisible = true binding.balance.isVisible = true binding.balance.text = getString(R.string.coinjoin_progress_balance, viewModel.mixedBalance, viewModel.walletBalance) } } } + + if (Constants.DASHPAY_DISABLED) { + binding.votingDashPay.isVisible = false + } } private fun setBatteryOptimizationText() { diff --git a/wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt b/wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt index c3ec9faffd..80e6e961ae 100644 --- a/wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt +++ b/wallet/src/de/schildbach/wallet/ui/main/MainViewModel.kt @@ -680,11 +680,16 @@ class MainViewModel @Inject constructor( suspend fun getInviteHistory() = invitationsDao.loadAll() private fun combineLatestData(): Boolean { - val isPlatformAvailable = isPlatformAvailableData.value ?: false - val isSynced = _isBlockchainSynced.value ?: false - val noIdentityCreatedOrInProgress = (blockchainIdentity.value == null) || blockchainIdentity.value!!.creationState == BlockchainIdentityData.CreationState.NONE - val canAffordIdentityCreation = walletData.canAffordIdentityCreation() - return isSynced && isPlatformAvailable && noIdentityCreatedOrInProgress && canAffordIdentityCreation + return if (Constants.DASHPAY_DISABLED) { + false + } else { + val isPlatformAvailable = isPlatformAvailableData.value ?: false + val isSynced = _isBlockchainSynced.value ?: false + val noIdentityCreatedOrInProgress = + (blockchainIdentity.value == null) || blockchainIdentity.value!!.creationState == BlockchainIdentityData.CreationState.NONE + val canAffordIdentityCreation = walletData.canAffordIdentityCreation() + return isSynced && isPlatformAvailable && noIdentityCreatedOrInProgress && canAffordIdentityCreation + } } private fun startContactRequestTimer() { diff --git a/wallet/src/de/schildbach/wallet/ui/main/WalletActivityExt.kt b/wallet/src/de/schildbach/wallet/ui/main/WalletActivityExt.kt index c07d683ade..4d4f5abee9 100644 --- a/wallet/src/de/schildbach/wallet/ui/main/WalletActivityExt.kt +++ b/wallet/src/de/schildbach/wallet/ui/main/WalletActivityExt.kt @@ -37,6 +37,7 @@ import androidx.navigation.fragment.NavHostFragment import androidx.navigation.ui.NavigationUI.onNavDestinationSelected import androidx.navigation.ui.NavigationUI.setupWithNavController import com.google.android.material.bottomnavigation.BottomNavigationView +import de.schildbach.wallet.Constants import de.schildbach.wallet.WalletBalanceWidgetProvider import de.schildbach.wallet.service.CoinJoinMode import de.schildbach.wallet_test.R @@ -93,6 +94,9 @@ object WalletActivityExt { navController.addOnDestinationChangedListener { _, _, arguments -> navView.isVisible = arguments?.getBoolean("ShowNavBar", false) == true } + if (Constants.DASHPAY_DISABLED) { + navView.menu.findItem(R.id.contactsFragment).isEnabled = false + } } fun MainActivity.checkTimeSkew(viewModel: MainViewModel, force: Boolean = false) { diff --git a/wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt b/wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt index 83cb069163..1fb4d78a43 100644 --- a/wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt +++ b/wallet/src/de/schildbach/wallet/ui/main/WalletFragment.kt @@ -198,6 +198,14 @@ class WalletFragment : Fragment(R.layout.home_content) { val activeSessionsText = ".".repeat(it) mixingBinding.mixingSessions.text = activeSessionsText } + + viewModel.balance.observe(viewLifecycleOwner) { + mixingBinding.balance.text = getString( + R.string.coinjoin_progress_balance, + viewModel.mixedBalance, + viewModel.walletBalance + ) + } } fun scrollToTop() { diff --git a/wallet/src/de/schildbach/wallet/ui/more/MoreFragment.kt b/wallet/src/de/schildbach/wallet/ui/more/MoreFragment.kt index c0de106fdd..090633244c 100644 --- a/wallet/src/de/schildbach/wallet/ui/more/MoreFragment.kt +++ b/wallet/src/de/schildbach/wallet/ui/more/MoreFragment.kt @@ -31,6 +31,7 @@ import androidx.navigation.NavOptions import androidx.navigation.fragment.findNavController import com.google.android.material.transition.MaterialFadeThrough import dagger.hilt.android.AndroidEntryPoint +import de.schildbach.wallet.Constants import de.schildbach.wallet.WalletApplication import de.schildbach.wallet.database.entity.DashPayProfile import de.schildbach.wallet.livedata.Status @@ -173,6 +174,10 @@ class MoreFragment : Fragment(R.layout.fragment_more) { } initViewModel() + + if (Constants.DASHPAY_DISABLED) { + binding.usernameVoting.isVisible = false + } } private fun dismissProfileError() { diff --git a/wallet/src/de/schildbach/wallet/util/TimeUtils.kt b/wallet/src/de/schildbach/wallet/util/TimeUtils.kt index 1e9cf4422c..9dff9f8d68 100644 --- a/wallet/src/de/schildbach/wallet/util/TimeUtils.kt +++ b/wallet/src/de/schildbach/wallet/util/TimeUtils.kt @@ -39,7 +39,7 @@ private fun queryNtpTime(server: String): Long? { // Convert seconds to milliseconds and adjust from 1900 to epoch (1970) return (seconds - 2208988800L) * 1000 } catch (e: Exception) { - e.printStackTrace() + // swallow } return null } @@ -58,11 +58,9 @@ suspend fun getTimeSkew(force: Boolean = false): Long { val networkTimes = arrayListOf() for (i in 0..3) { - try { - val time = queryNtpTime("pool.ntp.org") - if (time != null && time > 0) { networkTimes.add(time) } - } catch (e: SocketTimeoutException) { - // swallow + val time = queryNtpTime("pool.ntp.org") + if (time != null && time > 0) { + networkTimes.add(time) } } networkTimes.sort() @@ -96,6 +94,6 @@ suspend fun getTimeSkew(force: Boolean = false): Long { val systemTimeMillis = System.currentTimeMillis() lastTimeWhenSkewChecked = systemTimeMillis lastTimeSkew = systemTimeMillis - networkTime - log.info("timeskew: $systemTimeMillis-$networkTime = ${systemTimeMillis - networkTime}; source: $timeSource") + log.debug("timeskew: $systemTimeMillis-$networkTime = ${systemTimeMillis - networkTime}; source: $timeSource") return systemTimeMillis - networkTime }