Compare commits

...

3 Commits

Author SHA1 Message Date
-
cf154e97a3 bug fixes 2024-12-28 19:03:43 +01:00
anoncontributorxmr
8625c8750f update monero 2024-12-28 13:30:55 +00:00
-
c2fa492480 use last block optimization 2024-12-28 14:17:06 +01:00
11 changed files with 53 additions and 70 deletions

View File

@ -214,8 +214,9 @@ struct MyWalletListener : Monero::WalletListener {
/**
* @brief newBlock - called when new block received
* @param height - block height
* @param last - true if the block is the last block in the batch
*/
void newBlock(uint64_t height) {
void newBlock(uint64_t height, bool last) {
std::lock_guard<std::mutex> lock(_listenerMutex);
if (jlistener == nullptr) return;
//LOGD("newBlock");
@ -224,9 +225,10 @@ struct MyWalletListener : Monero::WalletListener {
if (envStat == JNI_ERR) return;
jlong h = static_cast<jlong>(height);
jboolean l = static_cast<jboolean>(last);
jmethodID listenerClass_newBlock = jenv->GetMethodID(class_WalletListener, "newBlock",
"(J)V");
jenv->CallVoidMethod(jlistener, listenerClass_newBlock, h);
"(JZ)V");
jenv->CallVoidMethod(jlistener, listenerClass_newBlock, h, l);
detachJVM(jenv, envStat);
}

View File

@ -14,6 +14,7 @@ import android.widget.TextView
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.viewModels
import androidx.appcompat.widget.SwitchCompat
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
@ -41,6 +42,7 @@ class OnboardingActivity : WalletOpeningActivity() {
private val viewModel: OnboardingViewModel by viewModels()
private lateinit var useProxySwitch: SwitchCompat
private lateinit var walletProxyAddressEditText: EditText
private lateinit var walletNameEditText: EditText
private lateinit var walletPasswordEditText: EditText
@ -70,6 +72,7 @@ class OnboardingActivity : WalletOpeningActivity() {
moreOptionsDropdownTextView = findViewById(R.id.advanced_settings_dropdown_textview)
moreOptionsChevronImageView = findViewById(R.id.advanced_settings_chevron_imageview)
seedOffsetCheckbox = findViewById(R.id.seed_offset_checkbox)
useProxySwitch = findViewById(R.id.use_proxy_switch)
walletProxyAddressEditText = findViewById(R.id.wallet_proxy_address_edittext)
advancedOptionsLayout = findViewById(R.id.more_options_layout)
seedTypeButton = findViewById(R.id.seed_type_button)
@ -77,7 +80,7 @@ class OnboardingActivity : WalletOpeningActivity() {
val useProxy = PreferenceUtils.isUseProxy(this)
walletProxyAddressEditText.isEnabled = useProxy
useProxySwitch.isChecked = useProxy
val node = PreferenceUtils.getOrSetDefaultNode(this, DefaultNode.defaultNode())
selectNodeButton.text = getString(R.string.node_button_text, node.name)
@ -146,8 +149,13 @@ class OnboardingActivity : WalletOpeningActivity() {
moreOptionsChevronImageView.setOnClickListener { viewModel.onMoreOptionsClicked() }
useProxySwitch.setOnCheckedChangeListener { _, b ->
PreferenceUtils.setUseProxy(this, b)
viewModel.setUseProxy(b)
}
seedOffsetCheckbox.setOnCheckedChangeListener { _: CompoundButton?, b: Boolean ->
viewModel.useOffset = b
viewModel.setUseOffset(b)
}
createWalletButton.setOnClickListener {
@ -193,6 +201,7 @@ class OnboardingActivity : WalletOpeningActivity() {
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun afterTextChanged(editable: Editable) {
val text = editable.toString()
PreferenceUtils.setProxy(this@OnboardingActivity, text)
viewModel.setProxyAddress(text)
}
})
@ -250,21 +259,21 @@ class OnboardingActivity : WalletOpeningActivity() {
walletNameEditText.text.toString(),
walletSeed,
restoreHeightText,
viewModel.useOffset,
viewModel.useOffset.value ?: false,
)
}
}
}
internal class OnboardingViewModel : ViewModel() {
var useOffset = true
private val _useOffset = MutableLiveData(false)
val useOffset: LiveData<Boolean> = _useOffset
private val _showMoreOptions = MutableLiveData(false)
private val _creatingWallet = MutableLiveData(false)
private val _seedType = MutableLiveData(SeedType.POLYSEED)
private val _useProxy = MutableLiveData(false)
val useProxy: LiveData<Boolean> = _useProxy
private val _proxyAddress = MutableLiveData("")
private val _proxyPort = MutableLiveData("")
private val _passphrase = MutableLiveData("")
val passphrase: LiveData<String> = _passphrase
private val _confirmedPassphrase = MutableLiveData("")
@ -275,16 +284,15 @@ internal class OnboardingViewModel : ViewModel() {
seedType,
_useProxy,
_proxyAddress,
_proxyPort,
_passphrase,
_confirmedPassphrase,
_creatingWallet,
) { seedType, useProxy, proxyAddress, proxyPort, passphrase, confirmedPassphrase, creatingWallet ->
if (seedType == null || useProxy == null || proxyAddress == null || proxyPort == null || passphrase == null || confirmedPassphrase == null || creatingWallet == null) return@combineLiveDatas false
) { seedType, useProxy, proxyAddress, passphrase, confirmedPassphrase, creatingWallet ->
if (seedType == null || useProxy == null || proxyAddress == null || passphrase == null || confirmedPassphrase == null || creatingWallet == null) return@combineLiveDatas false
if ((passphrase.isNotEmpty() || confirmedPassphrase.isNotEmpty()) && passphrase != confirmedPassphrase) return@combineLiveDatas false
if (creatingWallet) return@combineLiveDatas false
if (seedType == SeedType.POLYSEED && (passphrase.isEmpty() || confirmedPassphrase.isEmpty())) return@combineLiveDatas false
if (useProxy && (proxyAddress.isEmpty() || proxyPort.isEmpty())) return@combineLiveDatas false
if (useProxy && proxyAddress.isEmpty()) return@combineLiveDatas false
return@combineLiveDatas true
}
@ -443,9 +451,12 @@ internal class OnboardingViewModel : ViewModel() {
)
}
fun setUseOffset(useOffset: Boolean) {
_useOffset.value = useOffset
}
fun setProxyAddress(address: String) {
_proxyAddress.value = address
val port = _proxyPort.value ?: return
}
fun setUseProxy(useProxy: Boolean) {

View File

@ -178,11 +178,11 @@ class SettingsActivity : MoneroActivity() {
if (proxySwitch.isChecked) {
Toast.makeText(this, "Activating proxy", Toast.LENGTH_SHORT).show()
walletService?.setProxy(proxyAddress)
} else if (walletService?.getProxy() != "") {
Toast.makeText(this, "Deactivating proxy", Toast.LENGTH_SHORT).show()
walletService?.setProxy("")
} else {
if (walletService?.getProxy() != "") {
Toast.makeText(this, "Deactivating proxy", Toast.LENGTH_SHORT).show()
walletService?.setProxy("")
}
Toast.makeText(this, "Proxy saved", Toast.LENGTH_SHORT).show()
}
}

View File

@ -14,7 +14,7 @@ import net.mynero.wallet.adapter.NodeSelectionAdapter.NodeSelectionAdapterListen
import net.mynero.wallet.data.Node
class NodeSelectionBottomSheetDialog(
private val nodes: List<Node>,
private var nodes: List<Node>,
private var selectedNode: Node,
private val listener: NodeSelectionDialogListener,
) : BottomSheetDialogFragment(), NodeSelectionAdapterListener {
@ -52,6 +52,11 @@ class NodeSelectionBottomSheetDialog(
}
}
fun setNodes(nodes: List<Node>) {
this.nodes = nodes
adapter.setNodes(nodes)
}
fun setSelectedNode(selectedNode: Node) {
this.selectedNode = selectedNode
adapter.setSelectedNode(selectedNode)

View File

@ -64,6 +64,7 @@ abstract class NodeSelectionDialogListenerAdapter(
}
final override fun onAddNode(self: NodeSelectionBottomSheetDialog) {
val nodeSelectionBottomSheetDialog = self
val addNodeDialog = AddNodeBottomSheetDialog(object : AddNodeBottomSheetDialog.AddNodeListener {
override fun onAddNode(self: AddNodeBottomSheetDialog, node: Node) {
if (nodes.any { it.name == node.name }) {
@ -74,6 +75,7 @@ abstract class NodeSelectionDialogListenerAdapter(
newNodes.add(node)
PreferenceUtils.setNodes(activity, newNodes).fold(
{
nodeSelectionBottomSheetDialog.setNodes(newNodes)
Timber.i("New node ${node.name} added successfully")
Toast.makeText(activity, "Node added", Toast.LENGTH_SHORT).show()
self.dismiss()

View File

@ -3,15 +3,14 @@ package net.mynero.wallet.livedata
import androidx.lifecycle.LiveData
import androidx.lifecycle.MediatorLiveData
fun <T1, T2, T3, T4, T5, T6, T7, S> combineLiveDatas(
fun <T1, T2, T3, T4, T5, T6, S> combineLiveDatas(
source1: LiveData<T1>,
source2: LiveData<T2>,
source3: LiveData<T3>,
source4: LiveData<T4>,
source5: LiveData<T5>,
source6: LiveData<T6>,
source7: LiveData<T7>,
func: (T1?, T2?, T3?, T4?, T5?, T6?, T7?) -> S?
func: (T1?, T2?, T3?, T4?, T5?, T6?) -> S?
): LiveData<S> {
val result = MediatorLiveData<S>()
result.addSource(source1) {
@ -22,7 +21,6 @@ fun <T1, T2, T3, T4, T5, T6, T7, S> combineLiveDatas(
source4.value,
source5.value,
source6.value,
source7.value,
)?.run { result.value = this }
}
@ -34,7 +32,6 @@ fun <T1, T2, T3, T4, T5, T6, T7, S> combineLiveDatas(
source4.value,
source5.value,
source6.value,
source7.value,
)?.run { result.value = this }
}
@ -46,7 +43,6 @@ fun <T1, T2, T3, T4, T5, T6, T7, S> combineLiveDatas(
source4.value,
source5.value,
source6.value,
source7.value,
)?.run { result.value = this }
}
@ -58,7 +54,6 @@ fun <T1, T2, T3, T4, T5, T6, T7, S> combineLiveDatas(
source4.value,
source5.value,
source6.value,
source7.value,
)?.run { result.value = this }
}
@ -70,7 +65,6 @@ fun <T1, T2, T3, T4, T5, T6, T7, S> combineLiveDatas(
source4.value,
source5.value,
source6.value,
source7.value,
)?.run { result.value = this }
}
@ -82,19 +76,6 @@ fun <T1, T2, T3, T4, T5, T6, T7, S> combineLiveDatas(
source4.value,
source5.value,
source6.value,
source7.value,
)?.run { result.value = this }
}
result.addSource(source7) {
func(
source1.value,
source2.value,
source3.value,
source4.value,
source5.value,
source6.value,
source7.value,
)?.run { result.value = this }
}

View File

@ -22,7 +22,6 @@ import net.mynero.wallet.util.TransactionDestination
import java.io.File
class Wallet(private val handle: Long, val info: WalletInfo, private var accountIndex: Int = 0) {
var isSynchronized = false
private var listenerHandle: Long = 0
private var pendingTransaction: PendingTransaction? = null
private var enotes: List<Enote>? = null
@ -263,10 +262,6 @@ class Wallet(private val handle: Long, val info: WalletInfo, private var account
external fun getDaemonBlockChainHeightJ(): Long
external fun getDaemonBlockChainTargetHeight(): Long
fun setSynchronized() {
isSynchronized = true
}
fun startRefresh() {
startRefreshJ()
}
@ -276,10 +271,6 @@ class Wallet(private val handle: Long, val info: WalletInfo, private var account
external fun refresh(): Boolean
external fun refreshAsync()
private external fun rescanBlockchainAsyncJ()
fun rescanBlockchainAsync() {
isSynchronized = false
rescanBlockchainAsyncJ()
}
//TODO virtual void setAutoRefreshInterval(int millis) = 0;
//TODO virtual int autoRefreshInterval() const = 0;

View File

@ -45,7 +45,7 @@ interface WalletListener {
*
* @param height - block height
*/
fun newBlock(height: Long)
fun newBlock(height: Long, last: Boolean)
/**
* updated - generic callback, called when any event (sent/received/block reveived/etc) happened with the wallet;

View File

@ -467,16 +467,16 @@ class WalletService : Service(), WalletListener, DefaultLifecycleObserver {
Timber.d("Unconfirmed money received callback")
}
override fun newBlock(height: Long) {
Timber.d("New block callback at height $height")
override fun newBlock(height: Long, last: Boolean) {
Timber.d("New block callback at height $height, is last: $last")
// Monero heights are fucked up. Wallet and blockchain heights are always +1 to real height, but this callback receives real height
daemonHeight.updateAndGet { if (it > 0 && it < (height + 1)) (height + 1) else it }
val wallet = getWalletOrThrow()
if (wallet.isSynchronized) {
if (last) {
Timber.d("Storing and updating wallet because the block is the last one of the batch")
wallet.store()
updateWallet(wallet)
}
// TODO: optimize to call this only on the last block of the batch
updateWallet(wallet)
}
override fun updated() {
@ -490,14 +490,6 @@ class WalletService : Service(), WalletListener, DefaultLifecycleObserver {
Timber.d("Fetching blockchain height")
fetchBlockchainHeight()
}
val wallet = getWalletOrThrow()
val wasSynchronized = wallet.isSynchronized
if (!wasSynchronized) {
Timber.d("Storing wallet after synchronization was completed")
wallet.isSynchronized = true
wallet.store()
}
updateWallet(wallet)
}
fun addObserver(observer: WalletServiceObserver) {

View File

@ -227,13 +227,13 @@
android:layout_height="wrap_content"
android:text="@string/tor_switch_label"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@id/tor_onboarding_switch"
app:layout_constraintEnd_toStartOf="@id/tor_onboarding_switch"
app:layout_constraintBottom_toBottomOf="@id/use_proxy_switch"
app:layout_constraintEnd_toStartOf="@id/use_proxy_switch"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/tor_onboarding_switch" />
app:layout_constraintTop_toTopOf="@id/use_proxy_switch" />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/tor_onboarding_switch"
android:id="@+id/use_proxy_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="48dp"
@ -246,12 +246,11 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="@drawable/edittext_bg"
android:hint="@string/wallet_proxy_address_hint"
android:hint="@string/proxy_address_hint"
android:minHeight="48dp"
app:layout_constraintBottom_toTopOf="@id/wallet_proxy_address_edittext"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tor_onboarding_switch" />
app:layout_constraintTop_toBottomOf="@id/use_proxy_switch" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

@ -1 +1 @@
Subproject commit 64b54a40b94075bf7bff9aea8a9105598afed84a
Subproject commit 6e83819921a3c14094fc70c74361a8c026450d38