From 977706494d21ad90ccdde07ba5a99b09c56cc970 Mon Sep 17 00:00:00 2001 From: gv-timur Date: Tue, 24 Oct 2023 11:41:14 +0300 Subject: [PATCH] feature: added new instructions to transfer domain ownerhsip and revoke permissions (#382) * feature: added new instructions to transfer domain ownerhsip and revoke permissions Signed-off-by: Timur Guskov * feature: fix instruction name and added test for domain transfer Signed-off-by: Timur Guskov --------- Signed-off-by: Timur Guskov Co-authored-by: Timur Guskov --- .../iroha2/transaction/Instructions.kt | 36 +++++++++++++++++++ .../iroha2/transaction/TransactionBuilder.kt | 11 ++++++ .../co/soramitsu/iroha2/InstructionsTest.kt | 33 +++++++++++++++++ 3 files changed, 80 insertions(+) diff --git a/modules/client/src/main/kotlin/jp/co/soramitsu/iroha2/transaction/Instructions.kt b/modules/client/src/main/kotlin/jp/co/soramitsu/iroha2/transaction/Instructions.kt index 0417ec972..91d270f6c 100644 --- a/modules/client/src/main/kotlin/jp/co/soramitsu/iroha2/transaction/Instructions.kt +++ b/modules/client/src/main/kotlin/jp/co/soramitsu/iroha2/transaction/Instructions.kt @@ -444,6 +444,18 @@ object Instructions { ), ) + /** + * Transfer domain ownership. + */ + fun transferDomainOwnership(sourceId: AccountId, value: IdBox.DomainId, destinationId: AccountId) = + InstructionBox.Transfer( + TransferBox( + sourceId = IdBox.AccountId(sourceId).evaluatesTo(), + `object` = Value.Id(value).evaluatesTo(), + destinationId = IdBox.AccountId(destinationId).evaluatesTo(), + ), + ) + /** * Evaluate one instruction if a [condition] is met and another one otherwise. */ @@ -480,6 +492,30 @@ object Instructions { } } + /** + * Revoke an account the [Permissions.CanSetKeyValueInUserAccount] permission + */ + fun revokeSetKeyValueAccount(accountId: AccountId, target: AccountId): InstructionBox { + return revokeSome(IdBox.AccountId(target)) { + PermissionToken( + definitionId = Permissions.CanSetKeyValueInUserAccount.type, + payload = accountId.asJsonString().asStringWithJson(), + ) + } + } + + /** + * Revoke an account the [Permissions.CanSetKeyValueInDomain] permission + */ + fun revokeSetKeyValueDomain(domainId: DomainId, target: AccountId): InstructionBox { + return revokeSome(IdBox.AccountId(target)) { + PermissionToken( + definitionId = Permissions.CanSetKeyValueInDomain.type, + payload = domainId.asJsonString().asStringWithJson(), + ) + } + } + /** * Revoke an account a given role. */ diff --git a/modules/client/src/main/kotlin/jp/co/soramitsu/iroha2/transaction/TransactionBuilder.kt b/modules/client/src/main/kotlin/jp/co/soramitsu/iroha2/transaction/TransactionBuilder.kt index ffa3f91c5..0de9d58cf 100644 --- a/modules/client/src/main/kotlin/jp/co/soramitsu/iroha2/transaction/TransactionBuilder.kt +++ b/modules/client/src/main/kotlin/jp/co/soramitsu/iroha2/transaction/TransactionBuilder.kt @@ -13,6 +13,7 @@ import jp.co.soramitsu.iroha2.generated.AssetValue import jp.co.soramitsu.iroha2.generated.AssetValueType import jp.co.soramitsu.iroha2.generated.DomainId import jp.co.soramitsu.iroha2.generated.Executable +import jp.co.soramitsu.iroha2.generated.IdBox import jp.co.soramitsu.iroha2.generated.InstructionBox import jp.co.soramitsu.iroha2.generated.IpfsPath import jp.co.soramitsu.iroha2.generated.Metadata @@ -393,6 +394,10 @@ class TransactionBuilder(builder: TransactionBuilder.() -> Unit = {}) { instructions.value.add(Instructions.transferAsset(sourceId, value, destinationId)) } + fun transferDomainOwnership(sourceId: AccountId, value: IdBox.DomainId, destinationId: AccountId) = this.apply { + instructions.value.add(Instructions.transferDomainOwnership(sourceId, value, destinationId)) + } + fun `if`(condition: Boolean, then: InstructionBox, otherwise: InstructionBox) = this.apply { instructions.value.add(Instructions.`if`(condition, then, otherwise)) } @@ -412,6 +417,12 @@ class TransactionBuilder(builder: TransactionBuilder.() -> Unit = {}) { fun revokeSetKeyValueAsset(assetId: AssetId, target: AccountId) = this.apply { instructions.value.add(Instructions.revokeSetKeyValueAsset(assetId, target)) } + fun revokeSetKeyValueAccount(accountId: AccountId, target: AccountId) = + this.apply { instructions.value.add(Instructions.revokeSetKeyValueAccount(accountId, target)) } + + fun revokeSetKeyValueDomain(domainId: DomainId, target: AccountId) = + this.apply { instructions.value.add(Instructions.revokeSetKeyValueDomain(domainId, target)) } + fun revokeRole( roleId: RoleId, accountId: AccountId, diff --git a/modules/client/src/test/kotlin/jp/co/soramitsu/iroha2/InstructionsTest.kt b/modules/client/src/test/kotlin/jp/co/soramitsu/iroha2/InstructionsTest.kt index 87ccefa0c..3e078af81 100644 --- a/modules/client/src/test/kotlin/jp/co/soramitsu/iroha2/InstructionsTest.kt +++ b/modules/client/src/test/kotlin/jp/co/soramitsu/iroha2/InstructionsTest.kt @@ -12,6 +12,7 @@ import jp.co.soramitsu.iroha2.generated.AssetDefinitionId import jp.co.soramitsu.iroha2.generated.AssetId import jp.co.soramitsu.iroha2.generated.AssetValue import jp.co.soramitsu.iroha2.generated.AssetValueType +import jp.co.soramitsu.iroha2.generated.IdBox import jp.co.soramitsu.iroha2.generated.Metadata import jp.co.soramitsu.iroha2.generated.Name import jp.co.soramitsu.iroha2.generated.PermissionToken @@ -35,6 +36,7 @@ import jp.co.soramitsu.iroha2.testengine.DEFAULT_ASSET_DEFINITION_ID import jp.co.soramitsu.iroha2.testengine.DEFAULT_ASSET_ID import jp.co.soramitsu.iroha2.testengine.DEFAULT_DOMAIN_ID import jp.co.soramitsu.iroha2.testengine.DefaultGenesis +import jp.co.soramitsu.iroha2.testengine.GENESIS import jp.co.soramitsu.iroha2.testengine.IROHA_CONFIG_DELIMITER import jp.co.soramitsu.iroha2.testengine.IrohaTest import jp.co.soramitsu.iroha2.testengine.NewAccountWithMetadata @@ -1020,6 +1022,37 @@ class InstructionsTest : IrohaTest() { assertEquals(27, domains.size) } + @Test + @WithIroha([DefaultGenesis::class]) + @Feature("Domains") + @Story("Account transfers domain ownership") + @SdkTestId("transfer_domain_ownership") + fun `transfer domain ownership`(): Unit = runBlocking { + val genesisAccountId = AccountId(GENESIS.asName(), GENESIS.asDomainId()) + var domain = QueryBuilder.findDomainById(DEFAULT_DOMAIN_ID) + .account(super.account) + .buildSigned(super.keyPair) + .let { query -> + client.sendQuery(query) + } + assertEquals(genesisAccountId, domain.ownedBy) + + client.tx { + transferDomainOwnership( + genesisAccountId, + IdBox.DomainId(DEFAULT_DOMAIN_ID), + BOB_ACCOUNT_ID, + ) + } + domain = QueryBuilder.findDomainById(DEFAULT_DOMAIN_ID) + .account(super.account) + .buildSigned(super.keyPair) + .let { query -> + client.sendQuery(query) + } + assertEquals(BOB_ACCOUNT_ID, domain.ownedBy) + } + private suspend fun registerAccount(id: AccountId, publicKey: PublicKey) { client.sendTransaction { account(super.account)