Verify that the node is synced before trying to broadcast a transaction in TransactionsActivity, to avoid users confusion. Ideally, the app should not be connected to an out of sync node, but this is in case that still happens.
This commit is contained in:
parent
01a2bc1a53
commit
8af2042039
2 changed files with 23 additions and 11 deletions
|
@ -1,6 +1,5 @@
|
||||||
package cy.agorise.bitsybitshareswallet.fragments
|
package cy.agorise.bitsybitshareswallet.fragments
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
|
@ -10,6 +9,7 @@ import android.view.*
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
|
import androidx.collection.LongSparseArray
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProviders
|
import androidx.lifecycle.ViewModelProviders
|
||||||
|
@ -99,7 +99,7 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
private var mSelectedUserAccount: UserAccount? = null
|
private var mSelectedUserAccount: UserAccount? = null
|
||||||
|
|
||||||
// Map used to keep track of request and response id pairs
|
// Map used to keep track of request and response id pairs
|
||||||
private val responseMap = HashMap<Long, Int>()
|
private val responseMap = LongSparseArray<Int>()
|
||||||
|
|
||||||
/** Transaction being built */
|
/** Transaction being built */
|
||||||
private var transaction: Transaction? = null
|
private var transaction: Transaction? = null
|
||||||
|
@ -147,7 +147,7 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
mViewModel= ViewModelProviders.of(this).get(SendTransactionViewModel::class.java)
|
mViewModel= ViewModelProviders.of(this).get(SendTransactionViewModel::class.java)
|
||||||
|
|
||||||
mViewModel.getWIF(userId, AuthorityType.ACTIVE.ordinal).observe(this,
|
mViewModel.getWIF(userId, AuthorityType.ACTIVE.ordinal).observe(this,
|
||||||
androidx.lifecycle.Observer<String> { encryptedWIF ->
|
Observer<String> { encryptedWIF ->
|
||||||
context?.let {
|
context?.let {
|
||||||
try {
|
try {
|
||||||
wifKey = CryptoUtils.decrypt(it, encryptedWIF)
|
wifKey = CryptoUtils.decrypt(it, encryptedWIF)
|
||||||
|
@ -243,8 +243,7 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
|
|
||||||
override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) {
|
override fun handleJsonRpcResponse(response: JsonRpcResponse<*>) {
|
||||||
if (responseMap.containsKey(response.id)) {
|
if (responseMap.containsKey(response.id)) {
|
||||||
val responseType = responseMap[response.id]
|
when (responseMap[response.id]) {
|
||||||
when (responseType) {
|
|
||||||
RESPONSE_GET_ACCOUNT_BY_NAME -> handleAccountProperties(response.result)
|
RESPONSE_GET_ACCOUNT_BY_NAME -> handleAccountProperties(response.result)
|
||||||
RESPONSE_GET_DYNAMIC_GLOBAL_PROPERTIES -> handleDynamicGlobalProperties(response.result)
|
RESPONSE_GET_DYNAMIC_GLOBAL_PROPERTIES -> handleDynamicGlobalProperties(response.result)
|
||||||
RESPONSE_GET_REQUIRED_FEES -> handleRequiredFees(response.result)
|
RESPONSE_GET_REQUIRED_FEES -> handleRequiredFees(response.result)
|
||||||
|
@ -285,7 +284,17 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
* calls the next step which is [GetRequiredFees] else it shows an error */
|
* calls the next step which is [GetRequiredFees] else it shows an error */
|
||||||
private fun handleDynamicGlobalProperties(result: Any?) {
|
private fun handleDynamicGlobalProperties(result: Any?) {
|
||||||
if (result is DynamicGlobalProperties) {
|
if (result is DynamicGlobalProperties) {
|
||||||
val expirationTime = (result.time.time / 1000) + Transaction.DEFAULT_EXPIRATION_TIME
|
|
||||||
|
val now = System.currentTimeMillis() / 1000
|
||||||
|
val time = result.time.time / 1000
|
||||||
|
|
||||||
|
// Show an error if the current connected node is out of sync
|
||||||
|
if (now - time > Constants.CHECK_NODE_OUT_OF_SYNC) {
|
||||||
|
context?.toast(getString(R.string.msg__transaction_not_sent))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val expirationTime = time + Transaction.DEFAULT_EXPIRATION_TIME
|
||||||
val headBlockId = result.head_block_id
|
val headBlockId = result.head_block_id
|
||||||
val headBlockNumber = result.head_block_number
|
val headBlockNumber = result.head_block_number
|
||||||
|
|
||||||
|
@ -294,7 +303,7 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
val asset = Asset(mBalancesDetailsAdapter!!.getItem(spAsset.selectedItemPosition)!!.id)
|
val asset = Asset(mBalancesDetailsAdapter!!.getItem(spAsset.selectedItemPosition)!!.id)
|
||||||
|
|
||||||
val id = mNetworkService?.sendMessage(GetRequiredFees(transaction!!, asset), GetRequiredFees.REQUIRED_API)
|
val id = mNetworkService?.sendMessage(GetRequiredFees(transaction!!, asset), GetRequiredFees.REQUIRED_API)
|
||||||
if (id != null) responseMap[id] = RESPONSE_GET_REQUIRED_FEES
|
if (id != null) responseMap.append(id, RESPONSE_GET_REQUIRED_FEES)
|
||||||
} else {
|
} else {
|
||||||
context?.toast(getString(R.string.msg__transaction_not_sent))
|
context?.toast(getString(R.string.msg__transaction_not_sent))
|
||||||
}
|
}
|
||||||
|
@ -308,7 +317,7 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
transaction!!.setFees(result as List<AssetAmount>) // TODO find how to remove this warning
|
transaction!!.setFees(result as List<AssetAmount>) // TODO find how to remove this warning
|
||||||
|
|
||||||
val id = mNetworkService?.sendMessage(BroadcastTransaction(transaction), BroadcastTransaction.REQUIRED_API)
|
val id = mNetworkService?.sendMessage(BroadcastTransaction(transaction), BroadcastTransaction.REQUIRED_API)
|
||||||
if (id != null) responseMap[id] = RESPONSE_BROADCAST_TRANSACTION
|
if (id != null) responseMap.append(id, RESPONSE_BROADCAST_TRANSACTION)
|
||||||
} else {
|
} else {
|
||||||
context?.toast(getString(R.string.msg__transaction_not_sent))
|
context?.toast(getString(R.string.msg__transaction_not_sent))
|
||||||
}
|
}
|
||||||
|
@ -329,7 +338,7 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
|
|
||||||
/** Verifies if the user has already granted the Camera permission, if not the asks for it */
|
/** Verifies if the user has already granted the Camera permission, if not the asks for it */
|
||||||
private fun verifyCameraPermission() {
|
private fun verifyCameraPermission() {
|
||||||
if (ContextCompat.checkSelfPermission(activity!!, Manifest.permission.CAMERA)
|
if (ContextCompat.checkSelfPermission(activity!!, android.Manifest.permission.CAMERA)
|
||||||
!= PackageManager.PERMISSION_GRANTED) {
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
// Permission is not already granted
|
// Permission is not already granted
|
||||||
requestPermissions(arrayOf(android.Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION)
|
requestPermissions(arrayOf(android.Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION)
|
||||||
|
@ -442,7 +451,7 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
private fun validateAccount(accountName: String) {
|
private fun validateAccount(accountName: String) {
|
||||||
isToAccountCorrect = false
|
isToAccountCorrect = false
|
||||||
val id = mNetworkService?.sendMessage(GetAccountByName(accountName), GetAccountByName.REQUIRED_API)
|
val id = mNetworkService?.sendMessage(GetAccountByName(accountName), GetAccountByName.REQUIRED_API)
|
||||||
if (id != null) responseMap[id] = RESPONSE_GET_ACCOUNT_BY_NAME
|
if (id != null) responseMap.append(id, RESPONSE_GET_ACCOUNT_BY_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validateAmount() {
|
private fun validateAmount() {
|
||||||
|
@ -570,7 +579,7 @@ class SendTransactionFragment : ConnectedFragment(), ZXingScannerView.ResultHand
|
||||||
// Start the send transaction procedure which includes a series of calls
|
// Start the send transaction procedure which includes a series of calls
|
||||||
val id = mNetworkService?.sendMessage(GetDynamicGlobalProperties(),
|
val id = mNetworkService?.sendMessage(GetDynamicGlobalProperties(),
|
||||||
GetDynamicGlobalProperties.REQUIRED_API)
|
GetDynamicGlobalProperties.REQUIRED_API)
|
||||||
if (id != null ) responseMap[id] = RESPONSE_GET_DYNAMIC_GLOBAL_PROPERTIES
|
if (id != null ) responseMap.append(id, RESPONSE_GET_DYNAMIC_GLOBAL_PROPERTIES)
|
||||||
} else
|
} else
|
||||||
Log.d(TAG, "Network Service is not connected")
|
Log.d(TAG, "Network Service is not connected")
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,6 +122,9 @@ object Constants {
|
||||||
/** Name of the external storage folder used to save files like PDF and CSV exports and Backups **/
|
/** Name of the external storage folder used to save files like PDF and CSV exports and Backups **/
|
||||||
const val EXTERNAL_STORAGE_FOLDER = "BiTSy"
|
const val EXTERNAL_STORAGE_FOLDER = "BiTSy"
|
||||||
|
|
||||||
|
/** Constant used to check if the current connected node is out of sync */
|
||||||
|
const val CHECK_NODE_OUT_OF_SYNC = 10 // 10 seconds
|
||||||
|
|
||||||
|
|
||||||
/////////////////////// Crashlytics custom keys ///////////////////////
|
/////////////////////// Crashlytics custom keys ///////////////////////
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue