Skip to content

Commit 1d91227

Browse files
authored
Merge pull request #916 from soramitsu/feature/runtime_logic_upgrade
Runtime 9420 upgrades:
2 parents 033f6ca + 79ba9df commit 1d91227

File tree

6 files changed

+110
-39
lines changed

6 files changed

+110
-39
lines changed

feature-wallet-api/src/main/java/jp/co/soramitsu/wallet/api/data/cache/AssetCacheExt.kt

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
package jp.co.soramitsu.wallet.api.data.cache
22

3+
import java.math.BigInteger
4+
import jp.co.soramitsu.common.data.network.runtime.binding.AccountData
35
import jp.co.soramitsu.common.data.network.runtime.binding.AccountInfo
46
import jp.co.soramitsu.common.data.network.runtime.binding.EqAccountInfo
57
import jp.co.soramitsu.common.data.network.runtime.binding.OrmlTokensAccountData
68
import jp.co.soramitsu.common.data.network.runtime.binding.bindAccountInfo
79
import jp.co.soramitsu.common.data.network.runtime.binding.bindEquilibriumAccountInfo
10+
import jp.co.soramitsu.common.data.network.runtime.binding.bindNonce
811
import jp.co.soramitsu.common.data.network.runtime.binding.bindOrmlTokensAccountData
12+
import jp.co.soramitsu.common.data.network.runtime.binding.cast
13+
import jp.co.soramitsu.common.utils.orZero
14+
import jp.co.soramitsu.common.utils.system
915
import jp.co.soramitsu.core.models.Asset
16+
import jp.co.soramitsu.core.rpc.storage.returnType
1017
import jp.co.soramitsu.coredb.model.AssetLocal
1118
import jp.co.soramitsu.shared_utils.runtime.AccountId
1219
import jp.co.soramitsu.shared_utils.runtime.RuntimeSnapshot
20+
import jp.co.soramitsu.shared_utils.runtime.definitions.types.composite.Struct
21+
import jp.co.soramitsu.shared_utils.runtime.definitions.types.fromHexOrNull
22+
import jp.co.soramitsu.shared_utils.runtime.metadata.storage
1323

1424
suspend fun AssetCache.updateAsset(
1525
metaId: Long,
@@ -35,13 +45,32 @@ private fun accountInfoUpdater(accountInfo: AccountInfo) = { asset: AssetLocal -
3545
)
3646
}
3747

48+
fun bind9420AccountInfo(hex: String?, runtime: RuntimeSnapshot): AccountInfo {
49+
hex ?: return AccountInfo.empty()
50+
val type = runtime.metadata.system().storage("Account").returnType()
51+
52+
val dynamicInstance = type.fromHexOrNull(runtime, hex).cast<Struct.Instance>()
53+
val dataInstance: Struct.Instance? = dynamicInstance["data"]
54+
val data = AccountData(
55+
free = (dataInstance?.get("free") as? BigInteger).orZero(),
56+
reserved = (dataInstance?.get("reserved") as? BigInteger).orZero(),
57+
miscFrozen = (dataInstance?.get("frozen") as? BigInteger).orZero(),
58+
feeFrozen = (dataInstance?.get("feeFrozen") as? BigInteger).orZero()
59+
)
60+
return AccountInfo(
61+
nonce = bindNonce(dynamicInstance["nonce"]),
62+
data = data
63+
)
64+
}
65+
3866
fun bindAccountInfoOrDefault(hex: String?, runtime: RuntimeSnapshot): AccountInfo {
3967
return hex?.let { bindAccountInfo(it, runtime) } ?: AccountInfo.empty()
4068
}
4169

4270
fun bindOrmlTokensAccountDataOrDefault(hex: String?, runtime: RuntimeSnapshot): OrmlTokensAccountData {
4371
return hex?.let { bindOrmlTokensAccountData(it, runtime) } ?: OrmlTokensAccountData.empty()
4472
}
73+
4574
fun bindEquilibriumAccountData(hex: String?, runtime: RuntimeSnapshot): EqAccountInfo? {
4675
return hex?.let { bindEquilibriumAccountInfo(it, runtime) }
4776
}

feature-wallet-api/src/main/java/jp/co/soramitsu/wallet/impl/domain/model/Asset.kt

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package jp.co.soramitsu.wallet.impl.domain.model
22

3+
import java.math.BigDecimal
34
import jp.co.soramitsu.account.api.domain.model.MetaAccount
45
import jp.co.soramitsu.common.model.AssetKey
56
import jp.co.soramitsu.common.utils.orZero
@@ -72,12 +73,12 @@ data class Asset(
7273
)
7374
}
7475

75-
val free = token.amountFromPlanks(freeInPlanks.orZero())
76+
private val free = token.amountFromPlanks(freeInPlanks.orZero())
7677
val reserved = token.amountFromPlanks(reservedInPlanks.orZero())
77-
val miscFrozen = token.amountFromPlanks(miscFrozenInPlanks.orZero())
78-
val feeFrozen = token.amountFromPlanks(feeFrozenInPlanks.orZero())
78+
private val miscFrozen = token.amountFromPlanks(miscFrozenInPlanks.orZero())
79+
private val feeFrozen = token.amountFromPlanks(feeFrozenInPlanks.orZero())
7980

80-
val locked = miscFrozen.max(feeFrozen)
81+
val locked: BigDecimal = miscFrozen.max(feeFrozen)
8182
val frozen = locked + reserved
8283

8384
val total = calculateTotalBalance(freeInPlanks, reservedInPlanks)?.let { token.amountFromPlanks(it) }

feature-wallet-impl/src/main/java/jp/co/soramitsu/wallet/impl/data/network/blockchain/SubstrateRemoteSource.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package jp.co.soramitsu.wallet.impl.data.network.blockchain
22

3+
import java.math.BigInteger
34
import jp.co.soramitsu.common.data.network.runtime.binding.EqAccountInfo
45
import jp.co.soramitsu.common.data.network.runtime.binding.EqOraclePricePoint
56
import jp.co.soramitsu.common.data.network.runtime.binding.ExtrinsicStatusEvent
@@ -10,7 +11,6 @@ import jp.co.soramitsu.shared_utils.runtime.AccountId
1011
import jp.co.soramitsu.shared_utils.runtime.extrinsic.ExtrinsicBuilder
1112
import jp.co.soramitsu.wallet.impl.data.network.blockchain.bindings.TransferExtrinsic
1213
import jp.co.soramitsu.wallet.impl.domain.model.Transfer
13-
import java.math.BigInteger
1414

1515
class TransferExtrinsicWithStatus(
1616
val extrinsic: TransferExtrinsic,
@@ -25,7 +25,8 @@ interface SubstrateRemoteSource {
2525
chain: Chain,
2626
transfer: Transfer,
2727
additional: (suspend ExtrinsicBuilder.() -> Unit)?,
28-
batchAll: Boolean
28+
batchAll: Boolean,
29+
allowDeath: Boolean = false
2930
): BigInteger
3031

3132
suspend fun performTransfer(
@@ -34,7 +35,8 @@ interface SubstrateRemoteSource {
3435
transfer: Transfer,
3536
tip: BigInteger?,
3637
additional: (suspend ExtrinsicBuilder.() -> Unit)?,
37-
batchAll: Boolean
38+
batchAll: Boolean,
39+
allowDeath: Boolean = false
3840
): String
3941

4042
suspend fun fetchAccountTransfersInBlock(

feature-wallet-impl/src/main/java/jp/co/soramitsu/wallet/impl/data/network/blockchain/WssSubstrateSource.kt

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
package jp.co.soramitsu.wallet.impl.data.network.blockchain
44

5+
import java.math.BigInteger
56
import jp.co.soramitsu.common.data.network.runtime.binding.AccountInfo
67
import jp.co.soramitsu.common.data.network.runtime.binding.EqAccountInfo
78
import jp.co.soramitsu.common.data.network.runtime.binding.EqOraclePricePoint
@@ -42,7 +43,6 @@ import jp.co.soramitsu.wallet.api.data.cache.bindOrmlTokensAccountDataOrDefault
4243
import jp.co.soramitsu.wallet.impl.data.network.blockchain.bindings.bindTransferExtrinsic
4344
import jp.co.soramitsu.wallet.impl.data.repository.totalBalance
4445
import jp.co.soramitsu.wallet.impl.domain.model.Transfer
45-
import java.math.BigInteger
4646

4747
class WssSubstrateSource(
4848
private val rpcCalls: RpcCalls,
@@ -151,13 +151,14 @@ class WssSubstrateSource(
151151
chain: Chain,
152152
transfer: Transfer,
153153
additional: (suspend ExtrinsicBuilder.() -> Unit)?,
154-
batchAll: Boolean
154+
batchAll: Boolean,
155+
allowDeath: Boolean
155156
): BigInteger {
156157
return extrinsicService.estimateFee(
157158
chain = chain,
158159
useBatchAll = batchAll,
159160
formExtrinsic = {
160-
transfer(chain, transfer, this.runtime.typeRegistry)
161+
transfer(chain, transfer, this.runtime.typeRegistry, allowDeath)
161162
additional?.invoke(this)
162163
}
163164
)
@@ -169,15 +170,16 @@ class WssSubstrateSource(
169170
transfer: Transfer,
170171
tip: BigInteger?,
171172
additional: (suspend ExtrinsicBuilder.() -> Unit)?,
172-
batchAll: Boolean
173+
batchAll: Boolean,
174+
allowDeath: Boolean
173175
): String {
174176
return extrinsicService.submitExtrinsic(
175177
chain = chain,
176178
accountId = accountId,
177179
useBatchAll = batchAll,
178180
tip = tip,
179181
formExtrinsic = {
180-
transfer(chain, transfer, this.runtime.typeRegistry)
182+
transfer(chain, transfer, this.runtime.typeRegistry, allowDeath)
181183
additional?.invoke(this)
182184
}
183185
).getOrThrow()
@@ -226,30 +228,35 @@ class WssSubstrateSource(
226228
}.filterNotNull()
227229
}
228230

229-
private fun ExtrinsicBuilder.transfer(chain: Chain, transfer: Transfer, typeRegistry: TypeRegistry): ExtrinsicBuilder {
231+
private fun ExtrinsicBuilder.transfer(chain: Chain, transfer: Transfer, typeRegistry: TypeRegistry, allowDeath: Boolean): ExtrinsicBuilder {
230232
val accountId = chain.accountIdOf(transfer.recipient)
231-
return if (transfer.chainAsset.currency == null) {
232-
defaultTransfer(accountId, transfer, typeRegistry)
233-
} else {
234-
when (transfer.chainAsset.typeExtra) {
235-
null, ChainAssetType.Normal -> defaultTransfer(accountId, transfer, typeRegistry)
236-
ChainAssetType.OrmlChain -> ormlChainTransfer(accountId, transfer)
237-
238-
ChainAssetType.SoraAsset,
239-
ChainAssetType.SoraUtilityAsset -> soraAssetTransfer(accountId, transfer)
240-
241-
ChainAssetType.OrmlAsset,
242-
ChainAssetType.ForeignAsset,
243-
ChainAssetType.StableAssetPoolToken,
244-
ChainAssetType.LiquidCrowdloan,
245-
ChainAssetType.VToken,
246-
ChainAssetType.VSToken,
247-
ChainAssetType.Stable -> ormlAssetTransfer(accountId, transfer)
248-
249-
ChainAssetType.Equilibrium -> equilibriumAssetTransfer(accountId, transfer)
250-
ChainAssetType.Unknown -> error("Token ${transfer.chainAsset.symbolToShow} not supported, chain ${chain.name}")
233+
val useDefaultTransfer =
234+
transfer.chainAsset.currency == null || transfer.chainAsset.typeExtra == null || transfer.chainAsset.typeExtra == ChainAssetType.Normal
235+
if (useDefaultTransfer) {
236+
return if (allowDeath) {
237+
defaultTransferAllowDeath(accountId, transfer, typeRegistry)
238+
} else {
239+
defaultTransfer(accountId, transfer, typeRegistry)
251240
}
252241
}
242+
return when (transfer.chainAsset.typeExtra) {
243+
ChainAssetType.OrmlChain -> ormlChainTransfer(accountId, transfer)
244+
245+
ChainAssetType.SoraAsset,
246+
ChainAssetType.SoraUtilityAsset -> soraAssetTransfer(accountId, transfer)
247+
248+
ChainAssetType.OrmlAsset,
249+
ChainAssetType.ForeignAsset,
250+
ChainAssetType.StableAssetPoolToken,
251+
ChainAssetType.LiquidCrowdloan,
252+
ChainAssetType.VToken,
253+
ChainAssetType.VSToken,
254+
ChainAssetType.Stable -> ormlAssetTransfer(accountId, transfer)
255+
256+
ChainAssetType.Equilibrium -> equilibriumAssetTransfer(accountId, transfer)
257+
ChainAssetType.Unknown -> error("Token ${transfer.chainAsset.symbolToShow} not supported, chain ${chain.name}")
258+
else -> error("Token ${transfer.chainAsset.symbolToShow} not supported, chain ${chain.name}")
259+
}
253260
}
254261

255262
private fun ExtrinsicBuilder.equilibriumAssetTransfer(
@@ -326,4 +333,27 @@ class WssSubstrateSource(
326333
)
327334
)
328335
}
336+
337+
private fun ExtrinsicBuilder.defaultTransferAllowDeath(
338+
accountId: AccountId,
339+
transfer: Transfer,
340+
typeRegistry: TypeRegistry
341+
): ExtrinsicBuilder {
342+
@Suppress("IMPLICIT_CAST_TO_ANY")
343+
val dest = when (typeRegistry["Address"]) { // this logic was added to support Moonbeam/Moonriver chains; todo separate assets in json like orml
344+
is FixedByteArray -> accountId
345+
else -> DictEnum.Entry(
346+
name = "Id",
347+
value = accountId
348+
)
349+
}
350+
return call(
351+
moduleName = Modules.BALANCES,
352+
callName = "transfer_allow_death",
353+
arguments = mapOf(
354+
"dest" to dest,
355+
"value" to transfer.amountInPlanks
356+
)
357+
)
358+
}
329359
}

feature-wallet-impl/src/main/java/jp/co/soramitsu/wallet/impl/data/network/blockchain/updaters/PaymentUpdater.kt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ import jp.co.soramitsu.coredb.model.OperationLocal
2222
import jp.co.soramitsu.runtime.ext.addressOf
2323
import jp.co.soramitsu.runtime.multiNetwork.ChainRegistry
2424
import jp.co.soramitsu.runtime.multiNetwork.chain.model.Chain
25-
import jp.co.soramitsu.runtime.multiNetwork.getRuntime
2625
import jp.co.soramitsu.shared_utils.runtime.AccountId
2726
import jp.co.soramitsu.shared_utils.runtime.RuntimeSnapshot
2827
import jp.co.soramitsu.shared_utils.runtime.metadata.storage
2928
import jp.co.soramitsu.shared_utils.runtime.metadata.storageKey
3029
import jp.co.soramitsu.wallet.api.data.cache.AssetCache
30+
import jp.co.soramitsu.wallet.api.data.cache.bind9420AccountInfo
3131
import jp.co.soramitsu.wallet.api.data.cache.bindAccountInfoOrDefault
3232
import jp.co.soramitsu.wallet.api.data.cache.bindEquilibriumAccountData
3333
import jp.co.soramitsu.wallet.api.data.cache.bindOrmlTokensAccountDataOrDefault
@@ -128,7 +128,12 @@ class PaymentUpdater(
128128
when (asset.typeExtra) {
129129
null, ChainAssetType.Normal,
130130
ChainAssetType.SoraUtilityAsset -> {
131-
val newAccountInfo = bindAccountInfoOrDefault(change.value, runtime)
131+
val runtimeVersion = chainRegistry.getRemoteRuntimeVersion(chain.id) ?: 0
132+
val newAccountInfo = if (runtimeVersion >= 9420) {
133+
bind9420AccountInfo(change.value, runtime)
134+
} else {
135+
bindAccountInfoOrDefault(change.value, runtime)
136+
}
132137
assetCache.updateAsset(metaId, accountId, asset, newAccountInfo)
133138
}
134139

feature-wallet-impl/src/main/java/jp/co/soramitsu/wallet/impl/data/repository/WalletRepositoryImpl.kt

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package jp.co.soramitsu.wallet.impl.data.repository
22

33
import com.opencsv.CSVReaderHeaderAware
4+
import java.math.BigDecimal
5+
import java.math.BigInteger
46
import jp.co.soramitsu.account.api.domain.model.MetaAccount
57
import jp.co.soramitsu.account.api.domain.model.accountId
68
import jp.co.soramitsu.common.compose.component.NetworkIssueItemState
@@ -50,8 +52,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
5052
import kotlinx.coroutines.flow.first
5153
import kotlinx.coroutines.flow.mapNotNull
5254
import kotlinx.coroutines.withContext
53-
import java.math.BigDecimal
54-
import java.math.BigInteger
5555
import jp.co.soramitsu.core.models.Asset as CoreAsset
5656

5757
class WalletRepositoryImpl(
@@ -235,7 +235,9 @@ class WalletRepositoryImpl(
235235
additional: (suspend ExtrinsicBuilder.() -> Unit)?,
236236
batchAll: Boolean
237237
): Fee {
238-
val fee = substrateSource.getTransferFee(chain, transfer, additional, batchAll)
238+
val runtimeVersion = chainRegistry.getRemoteRuntimeVersion(chain.id) ?: 0
239+
val allowDeath = runtimeVersion >= 9420
240+
val fee = substrateSource.getTransferFee(chain, transfer, additional, batchAll, allowDeath)
239241

240242
return Fee(
241243
transferAmount = transfer.amount,
@@ -252,7 +254,9 @@ class WalletRepositoryImpl(
252254
additional: (suspend ExtrinsicBuilder.() -> Unit)?,
253255
batchAll: Boolean
254256
): String {
255-
val operationHash = substrateSource.performTransfer(accountId, chain, transfer, tip, additional, batchAll)
257+
val runtimeVersion = chainRegistry.getRemoteRuntimeVersion(chain.id) ?: 0
258+
val allowDeath = runtimeVersion >= 9420
259+
val operationHash = substrateSource.performTransfer(accountId, chain, transfer, tip, additional, batchAll, allowDeath)
256260
val accountAddress = chain.addressOf(accountId)
257261

258262
val operation = createOperation(

0 commit comments

Comments
 (0)