From 240ff7732f21eebfde48b38948aa56753fe97225 Mon Sep 17 00:00:00 2001 From: Carlton Hanna Date: Tue, 20 Aug 2024 10:35:43 -0600 Subject: [PATCH] Fix group save tx processing (#531) * move group save to group service * setup test * add test setup, start moving away from using logs * add backwards compatibility to extracting attribute values * disable a test until complete * remove wildcard imports * update logging * add update to retry blocks table to update error message, it might have changed * change retry tx update to update error message, change scheduled time from 1 min to 5 min * throw an actual meaningful error here when policy not found * look up group policy later in process * add an error when member address not found, instead of null pointer exception * temp comment out ibc * retry error every 10 seconds * remove unused import * fix lints * refactor code for easier debugging, update testing * fix lints * add better logging on retries * fix lint * fix another lint * more lints * lint * remove blank line * add changelog --- CHANGELOG.md | 1 + buildSrc/src/main/kotlin/Dependencies.kt | 2 + service/build.gradle.kts | 2 +- .../explorer/domain/entities/Blocks.kt | 18 +- .../explorer/domain/entities/Groups.kt | 6 +- .../domain/models/explorer/GroupModels.kt | 3 +- .../explorer/grpc/extensions/Helper.kt | 27 +- .../explorer/grpc/v1/TransactionGrpcClient.kt | 4 - .../explorer/service/GroupService.kt | 289 ++++++- .../explorer/service/async/AsyncCachingV2.kt | 272 +------ .../explorer/service/async/AsyncService.kt | 25 +- .../src/main/resources/application.properties | 2 +- .../explorer/grpc/extensions/HelperTest.kt | 40 + .../explorer/service/GroupServiceTest.kt | 75 ++ .../test/resources/group/group-18232283.json | 480 +++++++++++ ...5038FF8DD739CA6C5C29C8901AB0510426F65.json | 332 ++++++++ ...CAC1944C3F606FF6F87A388F30D1F79B05E18.json | 473 +++++++++++ ...00B71B6F6371AACA6388715B730978BB1EE6C.json | 755 ++++++++++++++++++ ...61B7FFCFEDDD83EB27F600608F3E9BAC1D068.json | 392 +++++++++ ...bmit-proposal-with-logs-and-msg-index.json | 589 ++++++++++++++ 20 files changed, 3488 insertions(+), 299 deletions(-) create mode 100644 service/src/test/kotlin/io/provenance/explorer/grpc/extensions/HelperTest.kt create mode 100644 service/src/test/kotlin/io/provenance/explorer/service/GroupServiceTest.kt create mode 100644 service/src/test/resources/group/group-18232283.json create mode 100644 service/src/test/resources/group/group-testnet-417C18D1FAF6B18ECFF55F81CED5038FF8DD739CA6C5C29C8901AB0510426F65.json create mode 100644 service/src/test/resources/group/group-testnet-798D86F2ACB66B842E67AC61E18CAC1944C3F606FF6F87A388F30D1F79B05E18.json create mode 100644 service/src/test/resources/group/group-testnet-9CBD6E9465A4747043B7665338F00B71B6F6371AACA6388715B730978BB1EE6C.json create mode 100644 service/src/test/resources/group/group-testnet-EEEEB2407730626280CFE41F60361B7FFCFEDDD83EB27F600608F3E9BAC1D068.json create mode 100644 service/src/test/resources/grpc/extensions/submit-proposal-with-logs-and-msg-index.json diff --git a/CHANGELOG.md b/CHANGELOG.md index e2937d48..274b45e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * Fixed issue with Proto deserialization incorrectly matching `cosmos.upgrade.v1beta1.CancelSoftwareUpgradeProposal` as `cosmos.upgrade.v1beta1.SoftwareUpgradeProposal`, ensuring accurate type URL handling. [#524](https://github.com/provenance-io/explorer-service/pull/524) * Update osmosis pricing query with new required field `coinMinimalDenom` [#526](https://github.com/provenance-io/explorer-service/pull/526) +* Fix group save tx processing [#526](https://github.com/provenance-io/explorer-service/pull/528), [#526](https://github.com/provenance-io/explorer-service/pull/529) ## [v5.10.0](https://github.com/provenance-io/explorer-service/releases/tag/v5.10.0) - 2024-06-11 ### Release Name: Fridtjof Nansen diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index e222bb53..afa5e910 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -60,6 +60,7 @@ object Versions { const val Jupiter = "5.9.1" const val SpringMockk = "3.1.1" const val Kotest = "5.5.4" + const val H2Database = "1.4.200" } object Libraries { @@ -113,4 +114,5 @@ object Libraries { const val JunitJupiterEngine = "org.junit.jupiter:junit-jupiter-engine:${Versions.Jupiter}" const val SpringMockk = "com.ninja-squad:springmockk:${Versions.SpringMockk}" const val KotestAssert = "io.kotest:kotest-assertions-core:${Versions.Kotest}" + const val H2Database = "com.h2database:h2:${Versions.H2Database}" } diff --git a/service/build.gradle.kts b/service/build.gradle.kts index ffdd2151..e53e1926 100644 --- a/service/build.gradle.kts +++ b/service/build.gradle.kts @@ -69,10 +69,10 @@ dependencies { testImplementation(Libraries.SpringBootStarterTest) { exclude(module = "junit") - exclude(module = "mockito-core") exclude(module = "assertj-core") } testImplementation(Libraries.JunitJupiterApi) + testImplementation(Libraries.H2Database) testRuntimeOnly(Libraries.JunitJupiterEngine) testImplementation(Libraries.SpringMockk) testImplementation(Libraries.KotestAssert) diff --git a/service/src/main/kotlin/io/provenance/explorer/domain/entities/Blocks.kt b/service/src/main/kotlin/io/provenance/explorer/domain/entities/Blocks.kt index 2453ef5e..e51ecf02 100644 --- a/service/src/main/kotlin/io/provenance/explorer/domain/entities/Blocks.kt +++ b/service/src/main/kotlin/io/provenance/explorer/domain/entities/Blocks.kt @@ -61,6 +61,7 @@ import org.jetbrains.exposed.sql.statements.BatchUpdateStatement import org.jetbrains.exposed.sql.sum import org.jetbrains.exposed.sql.transactions.TransactionManager import org.jetbrains.exposed.sql.transactions.transaction +import org.jetbrains.exposed.sql.update import org.joda.time.DateTime import org.joda.time.DateTimeZone import java.sql.ResultSet @@ -515,11 +516,17 @@ object BlockTxRetryTable : IdTable(name = "block_tx_retry") { class BlockTxRetryRecord(id: EntityID) : IntEntity(id) { companion object : IntEntityClass(BlockTxRetryTable) { - fun insert(height: Int, e: Exception) = transaction { - BlockTxRetryTable.insertIgnore { - it[this.height] = height + fun insertOrUpdate(height: Int, e: Exception) = transaction { + val rowsUpdated = BlockTxRetryTable.update({ BlockTxRetryTable.height eq height }) { it[this.errorBlock] = e.stackTraceToString() } + + if (rowsUpdated == 0) { + BlockTxRetryTable.insertIgnore { + it[this.height] = height + it[this.errorBlock] = e.stackTraceToString() + } + } } fun insertNonRetry(height: Int, e: Exception) = transaction { @@ -550,10 +557,13 @@ class BlockTxRetryRecord(id: EntityID) : IntEntity(id) { .map { it.height } } - fun updateRecord(height: Int, success: Boolean) = transaction { + fun updateRecord(height: Int, success: Boolean, e: Exception?) = transaction { BlockTxRetryRecord.find { BlockTxRetryTable.height eq height }.first().apply { this.retried = true this.success = success + if (e != null) { + this.errorBlock = e.stackTraceToString() + } } } diff --git a/service/src/main/kotlin/io/provenance/explorer/domain/entities/Groups.kt b/service/src/main/kotlin/io/provenance/explorer/domain/entities/Groups.kt index 2f7880a5..b1aea4e4 100644 --- a/service/src/main/kotlin/io/provenance/explorer/domain/entities/Groups.kt +++ b/service/src/main/kotlin/io/provenance/explorer/domain/entities/Groups.kt @@ -208,11 +208,13 @@ class GroupsProposalRecord(id: EntityID) : IntEntity(id) { proposalData: GroupsProposalInsertData, txInfo: TxData ) = transaction { + val policyId = GroupsPolicyRecord.findByPolicyAddr(proposalData.policyAddress)?.id?.value + ?: throw IllegalStateException("Policy not found for address: ${proposalData.policyAddress}") listOf( -1, proposalData.groupId, - proposalData.policy.id.value, - proposalData.policy.policyAddress, + policyId, + proposalData.policyAddress, proposalData.proposalId, proposalData.data.stringify(), proposalData.nodeData, diff --git a/service/src/main/kotlin/io/provenance/explorer/domain/models/explorer/GroupModels.kt b/service/src/main/kotlin/io/provenance/explorer/domain/models/explorer/GroupModels.kt index d7707533..5dd84b5b 100644 --- a/service/src/main/kotlin/io/provenance/explorer/domain/models/explorer/GroupModels.kt +++ b/service/src/main/kotlin/io/provenance/explorer/domain/models/explorer/GroupModels.kt @@ -6,7 +6,6 @@ import cosmos.group.v1.Types.Proposal import cosmos.group.v1.Types.ProposalExecutorResult import cosmos.group.v1.Types.ProposalStatus import cosmos.group.v1.Types.VoteOption -import io.provenance.explorer.domain.entities.GroupsPolicyRecord import org.joda.time.DateTime data class GroupMembers(val list: MutableList) @@ -25,7 +24,7 @@ data class GroupsProposalData( data class GroupsProposalInsertData( val groupId: Long, - val policy: GroupsPolicyRecord, + val policyAddress: String, val proposalId: Long, val data: GroupsProposalData, val nodeData: Proposal? = null, diff --git a/service/src/main/kotlin/io/provenance/explorer/grpc/extensions/Helper.kt b/service/src/main/kotlin/io/provenance/explorer/grpc/extensions/Helper.kt index bd2812d3..d47876f5 100644 --- a/service/src/main/kotlin/io/provenance/explorer/grpc/extensions/Helper.kt +++ b/service/src/main/kotlin/io/provenance/explorer/grpc/extensions/Helper.kt @@ -2,16 +2,33 @@ package io.provenance.explorer.grpc.extensions import cosmos.tx.v1beta1.ServiceOuterClass -fun ServiceOuterClass.GetTxResponse.mapEventAttrValues(idx: Int, event: String, attrList: List) = - this.txResponse.logsList[idx].eventsList.firstOrNull { it.type == event } +fun ServiceOuterClass.GetTxResponse.mapEventAttrValues(idx: Int, event: String, attrList: List): Map { + return if (this.txResponse.logsList == null || this.txResponse.logsList.size <= idx) { + mapEventAttrValuesByMsgIndex(idx, event, attrList) + } else { + mapEventAttrValuesFromLogs(idx, event, attrList) + } +} + +fun ServiceOuterClass.GetTxResponse.mapEventAttrValuesFromLogs(idx: Int, event: String, attrList: List): Map { + return this.txResponse.logsList[idx].eventsList.firstOrNull { it.type == event } ?.attributesList?.let { list -> attrList.map { attr -> attr to list.first { it.key == attr }.value.scrubQuotes() } } ?.toMap() ?: mapOf() +} -fun ServiceOuterClass.GetTxResponse.findEvent(idx: Int, event: String) = - this.txResponse.logsList[idx].eventsList.firstOrNull { it.type == event } +fun ServiceOuterClass.GetTxResponse.mapEventAttrValuesByMsgIndex(idx: Int, event: String, attrList: List): Map { + return this.txResponse.eventsList + .firstOrNull { eventEntry -> + eventEntry.type == event && eventEntry.attributesList.any { it.key == "msg_index" && it.value == idx.toString() } + } + ?.attributesList + ?.filter { it.key in attrList } + ?.associate { it.key to it.value.scrubQuotes() } + ?: mapOf() +} fun ServiceOuterClass.GetTxResponse.findAllMatchingEvents(eventList: List) = - this.txResponse.logsList.flatMap { log -> log.eventsList }.filter { it.type in eventList } + this.txResponse.eventsList.filter { it.type in eventList } fun String.removeFirstSlash() = this.split("/")[1] diff --git a/service/src/main/kotlin/io/provenance/explorer/grpc/v1/TransactionGrpcClient.kt b/service/src/main/kotlin/io/provenance/explorer/grpc/v1/TransactionGrpcClient.kt index 6f693a72..c56d58f3 100644 --- a/service/src/main/kotlin/io/provenance/explorer/grpc/v1/TransactionGrpcClient.kt +++ b/service/src/main/kotlin/io/provenance/explorer/grpc/v1/TransactionGrpcClient.kt @@ -2,14 +2,12 @@ package io.provenance.explorer.grpc.v1 import cosmos.tx.v1beta1.ServiceGrpcKt import cosmos.tx.v1beta1.ServiceOuterClass -import cosmos.tx.v1beta1.getTxRequest import cosmos.tx.v1beta1.getTxResponse import cosmos.tx.v1beta1.getTxsEventRequest import io.grpc.ManagedChannelBuilder import io.provenance.explorer.config.interceptor.GrpcLoggingInterceptor import io.provenance.explorer.domain.core.logger import io.provenance.explorer.domain.exceptions.TendermintApiException -import kotlinx.coroutines.runBlocking import org.springframework.stereotype.Component import java.net.URI import java.util.concurrent.TimeUnit @@ -40,8 +38,6 @@ class TransactionGrpcClient(channelUri: URI) { txClient = ServiceGrpcKt.ServiceCoroutineStub(channel) } - fun getTxByHash(hash: String) = runBlocking { txClient.getTx(getTxRequest { this.hash = hash }) } - suspend fun getTxsByHeight(height: Int, total: Int): List { var page = 1 val limit = 10 diff --git a/service/src/main/kotlin/io/provenance/explorer/service/GroupService.kt b/service/src/main/kotlin/io/provenance/explorer/service/GroupService.kt index 1404f0ab..8fcf5d16 100644 --- a/service/src/main/kotlin/io/provenance/explorer/service/GroupService.kt +++ b/service/src/main/kotlin/io/provenance/explorer/service/GroupService.kt @@ -5,17 +5,42 @@ import cosmos.group.v1.Types.ProposalExecutorResult import cosmos.group.v1.Types.ProposalStatus import cosmos.group.v1.Types.Vote import cosmos.group.v1.vote +import cosmos.tx.v1beta1.ServiceOuterClass +import io.provenance.explorer.domain.core.sql.toArray +import io.provenance.explorer.domain.core.sql.toObject import io.provenance.explorer.domain.entities.GroupsHistoryRecord import io.provenance.explorer.domain.entities.GroupsPolicyRecord import io.provenance.explorer.domain.entities.GroupsProposalRecord import io.provenance.explorer.domain.entities.GroupsRecord import io.provenance.explorer.domain.entities.GroupsVoteRecord +import io.provenance.explorer.domain.entities.ProcessQueueRecord +import io.provenance.explorer.domain.entities.ProcessQueueType import io.provenance.explorer.domain.entities.TxGroupsPolicyRecord +import io.provenance.explorer.domain.entities.TxGroupsPolicyTable import io.provenance.explorer.domain.entities.TxGroupsRecord +import io.provenance.explorer.domain.extensions.toDateTime import io.provenance.explorer.domain.models.explorer.GroupMembers import io.provenance.explorer.domain.models.explorer.GroupsProposalData import io.provenance.explorer.domain.models.explorer.GroupsProposalInsertData import io.provenance.explorer.domain.models.explorer.TxData +import io.provenance.explorer.domain.models.explorer.TxUpdate +import io.provenance.explorer.grpc.extensions.GroupEvents +import io.provenance.explorer.grpc.extensions.GroupGovMsgType +import io.provenance.explorer.grpc.extensions.GroupPolicyEvents +import io.provenance.explorer.grpc.extensions.GroupProposalEvents +import io.provenance.explorer.grpc.extensions.getAssociatedGroupPolicies +import io.provenance.explorer.grpc.extensions.getAssociatedGroupProposals +import io.provenance.explorer.grpc.extensions.getAssociatedGroups +import io.provenance.explorer.grpc.extensions.getGroupEventByEvent +import io.provenance.explorer.grpc.extensions.getGroupPolicyEventByEvent +import io.provenance.explorer.grpc.extensions.getGroupsExecutorResult +import io.provenance.explorer.grpc.extensions.getGroupsProposalStatus +import io.provenance.explorer.grpc.extensions.mapEventAttrValues +import io.provenance.explorer.grpc.extensions.scrubQuotes +import io.provenance.explorer.grpc.extensions.toMsgExecGroup +import io.provenance.explorer.grpc.extensions.toMsgSubmitProposalGroup +import io.provenance.explorer.grpc.extensions.toMsgVoteGroup +import io.provenance.explorer.grpc.extensions.toMsgWithdrawProposalGroup import io.provenance.explorer.grpc.v1.GroupGrpcClient import kotlinx.coroutines.runBlocking import org.jetbrains.exposed.sql.transactions.transaction @@ -31,16 +56,20 @@ class GroupService( groupClient.getGroupByIdAtHeight(groupId, height) } - fun groupMembersAHeight(groupId: Long, height: Int) = runBlocking { + fun groupMembersAtHeight(groupId: Long, height: Int) = runBlocking { groupClient.getMembersByGroupAtHeight(groupId, height) } - fun buildGroup(groupId: Long, txData: TxData) = - groupAtHeight(groupId, txData.blockHeight) - ?.let { res -> - val members = groupMembersAHeight(groupId, txData.blockHeight) - GroupsRecord.buildInsert(res.info, GroupMembers(members), txData) - } + fun buildGroup(groupId: Long, txData: TxData): String? { + val group = groupAtHeight(groupId, txData.blockHeight) + + return if (group != null) { + val members = groupMembersAtHeight(groupId, txData.blockHeight) + GroupsRecord.buildInsert(group.info, GroupMembers(members), txData) + } else { + null + } + } fun buildTxGroup(groupId: Long, txData: TxData) = TxGroupsRecord.buildInsert(txData, groupId.toInt()) @@ -79,9 +108,8 @@ class GroupService( result: ProposalExecutorResult, txInfo: TxData ) = transaction { - val policy = GroupsPolicyRecord.findByPolicyAddr(policyAddr) GroupsProposalRecord.buildInsert( - GroupsProposalInsertData(groupId, policy!!, proposalId, data, nodeData, status, result), + GroupsProposalInsertData(groupId, policyAddr, proposalId, data, nodeData, status, result), txInfo ) } @@ -95,12 +123,253 @@ class GroupService( ) = transaction { val members = ( GroupsHistoryRecord.getByIdAndVersion(groupId.toInt(), groupVer.toInt())?.groupMembers?.list - ?: groupMembersAHeight(groupId, txInfo.blockHeight) + ?: groupMembersAtHeight(groupId, txInfo.blockHeight) ) .associate { it.address to BigDecimal(it.weight) } addresses.map { addr -> val addrData = accountService.getAddressDetails(addr) + if (members[addr] == null) { + throw IllegalArgumentException( + "Member not found for the given address: $addr. Available addresses are: ${members.keys.joinToString(", ")}." + ) + } GroupsVoteRecord.buildInsert(addrData, vote, members[addr]!!, txInfo) } } + + fun saveGroups(tx: ServiceOuterClass.GetTxResponse, txInfo: TxData, txUpdate: TxUpdate) = transaction { + // get groups, save + val msgGroups = tx.tx.body.messagesList.mapNotNull { it.getAssociatedGroups() } + val gEvents = tx.txResponse.eventsList + .filter { it.type in GroupEvents.values().map { grp -> grp.event } } + + val eventGroups = gEvents.flatMap { e -> + getGroupEventByEvent(e.type)!!.let { + e.attributesList + .filter { attr -> attr.key in it.idField } + .map { found -> found.value.scrubQuotes().toLong() } + } + } + (msgGroups + eventGroups).toSet().forEach { id -> + buildGroup(id, txInfo)?.let { + txUpdate.apply { + if (tx.txResponse.code == 0) { + this.groupsList.add(it) + } + this.groupJoin.add(buildTxGroup(id, txInfo)) + } + } + } + + // get policies, save + val msgPolicies = tx.tx.body.messagesList.mapNotNull { it.getAssociatedGroupPolicies() } + val eventPolicies = tx.txResponse.eventsList + .filter { it.type in GroupPolicyEvents.values().map { pol -> pol.event } } + .flatMap { e -> + getGroupPolicyEventByEvent(e.type)!!.let { + e.attributesList + .filter { attr -> attr.key in it.idField } + .map { found -> found.value.scrubQuotes() } + } + } + (msgPolicies + eventPolicies).toSet().forEach { addr -> + buildGroupPolicy(addr, txInfo) + ?.also { ProcessQueueRecord.insertIgnore(ProcessQueueType.ACCOUNT, addr) } + ?.let { policy -> + val (join, savedPolicy) = buildTxGroupPolicy(addr, txInfo) + txUpdate.apply { + if (tx.txResponse.code == 0) { + this.groupPolicies + .add(listOf(policy, listOf(join).toArray(TxGroupsPolicyTable.tableName)).toObject()) + } else if (savedPolicy) { + this.policyJoinAlt.add(join) + } + } + } + } + + val govProposalMsgTuples = + tx.tx.body.messagesList.mapIndexedNotNull { idx, msg -> msg.getAssociatedGroupProposals(idx) } + if (tx.txResponse.code == 0) { + govProposalMsgTuples.forEach { triple -> + when (triple.second) { + GroupGovMsgType.PROPOSAL -> { + // Have to find the proposalId in the log events + val proposalId = tx.mapEventAttrValues( + triple.first, + GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.event, + GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.idField.toList() + )[GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.idField.first()]!!.toLong() + + val msg = triple.third.toMsgSubmitProposalGroup() + val nodeData = proposalAtHeight(proposalId, txInfo.blockHeight)?.proposal + val policy = policyAtHeight(msg.groupPolicyAddress, txInfo.blockHeight)!!.info + val group = groupAtHeight(policy.groupId, txInfo.blockHeight)!!.info + val tally = proposalTallyAtHeight(proposalId, txInfo.blockHeight)?.tally + val data = GroupsProposalData( + msg.proposersList, + msg.metadata, + msg.messagesList, + msg.exec.name, + txInfo.txTimestamp, + group.version, + policy.version, + tally, + nodeData?.votingPeriodEnd?.toDateTime() + ) + val status = nodeData?.status ?: ProposalStatus.PROPOSAL_STATUS_ACCEPTED + val execResult = nodeData?.executorResult ?: tx.mapEventAttrValues( + triple.first, + GroupProposalEvents.GROUP_EXEC.event, + listOf("result") + )["result"]!!.getGroupsExecutorResult() + val proposal = buildProposal( + group.id, + policy.address, + proposalId, + data, + nodeData, + status, + execResult, + txInfo + ) + + val votes = buildVotes( + group.id, + group.version, + msg.proposersList, + vote { + this.proposalId = proposalId + this.option = Types.VoteOption.VOTE_OPTION_YES + this.metadata = "" + }, + txInfo + ) + txUpdate.apply { + this.groupProposals.add(proposal) + this.groupVotes.addAll(votes) + this.policyJoinAlt.add(buildTxGroupPolicy(msg.groupPolicyAddress, txInfo).first) + } + } + + GroupGovMsgType.VOTE -> { + val msg = triple.third.toMsgVoteGroup() + val proposal = getProposalById(msg.proposalId)!! + + buildVotes( + proposal.groupId.toLong(), + proposal.proposalData.groupVersion, + listOf(msg.voter), + vote { + this.proposalId = msg.proposalId + this.option = msg.option + this.metadata = msg.metadata + }, + txInfo + ).let { + txUpdate.apply { + this.groupVotes.addAll(it) + this.policyJoinAlt.add(buildTxGroupPolicy(proposal.policyAddress, txInfo).first) + } + } + + val execResult = tx.mapEventAttrValues( + triple.first, + GroupProposalEvents.GROUP_EXEC.event, + listOf("result") + )["result"]?.getGroupsExecutorResult() + + if (execResult != null) { + transaction { + proposal.apply { + if (proposal.proposalStatus.getGroupsProposalStatus() != ProposalStatus.PROPOSAL_STATUS_ACCEPTED) { + this.proposalStatus = ProposalStatus.PROPOSAL_STATUS_ACCEPTED.name + } + if (proposal.executorResult.getGroupsExecutorResult() != execResult) { + this.executorResult = execResult.name + } + } + } + } + } + + GroupGovMsgType.EXEC -> { + val msg = triple.third.toMsgExecGroup() + val proposal = getProposalById(msg.proposalId)!! + + txUpdate.apply { + this.policyJoinAlt.add(buildTxGroupPolicy(proposal.policyAddress, txInfo).first) + } + + val execResult = tx.mapEventAttrValues( + triple.first, + GroupProposalEvents.GROUP_EXEC.event, + listOf("result") + )["result"]?.getGroupsExecutorResult() + + if (execResult != null) { + transaction { + proposal.apply { + if (proposal.proposalStatus.getGroupsProposalStatus() != ProposalStatus.PROPOSAL_STATUS_ACCEPTED) { + this.proposalStatus = ProposalStatus.PROPOSAL_STATUS_ACCEPTED.name + } + if (proposal.executorResult.getGroupsExecutorResult() != execResult) { + this.executorResult = execResult.name + } + } + } + } + } + + GroupGovMsgType.WITHDRAW -> { + val msg = triple.third.toMsgWithdrawProposalGroup() + val proposal = getProposalById(msg.proposalId)!! + + txUpdate.apply { + this.policyJoinAlt.add(buildTxGroupPolicy(proposal.policyAddress, txInfo).first) + } + + transaction { + proposal.apply { this.proposalStatus = ProposalStatus.PROPOSAL_STATUS_WITHDRAWN.name } + } + } + } + } + } else { + govProposalMsgTuples.forEachIndexed { _, triple -> + when (triple.second) { + GroupGovMsgType.PROPOSAL -> { + val msg = triple.third.toMsgSubmitProposalGroup() + txUpdate.apply { + this.policyJoinAlt.add(buildTxGroupPolicy(msg.groupPolicyAddress, txInfo).first) + } + } + + GroupGovMsgType.VOTE -> { + val msg = triple.third.toMsgVoteGroup() + val proposal = getProposalById(msg.proposalId)!! + txUpdate.apply { + this.policyJoinAlt.add(buildTxGroupPolicy(proposal.policyAddress, txInfo).first) + } + } + + GroupGovMsgType.EXEC -> { + val msg = triple.third.toMsgExecGroup() + val proposal = getProposalById(msg.proposalId)!! + txUpdate.apply { + this.policyJoinAlt.add(buildTxGroupPolicy(proposal.policyAddress, txInfo).first) + } + } + + GroupGovMsgType.WITHDRAW -> { + val msg = triple.third.toMsgWithdrawProposalGroup() + val proposal = getProposalById(msg.proposalId)!! + txUpdate.apply { + this.policyJoinAlt.add(buildTxGroupPolicy(proposal.policyAddress, txInfo).first) + } + } + } + } + } + } } diff --git a/service/src/main/kotlin/io/provenance/explorer/service/async/AsyncCachingV2.kt b/service/src/main/kotlin/io/provenance/explorer/service/async/AsyncCachingV2.kt index adf27022..b632670c 100644 --- a/service/src/main/kotlin/io/provenance/explorer/service/async/AsyncCachingV2.kt +++ b/service/src/main/kotlin/io/provenance/explorer/service/async/AsyncCachingV2.kt @@ -3,9 +3,6 @@ package io.provenance.explorer.service.async import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import com.google.protobuf.Timestamp import cosmos.base.tendermint.v1beta1.Query -import cosmos.group.v1.Types -import cosmos.group.v1.Types.ProposalStatus -import cosmos.group.v1.vote import cosmos.tx.v1beta1.ServiceOuterClass import io.provenance.explorer.config.ExplorerProperties import io.provenance.explorer.domain.core.logger @@ -32,7 +29,6 @@ import io.provenance.explorer.domain.entities.TxEventRecord import io.provenance.explorer.domain.entities.TxFeeRecord import io.provenance.explorer.domain.entities.TxFeepayerRecord import io.provenance.explorer.domain.entities.TxGasCacheRecord -import io.provenance.explorer.domain.entities.TxGroupsPolicyTable import io.provenance.explorer.domain.entities.TxIbcRecord import io.provenance.explorer.domain.entities.TxMarkerJoinRecord import io.provenance.explorer.domain.entities.TxMessageRecord @@ -56,17 +52,12 @@ import io.provenance.explorer.domain.extensions.height import io.provenance.explorer.domain.extensions.toDateTime import io.provenance.explorer.domain.models.explorer.BlockProposer import io.provenance.explorer.domain.models.explorer.BlockUpdate -import io.provenance.explorer.domain.models.explorer.GroupsProposalData import io.provenance.explorer.domain.models.explorer.Name import io.provenance.explorer.domain.models.explorer.TxData import io.provenance.explorer.domain.models.explorer.TxUpdate import io.provenance.explorer.grpc.extensions.AddressEvents import io.provenance.explorer.grpc.extensions.DenomEvents import io.provenance.explorer.grpc.extensions.GovMsgType -import io.provenance.explorer.grpc.extensions.GroupEvents -import io.provenance.explorer.grpc.extensions.GroupGovMsgType -import io.provenance.explorer.grpc.extensions.GroupPolicyEvents -import io.provenance.explorer.grpc.extensions.GroupProposalEvents import io.provenance.explorer.grpc.extensions.NameEvents import io.provenance.explorer.grpc.extensions.SmContractEventKeys import io.provenance.explorer.grpc.extensions.SmContractValue @@ -76,17 +67,10 @@ import io.provenance.explorer.grpc.extensions.getAddressEventByEvent import io.provenance.explorer.grpc.extensions.getAssociatedAddresses import io.provenance.explorer.grpc.extensions.getAssociatedDenoms import io.provenance.explorer.grpc.extensions.getAssociatedGovMsgs -import io.provenance.explorer.grpc.extensions.getAssociatedGroupPolicies -import io.provenance.explorer.grpc.extensions.getAssociatedGroupProposals -import io.provenance.explorer.grpc.extensions.getAssociatedGroups import io.provenance.explorer.grpc.extensions.getAssociatedMetadata import io.provenance.explorer.grpc.extensions.getAssociatedMetadataEvents import io.provenance.explorer.grpc.extensions.getAssociatedSmContractMsgs import io.provenance.explorer.grpc.extensions.getDenomEventByEvent -import io.provenance.explorer.grpc.extensions.getGroupEventByEvent -import io.provenance.explorer.grpc.extensions.getGroupPolicyEventByEvent -import io.provenance.explorer.grpc.extensions.getGroupsExecutorResult -import io.provenance.explorer.grpc.extensions.getGroupsProposalStatus import io.provenance.explorer.grpc.extensions.getIbcLedgerMsgs import io.provenance.explorer.grpc.extensions.getMsgSubTypes import io.provenance.explorer.grpc.extensions.getMsgType @@ -106,21 +90,17 @@ import io.provenance.explorer.grpc.extensions.toMsgBindNameRequest import io.provenance.explorer.grpc.extensions.toMsgDeleteNameRequest import io.provenance.explorer.grpc.extensions.toMsgDeposit import io.provenance.explorer.grpc.extensions.toMsgDepositOld -import io.provenance.explorer.grpc.extensions.toMsgExecGroup import io.provenance.explorer.grpc.extensions.toMsgIbcTransferRequest import io.provenance.explorer.grpc.extensions.toMsgRecvPacket import io.provenance.explorer.grpc.extensions.toMsgSubmitProposal -import io.provenance.explorer.grpc.extensions.toMsgSubmitProposalGroup import io.provenance.explorer.grpc.extensions.toMsgSubmitProposalOld import io.provenance.explorer.grpc.extensions.toMsgTimeout import io.provenance.explorer.grpc.extensions.toMsgTimeoutOnClose import io.provenance.explorer.grpc.extensions.toMsgTransfer import io.provenance.explorer.grpc.extensions.toMsgVote -import io.provenance.explorer.grpc.extensions.toMsgVoteGroup import io.provenance.explorer.grpc.extensions.toMsgVoteOld import io.provenance.explorer.grpc.extensions.toMsgVoteWeighted import io.provenance.explorer.grpc.extensions.toMsgVoteWeightedOld -import io.provenance.explorer.grpc.extensions.toMsgWithdrawProposalGroup import io.provenance.explorer.grpc.v1.MsgFeeGrpcClient import io.provenance.explorer.grpc.v1.TransactionGrpcClient import io.provenance.explorer.model.base.isMAddress @@ -205,8 +185,8 @@ class AsyncCachingV2( try { BlockCacheRecord.insertToProcedure(blockUpdate) } catch (e: Exception) { - logger.error("Failed to save block: ${blockRes.block.height()}", e.message) - BlockTxRetryRecord.insert(blockRes.block.height(), e) + logger.error("Failed to save block: ${blockRes.block.height()}", e) + BlockTxRetryRecord.insertOrUpdate(blockRes.block.height(), e) } return blockRes } @@ -281,8 +261,8 @@ class AsyncCachingV2( .map { addTxToCacheWithTimestamp(it, blockTime, proposerRec) } } } catch (e: Exception) { - logger.error("Failed to retrieve transactions at block: $blockHeight", e.message) - BlockTxRetryRecord.insert(blockHeight, e) + logger.error("Failed to retrieve transactions at block: $blockHeight error: ${e.message}", e) + BlockTxRetryRecord.insertOrUpdate(blockHeight, e) listOf() } @@ -311,7 +291,7 @@ class AsyncCachingV2( saveIbcChannelData(res, txInfo, txUpdate) saveSmartContractData(res, txInfo, txUpdate) saveNameData(res, txInfo) - saveGroups(res, txInfo, txUpdate) + groupService.saveGroups(res, txInfo, txUpdate) saveSignaturesTx(res, txInfo, txUpdate) return TxUpdatedItems(addrs, markers, txUpdate) } @@ -724,8 +704,7 @@ class AsyncCachingV2( } } - tx.txResponse.logsList - .flatMap { it.eventsList } + tx.txResponse.eventsList .filter { it.type in SmContractEventKeys.values().map { sc -> sc.eventType } } .flatMap { e -> getSmContractEventByEvent(e.type)!!.let { @@ -780,8 +759,7 @@ class AsyncCachingV2( } } - tx.txResponse.logsList - .flatMap { it.eventsList } + tx.txResponse.eventsList .filter { getNameEventTypes().contains(it.type) } .map { e -> when (e.type) { @@ -809,242 +787,6 @@ class AsyncCachingV2( } } - private fun saveGroups(tx: ServiceOuterClass.GetTxResponse, txInfo: TxData, txUpdate: TxUpdate) = transaction { - // get groups, save - val msgGroups = tx.tx.body.messagesList.mapNotNull { it.getAssociatedGroups() } - val eventGroups = tx.txResponse.logsList - .flatMap { it.eventsList } - .filter { it.type in GroupEvents.values().map { grp -> grp.event } } - .flatMap { e -> - getGroupEventByEvent(e.type)!!.let { - e.attributesList - .filter { attr -> attr.key in it.idField } - .map { found -> found.value.scrubQuotes().toLong() } - } - } - (msgGroups + eventGroups).toSet().forEach { id -> - groupService.buildGroup(id, txInfo)?.let { - txUpdate.apply { - if (tx.txResponse.code == 0) { - this.groupsList.add(it) - } - this.groupJoin.add(groupService.buildTxGroup(id, txInfo)) - } - } - } - - // get policies, save - val msgPolicies = tx.tx.body.messagesList.mapNotNull { it.getAssociatedGroupPolicies() } - val eventPolicies = tx.txResponse.logsList - .flatMap { it.eventsList } - .filter { it.type in GroupPolicyEvents.values().map { pol -> pol.event } } - .flatMap { e -> - getGroupPolicyEventByEvent(e.type)!!.let { - e.attributesList - .filter { attr -> attr.key in it.idField } - .map { found -> found.value.scrubQuotes() } - } - } - (msgPolicies + eventPolicies).toSet().forEach { addr -> - groupService.buildGroupPolicy(addr, txInfo) - ?.also { ProcessQueueRecord.insertIgnore(ProcessQueueType.ACCOUNT, addr) } - ?.let { policy -> - val (join, savedPolicy) = groupService.buildTxGroupPolicy(addr, txInfo) - txUpdate.apply { - if (tx.txResponse.code == 0) { - this.groupPolicies - .add(listOf(policy, listOf(join).toArray(TxGroupsPolicyTable.tableName)).toObject()) - } else if (savedPolicy) { - this.policyJoinAlt.add(join) - } - } - } - } - - val govProposalMsgTuples = tx.tx.body.messagesList.mapIndexedNotNull { idx, msg -> msg.getAssociatedGroupProposals(idx) } - if (tx.txResponse.code == 0) { - govProposalMsgTuples.forEach { triple -> - when (triple.second) { - GroupGovMsgType.PROPOSAL -> { - // Have to find the proposalId in the log events - val proposalId = tx.mapEventAttrValues( - triple.first, - GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.event, - GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.idField.toList() - )[GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.idField.first()]!!.toLong() - - val msg = triple.third.toMsgSubmitProposalGroup() - val nodeData = groupService.proposalAtHeight(proposalId, txInfo.blockHeight)?.proposal - val policy = groupService.policyAtHeight(msg.groupPolicyAddress, txInfo.blockHeight)!!.info - val group = groupService.groupAtHeight(policy.groupId, txInfo.blockHeight)!!.info - val tally = groupService.proposalTallyAtHeight(proposalId, txInfo.blockHeight)?.tally - val data = GroupsProposalData( - msg.proposersList, - msg.metadata, - msg.messagesList, - msg.exec.name, - txInfo.txTimestamp, - group.version, - policy.version, - tally, - nodeData?.votingPeriodEnd?.toDateTime() - ) - val status = nodeData?.status ?: ProposalStatus.PROPOSAL_STATUS_ACCEPTED - val execResult = nodeData?.executorResult ?: tx.mapEventAttrValues( - triple.first, - GroupProposalEvents.GROUP_EXEC.event, - listOf("result") - )["result"]!!.getGroupsExecutorResult() - val proposal = groupService.buildProposal( - group.id, - policy.address, - proposalId, - data, - nodeData, - status, - execResult, - txInfo - ) - - val votes = groupService.buildVotes( - group.id, - group.version, - msg.proposersList, - vote { - this.proposalId = proposalId - this.option = Types.VoteOption.VOTE_OPTION_YES - this.metadata = "" - }, - txInfo - ) - txUpdate.apply { - this.groupProposals.add(proposal) - this.groupVotes.addAll(votes) - this.policyJoinAlt.add(groupService.buildTxGroupPolicy(msg.groupPolicyAddress, txInfo).first) - } - } - - GroupGovMsgType.VOTE -> { - val msg = triple.third.toMsgVoteGroup() - val proposal = groupService.getProposalById(msg.proposalId)!! - - groupService.buildVotes( - proposal.groupId.toLong(), - proposal.proposalData.groupVersion, - listOf(msg.voter), - vote { - this.proposalId = msg.proposalId - this.option = msg.option - this.metadata = msg.metadata - }, - txInfo - ).let { - txUpdate.apply { - this.groupVotes.addAll(it) - this.policyJoinAlt.add(groupService.buildTxGroupPolicy(proposal.policyAddress, txInfo).first) - } - } - - val execResult = tx.mapEventAttrValues( - triple.first, - GroupProposalEvents.GROUP_EXEC.event, - listOf("result") - )["result"]?.getGroupsExecutorResult() - - if (execResult != null) { - transaction { - proposal.apply { - if (proposal.proposalStatus.getGroupsProposalStatus() != ProposalStatus.PROPOSAL_STATUS_ACCEPTED) { - this.proposalStatus = ProposalStatus.PROPOSAL_STATUS_ACCEPTED.name - } - if (proposal.executorResult.getGroupsExecutorResult() != execResult) { - this.executorResult = execResult.name - } - } - } - } - } - - GroupGovMsgType.EXEC -> { - val msg = triple.third.toMsgExecGroup() - val proposal = groupService.getProposalById(msg.proposalId)!! - - txUpdate.apply { - this.policyJoinAlt.add(groupService.buildTxGroupPolicy(proposal.policyAddress, txInfo).first) - } - - val execResult = tx.mapEventAttrValues( - triple.first, - GroupProposalEvents.GROUP_EXEC.event, - listOf("result") - )["result"]?.getGroupsExecutorResult() - - if (execResult != null) { - transaction { - proposal.apply { - if (proposal.proposalStatus.getGroupsProposalStatus() != ProposalStatus.PROPOSAL_STATUS_ACCEPTED) { - this.proposalStatus = ProposalStatus.PROPOSAL_STATUS_ACCEPTED.name - } - if (proposal.executorResult.getGroupsExecutorResult() != execResult) { - this.executorResult = execResult.name - } - } - } - } - } - - GroupGovMsgType.WITHDRAW -> { - val msg = triple.third.toMsgWithdrawProposalGroup() - val proposal = groupService.getProposalById(msg.proposalId)!! - - txUpdate.apply { - this.policyJoinAlt.add(groupService.buildTxGroupPolicy(proposal.policyAddress, txInfo).first) - } - - transaction { - proposal.apply { this.proposalStatus = ProposalStatus.PROPOSAL_STATUS_WITHDRAWN.name } - } - } - } - } - } else { - govProposalMsgTuples.forEachIndexed { _, triple -> - when (triple.second) { - GroupGovMsgType.PROPOSAL -> { - val msg = triple.third.toMsgSubmitProposalGroup() - txUpdate.apply { - this.policyJoinAlt.add(groupService.buildTxGroupPolicy(msg.groupPolicyAddress, txInfo).first) - } - } - - GroupGovMsgType.VOTE -> { - val msg = triple.third.toMsgVoteGroup() - val proposal = groupService.getProposalById(msg.proposalId)!! - txUpdate.apply { - this.policyJoinAlt.add(groupService.buildTxGroupPolicy(proposal.policyAddress, txInfo).first) - } - } - - GroupGovMsgType.EXEC -> { - val msg = triple.third.toMsgExecGroup() - val proposal = groupService.getProposalById(msg.proposalId)!! - txUpdate.apply { - this.policyJoinAlt.add(groupService.buildTxGroupPolicy(proposal.policyAddress, txInfo).first) - } - } - - GroupGovMsgType.WITHDRAW -> { - val msg = triple.third.toMsgWithdrawProposalGroup() - val proposal = groupService.getProposalById(msg.proposalId)!! - txUpdate.apply { - this.policyJoinAlt.add(groupService.buildTxGroupPolicy(proposal.policyAddress, txInfo).first) - } - } - } - } - } - } - private fun saveSignaturesTx(tx: ServiceOuterClass.GetTxResponse, txInfo: TxData, txUpdate: TxUpdate) = transaction { val signerEvents = tx.mapTxEventAttrValues(TX_EVENT, TX_ACC_SEQ) diff --git a/service/src/main/kotlin/io/provenance/explorer/service/async/AsyncService.kt b/service/src/main/kotlin/io/provenance/explorer/service/async/AsyncService.kt index 74762679..cfb6c18e 100644 --- a/service/src/main/kotlin/io/provenance/explorer/service/async/AsyncService.kt +++ b/service/src/main/kotlin/io/provenance/explorer/service/async/AsyncService.kt @@ -236,21 +236,36 @@ class AsyncService( tokenService.updateTokenDistributionStats(UTILITY_TOKEN) } - @Scheduled(cron = "0/5 * * * * ?") // Every 5 seconds + @Scheduled(initialDelay = 0L, fixedDelay = 5000L) fun updateSpotlight() = explorerService.createSpotlight() - @Scheduled(cron = "0 0/5 * * * ?") // Every 5 minute + @Scheduled(initialDelay = 0L, fixedDelay = 30000L) fun retryBlockTxs() { logger.info("Retrying block/tx records") BlockTxRetryRecord.getRecordsToRetry().map { height -> + logger.info("Retrying block/tx record at $height.") + var retryException: Exception? = null val block = try { asyncCache.saveBlockEtc(blockService.getBlockAtHeightFromChain(height), Pair(true, false))!! } catch (e: Exception) { + retryException = e + logger.error("Error saving block $height on retry.", e) null } - val success = - transaction { TxCacheRecord.findByHeight(height).toList() }.size == (block?.block?.data?.txsCount ?: -1) - BlockTxRetryRecord.updateRecord(height, success) + + val success = block?.let { + val txCount = block.block?.data?.txsCount ?: -1 + val dbTxCount = transaction { TxCacheRecord.findByHeight(height).toList().size } + + if (dbTxCount != txCount) { + logger.error("Mismatch in transaction count for retrying block $height. Expected: $txCount, Found: $dbTxCount") + } + + dbTxCount == txCount + } ?: false + + logger.info("Finished retrying block/tx $height with success status: $success") + BlockTxRetryRecord.updateRecord(height, success, retryException) height }.let { if (it.isNotEmpty()) BlockTxRetryRecord.deleteRecords(it) } } diff --git a/service/src/main/resources/application.properties b/service/src/main/resources/application.properties index eff2752a..225767f2 100644 --- a/service/src/main/resources/application.properties +++ b/service/src/main/resources/application.properties @@ -11,6 +11,6 @@ spring.datasource.driver-class-name=org.postgresql.Driver logging.level.io.provenance.timed=warn logging.level.Exposed=ERROR -spring.task.scheduling.pool.size=20 +spring.task.scheduling.pool.size=25 spring.mvc.pathmatch.matching-strategy=ant_path_matcher diff --git a/service/src/test/kotlin/io/provenance/explorer/grpc/extensions/HelperTest.kt b/service/src/test/kotlin/io/provenance/explorer/grpc/extensions/HelperTest.kt new file mode 100644 index 00000000..6efb0dec --- /dev/null +++ b/service/src/test/kotlin/io/provenance/explorer/grpc/extensions/HelperTest.kt @@ -0,0 +1,40 @@ +package io.provenance.explorer.grpc.extensions + +import cosmos.tx.v1beta1.ServiceOuterClass +import io.provenance.explorer.config.RestConfig +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.nio.file.Files +import java.nio.file.Paths + +class HelperTest { + var restConfig = RestConfig() + + fun getTxResponse(fileName: String): ServiceOuterClass.GetTxResponse { + val jsonFilePath = Paths.get("src/test/resources/grpc/extensions/$fileName") + val jsonResponse = String(Files.readAllBytes(jsonFilePath)) + val txResponseBuilder = ServiceOuterClass.GetTxResponse.newBuilder() + val parser = restConfig.protoParser() + + parser?.merge(jsonResponse, txResponseBuilder) + return txResponseBuilder.build() + } + + @Test + fun `test map event attr values from logs and msg index`() { + val response = getTxResponse("submit-proposal-with-logs-and-msg-index.json") + var proposalId = response.mapEventAttrValuesFromLogs( + 1, + GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.event, + GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.idField.toList() + )[GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.idField.first()]!!.toLong() + assertEquals(111500, proposalId) + + proposalId = response.mapEventAttrValuesByMsgIndex( + 1, + GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.event, + GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.idField.toList() + )[GroupProposalEvents.GROUP_SUBMIT_PROPOSAL.idField.first()]!!.toLong() + assertEquals(111500, proposalId) + } +} diff --git a/service/src/test/kotlin/io/provenance/explorer/service/GroupServiceTest.kt b/service/src/test/kotlin/io/provenance/explorer/service/GroupServiceTest.kt new file mode 100644 index 00000000..b0a135da --- /dev/null +++ b/service/src/test/kotlin/io/provenance/explorer/service/GroupServiceTest.kt @@ -0,0 +1,75 @@ +package io.provenance.explorer.service + +import cosmos.tx.v1beta1.ServiceOuterClass +import io.provenance.explorer.config.RestConfig +import io.provenance.explorer.domain.models.explorer.TxData +import io.provenance.explorer.domain.models.explorer.TxUpdate +import io.provenance.explorer.grpc.v1.GroupGrpcClient +import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.sql.transactions.transaction +import org.joda.time.DateTime +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.mockito.Mockito.mock +import java.net.URI +import java.nio.file.Files +import java.nio.file.Paths + +class GroupServiceTest { + private lateinit var restConfig: RestConfig + private lateinit var groupService: GroupService + private lateinit var groupClient: GroupGrpcClient + private lateinit var accountService: AccountService + + @BeforeEach + fun setUp() { + var testnetUri = "grpcs://grpc.test.provenance.io:443" + // var mainnetUri = "grpcs://grpc.provenance.io:443" + val uri = URI(testnetUri) + groupClient = GroupGrpcClient(uri) + accountService = mock(AccountService::class.java) + groupService = GroupService(groupClient, accountService) + restConfig = RestConfig() + } + + @Test + @Disabled("This test is used for manually executing group txs from a file.") + fun testSaveGroups() { + // This test was written to fix problems with saving groups. + // We had no easy way to test without trying to run the whole application. + // This is a way to partially simulate what is going on with a tx with groups. + // It reads a specific file from the resource directory and then calls saveGroups. + // From there, you can debug what is going on. + // To get specific tx to run, you can create a file by calling the grpc endpoint: + // grpcurl -d "{\"hash\":\"$hash\"}" grpc.provenance.io:443 cosmos.tx.v1beta1.Service.GetTx for mainnet + // and grpcurl -d "{\"hash\":\"$hash\"}" grpc.test.provenance.io:443 cosmos.tx.v1beta1.Service.GetTx for testnet. + // We will want to provide some legitimate tests in the future for all new functions. + + Database.connect("jdbc:h2:mem:test;MODE=PostgreSQL;DB_CLOSE_DELAY=-1;", driver = "org.h2.Driver") + transaction { + exec( + """ + CREATE TABLE IF NOT EXISTS process_queue ( + id SERIAL PRIMARY KEY, + process_type VARCHAR(128) NOT NULL, + process_value TEXT NOT NULL, + processing BOOLEAN NOT NULL DEFAULT FALSE + ); + """ + ) + } + + val jsonFilePath = + Paths.get("src/test/resources/group/group-testnet-417C18D1FAF6B18ECFF55F81CED5038FF8DD739CA6C5C29C8901AB0510426F65.json") + val jsonResponse = String(Files.readAllBytes(jsonFilePath)) + val txResponseBuilder = ServiceOuterClass.GetTxResponse.newBuilder() + restConfig.protoParser()!!.merge(jsonResponse, txResponseBuilder) + val txResponse = txResponseBuilder.build() + + val txData = TxData(txResponse.txResponse.height.toInt(), 0, txResponse.txResponse.txhash, DateTime()) + val txUpdate = TxUpdate(txResponse.txResponse.txhash) + + groupService.saveGroups(txResponse, txData, txUpdate) + } +} diff --git a/service/src/test/resources/group/group-18232283.json b/service/src/test/resources/group/group-18232283.json new file mode 100644 index 00000000..145e713d --- /dev/null +++ b/service/src/test/resources/group/group-18232283.json @@ -0,0 +1,480 @@ +{ + "tx": { + "body": { + "messages": [ + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "pb1td8ycyhc2txl27zj9ln6kmj4paaulhjh535al0sv3r9vf6c0wc7s7xggmk", + "messages": [ + { + "@type": "/cosmos.bank.v1beta1.MsgSend", + "amount": [ + { + "denom": "nhash", + "amount": "6028000000" + } + ], + "fromAddress": "pb1td8ycyhc2txl27zj9ln6kmj4paaulhjh535al0sv3r9vf6c0wc7s7xggmk", + "toAddress": "pb18c9hd74gl4et35t8xd999yfh4nh7c2h8x5l5jj" + } + ], + "metadata": "93f269b2-0ebb-434f-a1d1-78823c5830ce", + "proposers": [ + "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh" + ] + } + ] + }, + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "Ao27/S5GCE98x6SrjCDZQ7vB3MsHbv4DRTVfxJmTfG1n" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "98" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "2162422650" + } + ], + "gasLimit": "227026" + } + }, + "signatures": [ + "/WgijeeMtYexd66Ldqvjh1UmwWyRTgeF43Fs0L6gUb1M3v+cs46s8zsClBjerw0RbHmdb2L2IHGAyd8UHfjBww==" + ] + }, + "txResponse": { + "height": "18232283", + "txhash": "169159903A0482120C880441CF8E5B6FB7FF7CB0DF9ECA08208435D965F5C693", + "data": "12320A2A2F636F736D6F732E67726F75702E76312E4D73675375626D697450726F706F73616C526573706F6E73651204089BC709", + "gasWanted": "227026", + "gasUsed": "171822", + "tx": { + "@type": "/cosmos.tx.v1beta1.Tx", + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "Ao27/S5GCE98x6SrjCDZQ7vB3MsHbv4DRTVfxJmTfG1n" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "98" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "2162422650" + } + ], + "gasLimit": "227026" + } + }, + "body": { + "messages": [ + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "pb1td8ycyhc2txl27zj9ln6kmj4paaulhjh535al0sv3r9vf6c0wc7s7xggmk", + "messages": [ + { + "@type": "/cosmos.bank.v1beta1.MsgSend", + "amount": [ + { + "denom": "nhash", + "amount": "6028000000" + } + ], + "fromAddress": "pb1td8ycyhc2txl27zj9ln6kmj4paaulhjh535al0sv3r9vf6c0wc7s7xggmk", + "toAddress": "pb18c9hd74gl4et35t8xd999yfh4nh7c2h8x5l5jj" + } + ], + "metadata": "93f269b2-0ebb-434f-a1d1-78823c5830ce", + "proposers": [ + "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh" + ] + } + ] + }, + "signatures": [ + "/WgijeeMtYexd66Ldqvjh1UmwWyRTgeF43Fs0L6gUb1M3v+cs46s8zsClBjerw0RbHmdb2L2IHGAyd8UHfjBww==" + ] + }, + "timestamp": "2024-08-08T17:30:11Z", + "events": [ + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + }, + { + "key": "amount", + "value": "432484530nhash", + "index": true + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "pb17xpfvakm2amg962yls6f84z3kell8c5lehg9xp", + "index": true + }, + { + "key": "amount", + "value": "432484530nhash", + "index": true + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "pb17xpfvakm2amg962yls6f84z3kell8c5lehg9xp", + "index": true + }, + { + "key": "sender", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + }, + { + "key": "amount", + "value": "432484530nhash", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "2162422650nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "min_fee_charged", + "value": "432484530nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh/98", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "/WgijeeMtYexd66Ldqvjh1UmwWyRTgeF43Fs0L6gUb1M3v+cs46s8zsClBjerw0RbHmdb2L2IHGAyd8UHfjBww==", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.group.v1.MsgSubmitProposal", + "index": true + }, + { + "key": "sender", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + }, + { + "key": "module", + "value": "group", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventSubmitProposal", + "attributes": [ + { + "key": "proposal_id", + "value": "\"156571\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventVote", + "attributes": [ + { + "key": "proposal_id", + "value": "\"156571\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "pb1td8ycyhc2txl27zj9ln6kmj4paaulhjh535al0sv3r9vf6c0wc7s7xggmk", + "index": true + }, + { + "key": "amount", + "value": "6028000000nhash", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "pb18c9hd74gl4et35t8xd999yfh4nh7c2h8x5l5jj", + "index": true + }, + { + "key": "amount", + "value": "6028000000nhash", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "pb18c9hd74gl4et35t8xd999yfh4nh7c2h8x5l5jj", + "index": true + }, + { + "key": "sender", + "value": "pb1td8ycyhc2txl27zj9ln6kmj4paaulhjh535al0sv3r9vf6c0wc7s7xggmk", + "index": true + }, + { + "key": "amount", + "value": "6028000000nhash", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "pb1td8ycyhc2txl27zj9ln6kmj4paaulhjh535al0sv3r9vf6c0wc7s7xggmk", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventProposalPruned", + "attributes": [ + { + "key": "proposal_id", + "value": "\"156571\"", + "index": true + }, + { + "key": "status", + "value": "\"PROPOSAL_STATUS_ACCEPTED\"", + "index": true + }, + { + "key": "tally_result", + "value": "{\"yes_count\":\"1\",\"abstain_count\":\"0\",\"no_count\":\"0\",\"no_with_veto_count\":\"0\"}", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventExec", + "attributes": [ + { + "key": "logs", + "value": "\"\"", + "index": true + }, + { + "key": "proposal_id", + "value": "\"156571\"", + "index": true + }, + { + "key": "result", + "value": "\"PROPOSAL_EXECUTOR_RESULT_SUCCESS\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + }, + { + "key": "amount", + "value": "1729938120nhash", + "index": true + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "pb17xpfvakm2amg962yls6f84z3kell8c5lehg9xp", + "index": true + }, + { + "key": "amount", + "value": "1729938120nhash", + "index": true + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "pb17xpfvakm2amg962yls6f84z3kell8c5lehg9xp", + "index": true + }, + { + "key": "sender", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + }, + { + "key": "amount", + "value": "1729938120nhash", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "pb1znuc2vpg36vegm84mltsmhqn3z9p4sfncaemuh", + "index": true + } + ] + } + ] + } +} diff --git a/service/src/test/resources/group/group-testnet-417C18D1FAF6B18ECFF55F81CED5038FF8DD739CA6C5C29C8901AB0510426F65.json b/service/src/test/resources/group/group-testnet-417C18D1FAF6B18ECFF55F81CED5038FF8DD739CA6C5C29C8901AB0510426F65.json new file mode 100644 index 00000000..3fca38d4 --- /dev/null +++ b/service/src/test/resources/group/group-testnet-417C18D1FAF6B18ECFF55F81CED5038FF8DD739CA6C5C29C8901AB0510426F65.json @@ -0,0 +1,332 @@ +{ + "tx": { + "body": { + "messages": [ + { + "@type": "/cosmos.group.v1.MsgCreateGroupWithPolicy", + "admin": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "decisionPolicy": { + "@type": "/cosmos.group.v1.ThresholdDecisionPolicy", + "threshold": "100", + "windows": { + "votingPeriod": "86400s", + "minExecutionPeriod": "0s" + } + }, + "groupMetadata": "fb63a0ad-b020-49ff-95a0-7acb4dd2620a", + "groupPolicyAsAdmin": true, + "groupPolicyMetadata": "f200b238-5eb7-4c58-be93-3f5258403182", + "members": [ + { + "address": "tp15s02v6c4c3enqzx7kecyalafggp29gl2gch3g7", + "weight": "100", + "metadata": "f17c3b93-53c0-49f4-bd41-5b875b6b6387" + }, + { + "address": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "weight": "100", + "metadata": "5eebba49-ae83-422d-a660-ea7db1839153" + } + ] + } + ], + "timeoutHeight": "23459600" + }, + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "Aqp1Bg96eCTpP8/kdNs8d+2zrruF18MAlEwI1guNr6vH" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "61120" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "4635455550" + } + ], + "gasLimit": "243331" + } + }, + "signatures": [ + "DDif6KmwRi/a7/paril81Z1mfqPqYQrpRveHXK/m1eA2BpicbXltHXnCnbPDfvPSWghcDkvmSd4lypYTbK/m2w==" + ] + }, + "txResponse": { + "height": "23459582", + "txhash": "417C18D1FAF6B18ECFF55F81CED5038FF8DD739CA6C5C29C8901AB0510426F65", + "data": "12770A312F636F736D6F732E67726F75702E76312E4D736743726561746547726F757057697468506F6C696379526573706F6E7365124208B741123D7470316D32356D786166686A376D6C33703473756A77737770716761326666726661336674646D6A796D6C77386A70796D786136337371713777343938", + "gasWanted": "243331", + "gasUsed": "183015", + "tx": { + "@type": "/cosmos.tx.v1beta1.Tx", + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "Aqp1Bg96eCTpP8/kdNs8d+2zrruF18MAlEwI1guNr6vH" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "61120" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "4635455550" + } + ], + "gasLimit": "243331" + } + }, + "body": { + "messages": [ + { + "@type": "/cosmos.group.v1.MsgCreateGroupWithPolicy", + "admin": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "decisionPolicy": { + "@type": "/cosmos.group.v1.ThresholdDecisionPolicy", + "threshold": "100", + "windows": { + "votingPeriod": "86400s", + "minExecutionPeriod": "0s" + } + }, + "groupMetadata": "fb63a0ad-b020-49ff-95a0-7acb4dd2620a", + "groupPolicyAsAdmin": true, + "groupPolicyMetadata": "f200b238-5eb7-4c58-be93-3f5258403182", + "members": [ + { + "address": "tp15s02v6c4c3enqzx7kecyalafggp29gl2gch3g7", + "weight": "100", + "metadata": "f17c3b93-53c0-49f4-bd41-5b875b6b6387" + }, + { + "address": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "weight": "100", + "metadata": "5eebba49-ae83-422d-a660-ea7db1839153" + } + ] + } + ], + "timeoutHeight": "23459600" + }, + "signatures": [ + "DDif6KmwRi/a7/paril81Z1mfqPqYQrpRveHXK/m1eA2BpicbXltHXnCnbPDfvPSWghcDkvmSd4lypYTbK/m2w==" + ] + }, + "timestamp": "2024-07-10T14:58:38Z", + "events": [ + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "amount", + "value": "4635455550nhash", + "index": true + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "amount", + "value": "4635455550nhash", + "index": true + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "amount", + "value": "4635455550nhash", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "4635455550nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "min_fee_charged", + "value": "4635455550nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq/61120", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "DDif6KmwRi/a7/paril81Z1mfqPqYQrpRveHXK/m1eA2BpicbXltHXnCnbPDfvPSWghcDkvmSd4lypYTbK/m2w==", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.group.v1.MsgCreateGroupWithPolicy", + "index": true + }, + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "module", + "value": "group", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventCreateGroup", + "attributes": [ + { + "key": "group_id", + "value": "\"8375\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventCreateGroupPolicy", + "attributes": [ + { + "key": "address", + "value": "\"tp1m25mxafhj7ml3p4sujwswpqga2ffrfa3ftdmjymlw8jpymxa63sqq7w498\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventUpdateGroup", + "attributes": [ + { + "key": "group_id", + "value": "\"8375\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventUpdateGroupPolicy", + "attributes": [ + { + "key": "address", + "value": "\"tp1m25mxafhj7ml3p4sujwswpqga2ffrfa3ftdmjymlw8jpymxa63sqq7w498\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + } + ] + } +} diff --git a/service/src/test/resources/group/group-testnet-798D86F2ACB66B842E67AC61E18CAC1944C3F606FF6F87A388F30D1F79B05E18.json b/service/src/test/resources/group/group-testnet-798D86F2ACB66B842E67AC61E18CAC1944C3F606FF6F87A388F30D1F79B05E18.json new file mode 100644 index 00000000..abe8ae39 --- /dev/null +++ b/service/src/test/resources/group/group-testnet-798D86F2ACB66B842E67AC61E18CAC1944C3F606FF6F87A388F30D1F79B05E18.json @@ -0,0 +1,473 @@ +{ + "tx": { + "body": { + "messages": [ + { + "@type": "/cosmos.authz.v1beta1.MsgGrant", + "grant": { + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/provenance.metadata.v1.MsgUpdateValueOwnersRequest" + }, + "expiration": "2024-07-27T23:26:36.497734695Z" + }, + "grantee": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "granter": "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha" + }, + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "tp1jyp4crcssn2sh97xzd05lq3qnxsw7nxc084w7dllzqq5mcglmy0sxhdmj9", + "messages": [ + { + "@type": "/cosmos.authz.v1beta1.MsgGrant", + "grant": { + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/provenance.metadata.v1.MsgUpdateValueOwnersRequest" + }, + "expiration": "2024-07-27T23:26:36.497671244Z" + }, + "grantee": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "granter": "tp1jyp4crcssn2sh97xzd05lq3qnxsw7nxc084w7dllzqq5mcglmy0sxhdmj9" + } + ], + "proposers": [ + "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha" + ] + } + ], + "timeoutHeight": "23791209" + }, + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "A+MGXlqove6huk+stReazUD43ANdehXQbewNHw/mv8vz" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "1741636" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "5874581850" + } + ], + "gasLimit": "308377", + "granter": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr" + } + }, + "signatures": [ + "c3p3yEcoODtm43BJJfrKkPQefAX0U87gsqS3xih8h2gcFvH+5E+QGjrQG2QY1PZJtCNX/+bUgHplMLpuU6ccCg==" + ] + }, + "txResponse": { + "height": "23791200", + "txhash": "798D86F2ACB66B842E67AC61E18CAC1944C3F606FF6F87A388F30D1F79B05E18", + "data": "12280A262F636F736D6F732E617574687A2E763162657461312E4D73674772616E74526573706F6E736512320A2A2F636F736D6F732E67726F75702E76312E4D73675375626D697450726F706F73616C526573706F6E7365120408E4EF05", + "gasWanted": "308377", + "gasUsed": "224083", + "tx": { + "@type": "/cosmos.tx.v1beta1.Tx", + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "A+MGXlqove6huk+stReazUD43ANdehXQbewNHw/mv8vz" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "1741636" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "5874581850" + } + ], + "gasLimit": "308377", + "granter": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr" + } + }, + "body": { + "messages": [ + { + "@type": "/cosmos.authz.v1beta1.MsgGrant", + "grant": { + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/provenance.metadata.v1.MsgUpdateValueOwnersRequest" + }, + "expiration": "2024-07-27T23:26:36.497734695Z" + }, + "grantee": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "granter": "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha" + }, + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "tp1jyp4crcssn2sh97xzd05lq3qnxsw7nxc084w7dllzqq5mcglmy0sxhdmj9", + "messages": [ + { + "@type": "/cosmos.authz.v1beta1.MsgGrant", + "grant": { + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/provenance.metadata.v1.MsgUpdateValueOwnersRequest" + }, + "expiration": "2024-07-27T23:26:36.497671244Z" + }, + "grantee": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "granter": "tp1jyp4crcssn2sh97xzd05lq3qnxsw7nxc084w7dllzqq5mcglmy0sxhdmj9" + } + ], + "proposers": [ + "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha" + ] + } + ], + "timeoutHeight": "23791209" + }, + "signatures": [ + "c3p3yEcoODtm43BJJfrKkPQefAX0U87gsqS3xih8h2gcFvH+5E+QGjrQG2QY1PZJtCNX/+bUgHplMLpuU6ccCg==" + ] + }, + "timestamp": "2024-07-27T13:26:32Z", + "events": [ + { + "type": "use_feegrant", + "attributes": [ + { + "key": "granter", + "value": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "index": true + }, + { + "key": "grantee", + "value": "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha", + "index": true + } + ] + }, + { + "type": "update_feegrant", + "attributes": [ + { + "key": "granter", + "value": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "index": true + }, + { + "key": "grantee", + "value": "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha", + "index": true + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "index": true + }, + { + "key": "amount", + "value": "5874581850nhash", + "index": true + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "amount", + "value": "5874581850nhash", + "index": true + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "sender", + "value": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "index": true + }, + { + "key": "amount", + "value": "5874581850nhash", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "5874581850nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "min_fee_charged", + "value": "5874581850nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha/1741636", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "c3p3yEcoODtm43BJJfrKkPQefAX0U87gsqS3xih8h2gcFvH+5E+QGjrQG2QY1PZJtCNX/+bUgHplMLpuU6ccCg==", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.authz.v1beta1.MsgGrant", + "index": true + }, + { + "key": "sender", + "value": "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha", + "index": true + }, + { + "key": "module", + "value": "authz", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.authz.v1beta1.EventGrant", + "attributes": [ + { + "key": "grantee", + "value": "\"tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr\"", + "index": true + }, + { + "key": "granter", + "value": "\"tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha\"", + "index": true + }, + { + "key": "msg_type_url", + "value": "\"/provenance.metadata.v1.MsgUpdateValueOwnersRequest\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.group.v1.MsgSubmitProposal", + "index": true + }, + { + "key": "sender", + "value": "tp1rr4d0eu62pgt4edw38d2ev27798pfhdhp5ttha", + "index": true + }, + { + "key": "module", + "value": "group", + "index": true + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventSubmitProposal", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96228\"", + "index": true + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventVote", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96228\"", + "index": true + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.authz.v1beta1.EventGrant", + "attributes": [ + { + "key": "grantee", + "value": "\"tp143sel8w3rshuz7a5jwtq7k4nrgp60tv846kgyr\"", + "index": true + }, + { + "key": "granter", + "value": "\"tp1jyp4crcssn2sh97xzd05lq3qnxsw7nxc084w7dllzqq5mcglmy0sxhdmj9\"", + "index": true + }, + { + "key": "msg_type_url", + "value": "\"/provenance.metadata.v1.MsgUpdateValueOwnersRequest\"", + "index": true + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventProposalPruned", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96228\"", + "index": true + }, + { + "key": "status", + "value": "\"PROPOSAL_STATUS_ACCEPTED\"", + "index": true + }, + { + "key": "tally_result", + "value": "{\"yes_count\":\"100\",\"abstain_count\":\"0\",\"no_count\":\"0\",\"no_with_veto_count\":\"0\"}", + "index": true + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventExec", + "attributes": [ + { + "key": "logs", + "value": "\"\"", + "index": true + }, + { + "key": "proposal_id", + "value": "\"96228\"", + "index": true + }, + { + "key": "result", + "value": "\"PROPOSAL_EXECUTOR_RESULT_SUCCESS\"", + "index": true + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + } + ] + } +} diff --git a/service/src/test/resources/group/group-testnet-9CBD6E9465A4747043B7665338F00B71B6F6371AACA6388715B730978BB1EE6C.json b/service/src/test/resources/group/group-testnet-9CBD6E9465A4747043B7665338F00B71B6F6371AACA6388715B730978BB1EE6C.json new file mode 100644 index 00000000..5ccaeafa --- /dev/null +++ b/service/src/test/resources/group/group-testnet-9CBD6E9465A4747043B7665338F00B71B6F6371AACA6388715B730978BB1EE6C.json @@ -0,0 +1,755 @@ +{ + "tx": { + "body": { + "messages": [ + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f", + "messages": [ + { + "@type": "/provenance.metadata.v1.MsgWriteScopeRequest", + "scope": { + "scopeId": "AHdq69QeIEQ5pWHMdewbPqI=", + "specificationId": "BMxbojCcZ0KSkzR2l3RFh30=", + "owners": [ + { + "address": "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f", + "role": "PARTY_TYPE_OWNER" + } + ], + "dataAccess": [ + "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f", + "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq" + ], + "valueOwnerAddress": "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f" + }, + "scopeUuid": "776aebd4-1e20-4439-a561-cc75ec1b3ea2", + "signers": [ + "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f" + ], + "specUuid": "cc5ba230-9c67-4292-9334-76977445877d" + }, + { + "@type": "/provenance.metadata.v1.MsgWriteSessionRequest", + "session": { + "sessionId": "AXdq69QeIEQ5pWHMdewbPqJ+nwxErJlBT4d6L9Qs9nEE", + "specificationId": "Ax98xpB39kqkoKeQIw3xEG4=", + "parties": [ + { + "address": "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f", + "role": "PARTY_TYPE_OWNER" + } + ], + "name": "tech.figure.passport.StorePassport", + "audit": { + "createdBy": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "updatedBy": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl" + } + }, + "sessionIdComponents": { + "scopeUuid": "776aebd4-1e20-4439-a561-cc75ec1b3ea2", + "sessionUuid": "7e9f0c44-ac99-414f-877a-2fd42cf67104" + }, + "signers": [ + "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f" + ] + }, + { + "@type": "/provenance.metadata.v1.MsgWriteRecordRequest", + "contractSpecUuid": "1f7cc690-77f6-4aa4-a0a7-90230df1106e", + "record": { + "name": "Passport", + "sessionId": "AXdq69QeIEQ5pWHMdewbPqJ+nwxErJlBT4d6L9Qs9nEE", + "process": { + "hash": "3239362c0ef8708cbd660dccaab7a26ba02a463d1b5c64d09864a0bc5e16792e", + "name": "StorePassportProcess", + "method": "StorePassport" + }, + "inputs": [ + { + "name": "Passport", + "hash": "3l49UtxGr/ULdNd/tSBfAQa1hbxLRlOKbR8e1fpWEzM=", + "typeName": "String", + "status": "RECORD_INPUT_STATUS_PROPOSED" + } + ], + "outputs": [ + { + "hash": "3l49UtxGr/ULdNd/tSBfAQa1hbxLRlOKbR8e1fpWEzM=", + "status": "RESULT_STATUS_PASS" + } + ], + "specificationId": "BR98xpB39kqkoKeQIw3xEG7LxHHKYAkrvmxjHwK8Vzmb" + }, + "signers": [ + "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f" + ] + } + ], + "metadata": "d7182b32-bdd9-41ec-92db-9f26131f8f89", + "proposers": [ + "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl" + ] + } + ] + }, + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "A98RWJMRsERkw6XWIB1DjJiXIA2Y8D/IAsSFK2wQAkam" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "1" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "16721735350" + } + ], + "gasLimit": "352847", + "granter": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq" + } + }, + "signatures": [ + "rvKdkB6WP46kwz/Aeo5FCm6Nkr4SkdMzuNft4+tjLqc1WyeDD66YCuyhy5HoiySkirYb1M9d4rsQrCLf0sgNTA==" + ] + }, + "txResponse": { + "height": "23900775", + "txhash": "9CBD6E9465A4747043B7665338F00B71B6F6371AACA6388715B730978BB1EE6C", + "data": "12320A2A2F636F736D6F732E67726F75702E76312E4D73675375626D697450726F706F73616C526573706F6E7365120408ACF505", + "gasWanted": "352847", + "gasUsed": "293325", + "tx": { + "@type": "/cosmos.tx.v1beta1.Tx", + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "A98RWJMRsERkw6XWIB1DjJiXIA2Y8D/IAsSFK2wQAkam" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "1" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "16721735350" + } + ], + "gasLimit": "352847", + "granter": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq" + } + }, + "body": { + "messages": [ + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f", + "messages": [ + { + "@type": "/provenance.metadata.v1.MsgWriteScopeRequest", + "scope": { + "scopeId": "AHdq69QeIEQ5pWHMdewbPqI=", + "specificationId": "BMxbojCcZ0KSkzR2l3RFh30=", + "owners": [ + { + "address": "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f", + "role": "PARTY_TYPE_OWNER" + } + ], + "dataAccess": [ + "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f", + "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq" + ], + "valueOwnerAddress": "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f" + }, + "scopeUuid": "776aebd4-1e20-4439-a561-cc75ec1b3ea2", + "signers": [ + "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f" + ], + "specUuid": "cc5ba230-9c67-4292-9334-76977445877d" + }, + { + "@type": "/provenance.metadata.v1.MsgWriteSessionRequest", + "session": { + "sessionId": "AXdq69QeIEQ5pWHMdewbPqJ+nwxErJlBT4d6L9Qs9nEE", + "specificationId": "Ax98xpB39kqkoKeQIw3xEG4=", + "parties": [ + { + "address": "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f", + "role": "PARTY_TYPE_OWNER" + } + ], + "name": "tech.figure.passport.StorePassport", + "audit": { + "createdBy": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "updatedBy": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl" + } + }, + "sessionIdComponents": { + "scopeUuid": "776aebd4-1e20-4439-a561-cc75ec1b3ea2", + "sessionUuid": "7e9f0c44-ac99-414f-877a-2fd42cf67104" + }, + "signers": [ + "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f" + ] + }, + { + "@type": "/provenance.metadata.v1.MsgWriteRecordRequest", + "contractSpecUuid": "1f7cc690-77f6-4aa4-a0a7-90230df1106e", + "record": { + "name": "Passport", + "sessionId": "AXdq69QeIEQ5pWHMdewbPqJ+nwxErJlBT4d6L9Qs9nEE", + "process": { + "hash": "3239362c0ef8708cbd660dccaab7a26ba02a463d1b5c64d09864a0bc5e16792e", + "name": "StorePassportProcess", + "method": "StorePassport" + }, + "inputs": [ + { + "name": "Passport", + "hash": "3l49UtxGr/ULdNd/tSBfAQa1hbxLRlOKbR8e1fpWEzM=", + "typeName": "String", + "status": "RECORD_INPUT_STATUS_PROPOSED" + } + ], + "outputs": [ + { + "hash": "3l49UtxGr/ULdNd/tSBfAQa1hbxLRlOKbR8e1fpWEzM=", + "status": "RESULT_STATUS_PASS" + } + ], + "specificationId": "BR98xpB39kqkoKeQIw3xEG7LxHHKYAkrvmxjHwK8Vzmb" + }, + "signers": [ + "tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f" + ] + } + ], + "metadata": "d7182b32-bdd9-41ec-92db-9f26131f8f89", + "proposers": [ + "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl" + ] + } + ] + }, + "signatures": [ + "rvKdkB6WP46kwz/Aeo5FCm6Nkr4SkdMzuNft4+tjLqc1WyeDD66YCuyhy5HoiySkirYb1M9d4rsQrCLf0sgNTA==" + ] + }, + "timestamp": "2024-08-01T22:36:52Z", + "events": [ + { + "type": "use_feegrant", + "attributes": [ + { + "key": "granter", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "grantee", + "value": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "index": true + } + ] + }, + { + "type": "update_feegrant", + "attributes": [ + { + "key": "granter", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "grantee", + "value": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "index": true + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "amount", + "value": "6721735350nhash", + "index": true + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "amount", + "value": "6721735350nhash", + "index": true + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "amount", + "value": "6721735350nhash", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "16721735350nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "min_fee_charged", + "value": "6721735350nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl/1", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "rvKdkB6WP46kwz/Aeo5FCm6Nkr4SkdMzuNft4+tjLqc1WyeDD66YCuyhy5HoiySkirYb1M9d4rsQrCLf0sgNTA==", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.group.v1.MsgSubmitProposal", + "index": true + }, + { + "key": "sender", + "value": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventSubmitProposal", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96940\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventVote", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96940\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "provenance.metadata.v1.EventSetNetAssetValue", + "attributes": [ + { + "key": "price", + "value": "\"0usd\"", + "index": true + }, + { + "key": "scope_id", + "value": "\"scope1qpmk4675rcsygwd9v8x8tmqm863qvj6uul\"", + "index": true + }, + { + "key": "source", + "value": "\"metadata\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "provenance.metadata.v1.EventScopeCreated", + "attributes": [ + { + "key": "scope_addr", + "value": "\"scope1qpmk4675rcsygwd9v8x8tmqm863qvj6uul\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "provenance.metadata.v1.EventTxCompleted", + "attributes": [ + { + "key": "endpoint", + "value": "\"WriteScope\"", + "index": true + }, + { + "key": "module", + "value": "\"metadata\"", + "index": true + }, + { + "key": "signers", + "value": "[\"tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f\"]", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "provenance.metadata.v1.EventSessionCreated", + "attributes": [ + { + "key": "scope_addr", + "value": "\"scope1qpmk4675rcsygwd9v8x8tmqm863qvj6uul\"", + "index": true + }, + { + "key": "session_addr", + "value": "\"session1q9mk4675rcsygwd9v8x8tmqm8638a8cvgjkfjs20saazl4pv7ecsg9w5upd\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "provenance.metadata.v1.EventTxCompleted", + "attributes": [ + { + "key": "endpoint", + "value": "\"WriteSession\"", + "index": true + }, + { + "key": "module", + "value": "\"metadata\"", + "index": true + }, + { + "key": "signers", + "value": "[\"tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f\"]", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "provenance.metadata.v1.EventRecordCreated", + "attributes": [ + { + "key": "record_addr", + "value": "\"record1qfmk4675rcsygwd9v8x8tmqm863vh3r3efsqj2a7d3337q4u2uuekxcku7c\"", + "index": true + }, + { + "key": "scope_addr", + "value": "\"scope1qpmk4675rcsygwd9v8x8tmqm863qvj6uul\"", + "index": true + }, + { + "key": "session_addr", + "value": "\"session1q9mk4675rcsygwd9v8x8tmqm8638a8cvgjkfjs20saazl4pv7ecsg9w5upd\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "provenance.metadata.v1.EventTxCompleted", + "attributes": [ + { + "key": "endpoint", + "value": "\"WriteRecord\"", + "index": true + }, + { + "key": "module", + "value": "\"metadata\"", + "index": true + }, + { + "key": "signers", + "value": "[\"tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f\"]", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventProposalPruned", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96940\"", + "index": true + }, + { + "key": "status", + "value": "\"PROPOSAL_STATUS_ACCEPTED\"", + "index": true + }, + { + "key": "tally_result", + "value": "{\"yes_count\":\"100\",\"abstain_count\":\"0\",\"no_count\":\"0\",\"no_with_veto_count\":\"0\"}", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventExec", + "attributes": [ + { + "key": "logs", + "value": "\"\"", + "index": true + }, + { + "key": "proposal_id", + "value": "\"96940\"", + "index": true + }, + { + "key": "result", + "value": "\"PROPOSAL_EXECUTOR_RESULT_SUCCESS\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "amount", + "value": "10000000000nhash", + "index": true + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "amount", + "value": "10000000000nhash", + "index": true + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "amount", + "value": "10000000000nhash", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "additionalfee", + "value": "10000000000nhash", + "index": true + }, + { + "key": "basefee", + "value": "6721735350nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "provenance.msgfees.v1.EventMsgFees", + "attributes": [ + { + "key": "msg_fees", + "value": "[{\"msg_type\":\"/provenance.metadata.v1.MsgWriteScopeRequest\",\"count\":\"1\",\"total\":\"10000000000nhash\",\"recipient\":\"\"}]", + "index": true + } + ] + } + ] + } +} diff --git a/service/src/test/resources/group/group-testnet-EEEEB2407730626280CFE41F60361B7FFCFEDDD83EB27F600608F3E9BAC1D068.json b/service/src/test/resources/group/group-testnet-EEEEB2407730626280CFE41F60361B7FFCFEDDD83EB27F600608F3E9BAC1D068.json new file mode 100644 index 00000000..a77e8670 --- /dev/null +++ b/service/src/test/resources/group/group-testnet-EEEEB2407730626280CFE41F60361B7FFCFEDDD83EB27F600608F3E9BAC1D068.json @@ -0,0 +1,392 @@ +{ + "tx": { + "body": { + "messages": [ + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "tp1n98en3cwgrhkrgfakh5wg7yfvl23lnuzrgg9qlfmdh7ekmtl044sk6pcfm", + "messages": [ + { + "@type": "/cosmos.group.v1.MsgCreateGroupWithPolicy", + "admin": "tp1n98en3cwgrhkrgfakh5wg7yfvl23lnuzrgg9qlfmdh7ekmtl044sk6pcfm", + "decisionPolicy": { + "@type": "/cosmos.group.v1.ThresholdDecisionPolicy", + "threshold": "100", + "windows": { + "votingPeriod": "86400s", + "minExecutionPeriod": "0s" + } + }, + "groupMetadata": "2746579a-97f5-4d8e-9ef6-7811f9cae452", + "groupPolicyMetadata": "427e131b-fe84-4cb2-9f7b-04476414bae8", + "members": [ + { + "address": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "weight": "100", + "metadata": "d2a63045-677f-415d-ab02-b34c47c9b8ab" + } + ] + } + ], + "metadata": "f31b32f9-8d37-481c-9222-7a8f968ba09b", + "proposers": [ + "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq" + ] + } + ], + "timeoutHeight": "23900746" + }, + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "Aqp1Bg96eCTpP8/kdNs8d+2zrruF18MAlEwI1guNr6vH" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "61563" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "5526538350" + } + ], + "gasLimit": "290107" + } + }, + "signatures": [ + "KuPVesL9X6DNHY+BdTXcdIHOaPGQ4gDj1gxd/l0ShiQiFz1JRM9Rg/hzk+G4EqT935PrYZ4Bk7CNfNmT52zrLA==" + ] + }, + "txResponse": { + "height": "23900727", + "txhash": "EEEEB2407730626280CFE41F60361B7FFCFEDDD83EB27F600608F3E9BAC1D068", + "data": "12320A2A2F636F736D6F732E67726F75702E76312E4D73675375626D697450726F706F73616C526573706F6E7365120408ABF505", + "gasWanted": "290107", + "gasUsed": "214199", + "tx": { + "@type": "/cosmos.tx.v1beta1.Tx", + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "Aqp1Bg96eCTpP8/kdNs8d+2zrruF18MAlEwI1guNr6vH" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "61563" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "5526538350" + } + ], + "gasLimit": "290107" + } + }, + "body": { + "messages": [ + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "tp1n98en3cwgrhkrgfakh5wg7yfvl23lnuzrgg9qlfmdh7ekmtl044sk6pcfm", + "messages": [ + { + "@type": "/cosmos.group.v1.MsgCreateGroupWithPolicy", + "admin": "tp1n98en3cwgrhkrgfakh5wg7yfvl23lnuzrgg9qlfmdh7ekmtl044sk6pcfm", + "decisionPolicy": { + "@type": "/cosmos.group.v1.ThresholdDecisionPolicy", + "threshold": "100", + "windows": { + "votingPeriod": "86400s", + "minExecutionPeriod": "0s" + } + }, + "groupMetadata": "2746579a-97f5-4d8e-9ef6-7811f9cae452", + "groupPolicyMetadata": "427e131b-fe84-4cb2-9f7b-04476414bae8", + "members": [ + { + "address": "tp1nrchyhfg8uv9r4jlxfywzyldmqyrd3qp6lyxjl", + "weight": "100", + "metadata": "d2a63045-677f-415d-ab02-b34c47c9b8ab" + } + ] + } + ], + "metadata": "f31b32f9-8d37-481c-9222-7a8f968ba09b", + "proposers": [ + "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq" + ] + } + ], + "timeoutHeight": "23900746" + }, + "signatures": [ + "KuPVesL9X6DNHY+BdTXcdIHOaPGQ4gDj1gxd/l0ShiQiFz1JRM9Rg/hzk+G4EqT935PrYZ4Bk7CNfNmT52zrLA==" + ] + }, + "timestamp": "2024-08-01T22:33:29Z", + "events": [ + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "amount", + "value": "5526538350nhash", + "index": true + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "amount", + "value": "5526538350nhash", + "index": true + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "tp17xpfvakm2amg962yls6f84z3kell8c5l2udfyt", + "index": true + }, + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "amount", + "value": "5526538350nhash", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "5526538350nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "min_fee_charged", + "value": "5526538350nhash", + "index": true + }, + { + "key": "fee_payer", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq/61563", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "KuPVesL9X6DNHY+BdTXcdIHOaPGQ4gDj1gxd/l0ShiQiFz1JRM9Rg/hzk+G4EqT935PrYZ4Bk7CNfNmT52zrLA==", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.group.v1.MsgSubmitProposal", + "index": true + }, + { + "key": "sender", + "value": "tp1v586fwt55n59cmh38w8ny2fxaxejg94kkdxafq", + "index": true + }, + { + "key": "module", + "value": "group", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventSubmitProposal", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96939\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventVote", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96939\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventCreateGroup", + "attributes": [ + { + "key": "group_id", + "value": "\"8593\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventCreateGroupPolicy", + "attributes": [ + { + "key": "address", + "value": "\"tp1354aynhwnjuzvtutu64lap4pldynqfgz0v0ayp9a8xqpgxfvt2msve434f\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventProposalPruned", + "attributes": [ + { + "key": "proposal_id", + "value": "\"96939\"", + "index": true + }, + { + "key": "status", + "value": "\"PROPOSAL_STATUS_ACCEPTED\"", + "index": true + }, + { + "key": "tally_result", + "value": "{\"yes_count\":\"100\",\"abstain_count\":\"0\",\"no_count\":\"0\",\"no_with_veto_count\":\"0\"}", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventExec", + "attributes": [ + { + "key": "logs", + "value": "\"\"", + "index": true + }, + { + "key": "proposal_id", + "value": "\"96939\"", + "index": true + }, + { + "key": "result", + "value": "\"PROPOSAL_EXECUTOR_RESULT_SUCCESS\"", + "index": true + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + } + ] + } +} diff --git a/service/src/test/resources/grpc/extensions/submit-proposal-with-logs-and-msg-index.json b/service/src/test/resources/grpc/extensions/submit-proposal-with-logs-and-msg-index.json new file mode 100644 index 00000000..3f8ede0f --- /dev/null +++ b/service/src/test/resources/grpc/extensions/submit-proposal-with-logs-and-msg-index.json @@ -0,0 +1,589 @@ +{ + "tx": { + "body": { + "messages": [ + { + "@type": "/cosmos.authz.v1beta1.MsgGrant", + "grant": { + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/provenance.metadata.v1.MsgWriteScopeRequest" + }, + "expiration": "2024-03-22T11:57:26.011699069Z" + }, + "grantee": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca", + "granter": "pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd" + }, + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "pb1whzz6j94tfsz2nyhqd2xu4ctfru28lj4zaa5npr5w39r6yy2slnsvyft3v", + "messages": [ + { + "@type": "/cosmos.authz.v1beta1.MsgGrant", + "grant": { + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/provenance.metadata.v1.MsgWriteScopeRequest" + }, + "expiration": "2024-03-22T11:57:26.011636429Z" + }, + "grantee": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca", + "granter": "pb1whzz6j94tfsz2nyhqd2xu4ctfru28lj4zaa5npr5w39r6yy2slnsvyft3v" + } + ], + "proposers": [ + "pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd" + ] + } + ], + "timeoutHeight": "15622439" + }, + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "AxfSB7+TgeQojPqXDpcIwT7gR4ghE9NC4vYsdNORgRr3" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "4543856" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "3115236975" + } + ], + "gasLimit": "327059", + "granter": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + } + }, + "signatures": [ + "3ZljAQhyyhUrnmfqzFwWqFTMdaDC8YgLmJnPuPXN0dY/xY8A2OMdX89Qvq+Vb0dCl7R2NfhjJD4Y8K6kuXTXgA==" + ] + }, + "txResponse": { + "height": "15622432", + "txhash": "F71919C0920AB49A7CE4624CB897A676AAFD4F4392D424FA59AD4C5383AC6CD7", + "data": "12280A262F636F736D6F732E617574687A2E763162657461312E4D73674772616E74526573706F6E736512320A2A2F636F736D6F732E67726F75702E76312E4D73675375626D697450726F706F73616C526573706F6E73651204088CE706", + "rawLog": "[{\"msg_index\":0,\"events\":[{\"type\":\"cosmos.authz.v1beta1.EventGrant\",\"attributes\":[{\"key\":\"grantee\",\"value\":\"\\\"pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca\\\"\"},{\"key\":\"granter\",\"value\":\"\\\"pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd\\\"\"},{\"key\":\"msg_type_url\",\"value\":\"\\\"/provenance.metadata.v1.MsgWriteScopeRequest\\\"\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"/cosmos.authz.v1beta1.MsgGrant\"}]}]},{\"msg_index\":1,\"events\":[{\"type\":\"cosmos.authz.v1beta1.EventGrant\",\"attributes\":[{\"key\":\"grantee\",\"value\":\"\\\"pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca\\\"\"},{\"key\":\"granter\",\"value\":\"\\\"pb1whzz6j94tfsz2nyhqd2xu4ctfru28lj4zaa5npr5w39r6yy2slnsvyft3v\\\"\"},{\"key\":\"msg_type_url\",\"value\":\"\\\"/provenance.metadata.v1.MsgWriteScopeRequest\\\"\"}]},{\"type\":\"cosmos.group.v1.EventExec\",\"attributes\":[{\"key\":\"logs\",\"value\":\"\\\"\\\"\"},{\"key\":\"proposal_id\",\"value\":\"\\\"111500\\\"\"},{\"key\":\"result\",\"value\":\"\\\"PROPOSAL_EXECUTOR_RESULT_SUCCESS\\\"\"}]},{\"type\":\"cosmos.group.v1.EventProposalPruned\",\"attributes\":[{\"key\":\"proposal_id\",\"value\":\"\\\"111500\\\"\"},{\"key\":\"status\",\"value\":\"\\\"PROPOSAL_STATUS_ACCEPTED\\\"\"},{\"key\":\"tally_result\",\"value\":\"{\\\"yes_count\\\":\\\"100\\\",\\\"abstain_count\\\":\\\"0\\\",\\\"no_count\\\":\\\"0\\\",\\\"no_with_veto_count\\\":\\\"0\\\"}\"}]},{\"type\":\"cosmos.group.v1.EventSubmitProposal\",\"attributes\":[{\"key\":\"proposal_id\",\"value\":\"\\\"111500\\\"\"}]},{\"type\":\"cosmos.group.v1.EventVote\",\"attributes\":[{\"key\":\"proposal_id\",\"value\":\"\\\"111500\\\"\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"/cosmos.group.v1.MsgSubmitProposal\"}]}]}]", + "logs": [ + { + "events": [ + { + "type": "cosmos.authz.v1beta1.EventGrant", + "attributes": [ + { + "key": "grantee", + "value": "\"pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca\"" + }, + { + "key": "granter", + "value": "\"pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd\"" + }, + { + "key": "msg_type_url", + "value": "\"/provenance.metadata.v1.MsgWriteScopeRequest\"" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.authz.v1beta1.MsgGrant" + } + ] + } + ] + }, + { + "msgIndex": 1, + "events": [ + { + "type": "cosmos.authz.v1beta1.EventGrant", + "attributes": [ + { + "key": "grantee", + "value": "\"pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca\"" + }, + { + "key": "granter", + "value": "\"pb1whzz6j94tfsz2nyhqd2xu4ctfru28lj4zaa5npr5w39r6yy2slnsvyft3v\"" + }, + { + "key": "msg_type_url", + "value": "\"/provenance.metadata.v1.MsgWriteScopeRequest\"" + } + ] + }, + { + "type": "cosmos.group.v1.EventExec", + "attributes": [ + { + "key": "logs", + "value": "\"\"" + }, + { + "key": "proposal_id", + "value": "\"111500\"" + }, + { + "key": "result", + "value": "\"PROPOSAL_EXECUTOR_RESULT_SUCCESS\"" + } + ] + }, + { + "type": "cosmos.group.v1.EventProposalPruned", + "attributes": [ + { + "key": "proposal_id", + "value": "\"111500\"" + }, + { + "key": "status", + "value": "\"PROPOSAL_STATUS_ACCEPTED\"" + }, + { + "key": "tally_result", + "value": "{\"yes_count\":\"100\",\"abstain_count\":\"0\",\"no_count\":\"0\",\"no_with_veto_count\":\"0\"}" + } + ] + }, + { + "type": "cosmos.group.v1.EventSubmitProposal", + "attributes": [ + { + "key": "proposal_id", + "value": "\"111500\"" + } + ] + }, + { + "type": "cosmos.group.v1.EventVote", + "attributes": [ + { + "key": "proposal_id", + "value": "\"111500\"" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.group.v1.MsgSubmitProposal" + } + ] + } + ] + } + ], + "gasWanted": "327059", + "gasUsed": "228753", + "tx": { + "@type": "/cosmos.tx.v1beta1.Tx", + "authInfo": { + "signerInfos": [ + { + "publicKey": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "AxfSB7+TgeQojPqXDpcIwT7gR4ghE9NC4vYsdNORgRr3" + }, + "modeInfo": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "4543856" + } + ], + "fee": { + "amount": [ + { + "denom": "nhash", + "amount": "3115236975" + } + ], + "gasLimit": "327059", + "granter": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + } + }, + "body": { + "messages": [ + { + "@type": "/cosmos.authz.v1beta1.MsgGrant", + "grant": { + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/provenance.metadata.v1.MsgWriteScopeRequest" + }, + "expiration": "2024-03-22T11:57:26.011699069Z" + }, + "grantee": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca", + "granter": "pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd" + }, + { + "@type": "/cosmos.group.v1.MsgSubmitProposal", + "exec": "EXEC_TRY", + "groupPolicyAddress": "pb1whzz6j94tfsz2nyhqd2xu4ctfru28lj4zaa5npr5w39r6yy2slnsvyft3v", + "messages": [ + { + "@type": "/cosmos.authz.v1beta1.MsgGrant", + "grant": { + "authorization": { + "@type": "/cosmos.authz.v1beta1.GenericAuthorization", + "msg": "/provenance.metadata.v1.MsgWriteScopeRequest" + }, + "expiration": "2024-03-22T11:57:26.011636429Z" + }, + "grantee": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca", + "granter": "pb1whzz6j94tfsz2nyhqd2xu4ctfru28lj4zaa5npr5w39r6yy2slnsvyft3v" + } + ], + "proposers": [ + "pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd" + ] + } + ], + "timeoutHeight": "15622439" + }, + "signatures": [ + "3ZljAQhyyhUrnmfqzFwWqFTMdaDC8YgLmJnPuPXN0dY/xY8A2OMdX89Qvq+Vb0dCl7R2NfhjJD4Y8K6kuXTXgA==" + ] + }, + "timestamp": "2024-03-22T01:57:35Z", + "events": [ + { + "type": "use_feegrant", + "attributes": [ + { + "key": "granter", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + }, + { + "key": "grantee", + "value": "pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd" + } + ] + }, + { + "type": "update_feegrant", + "attributes": [ + { + "key": "granter", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + }, + { + "key": "grantee", + "value": "pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + }, + { + "key": "amount", + "value": "623047395nhash" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "pb17xpfvakm2amg962yls6f84z3kell8c5lehg9xp" + }, + { + "key": "amount", + "value": "623047395nhash" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "pb17xpfvakm2amg962yls6f84z3kell8c5lehg9xp" + }, + { + "key": "sender", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + }, + { + "key": "amount", + "value": "623047395nhash" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca", + "index": true + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "3115236975nhash" + }, + { + "key": "fee_payer", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "min_fee_charged", + "value": "623047395nhash" + }, + { + "key": "fee_payer", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd/4543856" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "3ZljAQhyyhUrnmfqzFwWqFTMdaDC8YgLmJnPuPXN0dY/xY8A2OMdX89Qvq+Vb0dCl7R2NfhjJD4Y8K6kuXTXgA==" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.authz.v1beta1.MsgGrant" + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "cosmos.authz.v1beta1.EventGrant", + "attributes": [ + { + "key": "grantee", + "value": "\"pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca\"" + }, + { + "key": "granter", + "value": "\"pb1xvd4k9jg5h0d4dhzr4z0txtwe9p5zxf58xcmxd\"" + }, + { + "key": "msg_type_url", + "value": "\"/provenance.metadata.v1.MsgWriteScopeRequest\"" + }, + { + "key": "msg_index", + "value": "0", + "index": true + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmos.group.v1.MsgSubmitProposal" + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventSubmitProposal", + "attributes": [ + { + "key": "proposal_id", + "value": "\"111500\"" + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventVote", + "attributes": [ + { + "key": "proposal_id", + "value": "\"111500\"" + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.authz.v1beta1.EventGrant", + "attributes": [ + { + "key": "grantee", + "value": "\"pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca\"" + }, + { + "key": "granter", + "value": "\"pb1whzz6j94tfsz2nyhqd2xu4ctfru28lj4zaa5npr5w39r6yy2slnsvyft3v\"" + }, + { + "key": "msg_type_url", + "value": "\"/provenance.metadata.v1.MsgWriteScopeRequest\"" + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventProposalPruned", + "attributes": [ + { + "key": "proposal_id", + "value": "\"111500\"" + }, + { + "key": "status", + "value": "\"PROPOSAL_STATUS_ACCEPTED\"" + }, + { + "key": "tally_result", + "value": "{\"yes_count\":\"100\",\"abstain_count\":\"0\",\"no_count\":\"0\",\"no_with_veto_count\":\"0\"}" + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "cosmos.group.v1.EventExec", + "attributes": [ + { + "key": "logs", + "value": "\"\"" + }, + { + "key": "proposal_id", + "value": "\"111500\"" + }, + { + "key": "result", + "value": "\"PROPOSAL_EXECUTOR_RESULT_SUCCESS\"" + }, + { + "key": "msg_index", + "value": "1", + "index": true + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "spender", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + }, + { + "key": "amount", + "value": "2492189580nhash" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "receiver", + "value": "pb17xpfvakm2amg962yls6f84z3kell8c5lehg9xp" + }, + { + "key": "amount", + "value": "2492189580nhash" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "recipient", + "value": "pb17xpfvakm2amg962yls6f84z3kell8c5lehg9xp" + }, + { + "key": "sender", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca" + }, + { + "key": "amount", + "value": "2492189580nhash" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "pb1zsherr3eat6gvq9ptg3m0n3dj33xf2mwevk3ca", + "index": true + } + ] + } + ] + } +}