diff --git a/es-api-model/src/main/resources/tendermint-v0.34.12-rpc-openapi-FIXED.yaml b/es-api-model/src/main/resources/tendermint-v0.34.12-rpc-openapi-FIXED.yaml index e140914d..64ba36dc 100644 --- a/es-api-model/src/main/resources/tendermint-v0.34.12-rpc-openapi-FIXED.yaml +++ b/es-api-model/src/main/resources/tendermint-v0.34.12-rpc-openapi-FIXED.yaml @@ -1905,7 +1905,7 @@ components: - "chain_id" - "initial_height" - "consensus_params" - - "validators" +# - "validators" # for some reason this schema has this as required, but it comes back as empty from the chain... maybe this is just out of date? - "app_hash" properties: genesis_time: @@ -2938,11 +2938,19 @@ components: evidence: type: object required: - - "max_age" + - "max_age_num_blocks" + - "max_age_duration" + - "max_bytes" properties: - max_age: + max_age_num_blocks: # Manually updated these properties to reflect the current properties here in cosmos/tendermint type: string example: "100000" + max_age_duration: + type: string + example: "172800000000000" + max_bytes: + type: string + example: "1048576" validator: type: object required: diff --git a/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/BlockFetcher.kt b/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/BlockFetcher.kt index 3cb393e7..2e42f6b0 100644 --- a/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/BlockFetcher.kt +++ b/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/BlockFetcher.kt @@ -68,6 +68,7 @@ open class BlockFetchException(m: String) : Exception(m) interface BlockFetcher { suspend fun getBlocksMeta(min: Long, max: Long): List? suspend fun getCurrentHeight(): Long? + suspend fun getInitialHeight(): Long suspend fun getBlock(height: Long): BlockData suspend fun getBlockResults(height: Long): BlockResultsResponse? suspend fun getBlocks(heights: List, concurrency: Int = DEFAULT_CONCURRENCY, context: CoroutineContext = EmptyCoroutineContext): Flow diff --git a/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintBlockFetcher.kt b/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintBlockFetcher.kt index e87b660b..195c567f 100644 --- a/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintBlockFetcher.kt +++ b/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintBlockFetcher.kt @@ -29,6 +29,10 @@ class TendermintBlockFetcher( ?: throw BlockFetchException("failed to fetch current block height") } + override suspend fun getInitialHeight(): Long { + return tendermintServiceClient.genesis().result.genesis.initialHeight + } + override suspend fun getBlock(height: Long): BlockData { log.trace("getBlock($height)") val block = tendermintServiceClient.block(height).result?.block diff --git a/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintServiceClient.kt b/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintServiceClient.kt index 098b25cf..6bc882ed 100644 --- a/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintServiceClient.kt +++ b/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintServiceClient.kt @@ -4,12 +4,14 @@ import tech.figure.eventstream.stream.models.ABCIInfoResponse import tech.figure.eventstream.stream.models.BlockResponse import tech.figure.eventstream.stream.models.BlockResultsResponse import tech.figure.eventstream.stream.models.BlockchainResponse +import tech.figure.eventstream.stream.models.GenesisResponse /** * A client designed to interact with the Tendermint RPC API. */ interface TendermintServiceClient { suspend fun abciInfo(): ABCIInfoResponse + suspend fun genesis(): GenesisResponse suspend fun block(height: Long?): BlockResponse suspend fun blockResults(height: Long?): BlockResultsResponse suspend fun blockchain(minHeight: Long?, maxHeight: Long?): BlockchainResponse diff --git a/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintServiceOpenApiClient.kt b/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintServiceOpenApiClient.kt index 3848251f..71bf3ba6 100644 --- a/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintServiceOpenApiClient.kt +++ b/es-core/src/main/kotlin/tech/figure/eventstream/stream/clients/TendermintServiceOpenApiClient.kt @@ -8,6 +8,7 @@ import tech.figure.eventstream.stream.models.ABCIInfoResponse import tech.figure.eventstream.stream.models.BlockResponse import tech.figure.eventstream.stream.models.BlockResultsResponse import tech.figure.eventstream.stream.models.BlockchainResponse +import tech.figure.eventstream.stream.models.GenesisResponse /** * An OpenAPI generated client designed to interact with the Tendermint RPC API. @@ -30,6 +31,8 @@ class TendermintServiceOpenApiClient( override suspend fun abciInfo(): ABCIInfoResponse = abciApi.abciInfo() + override suspend fun genesis(): GenesisResponse = infoApi.genesis() + override suspend fun block(height: Long?): BlockResponse = infoApi.block(height) override suspend fun blockResults(height: Long?): BlockResultsResponse = infoApi.blockResults(height) diff --git a/es-core/src/test/kotlin/tech/figure/eventstream/StreamTests.kt b/es-core/src/test/kotlin/tech/figure/eventstream/StreamTests.kt index 2eb6c9fd..d271afdf 100644 --- a/es-core/src/test/kotlin/tech/figure/eventstream/StreamTests.kt +++ b/es-core/src/test/kotlin/tech/figure/eventstream/StreamTests.kt @@ -32,6 +32,7 @@ import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.assertThrows import tech.figure.eventstream.mocks.MockEventStreamService import tech.figure.eventstream.stream.clients.TendermintServiceClient +import tech.figure.eventstream.stream.models.GenesisResponse @TestInstance(TestInstance.Lifecycle.PER_CLASS) class StreamTests : TestBase() { @@ -153,6 +154,27 @@ class StreamTests : TestBase() { } } + @OptIn(ExperimentalCoroutinesApi::class) + @Test + fun testGenesisResponse() { + val expectedInitialHeight = 10000L + + val tm = ServiceMocker.Builder() + .doFor("genesis") { + templates.readAs( + GenesisResponse::class.java, + "genesis/success.json", + mapOf("initial_height" to expectedInitialHeight), + ) + } + .build(MockTendermintServiceClient::class.java) + + dispatcherProvider.runBlockingTest { + val initialHeight = tm.genesis().result.genesis.initialHeight + assert(initialHeight == expectedInitialHeight) { "expected: $expectedInitialHeight received: $initialHeight" } + } + } + // duped @OptIn(ExperimentalCoroutinesApi::class) @Test diff --git a/es-core/src/testFixtures/kotlin/tech/figure/eventstream/mocks/MockNetAdapter.kt b/es-core/src/testFixtures/kotlin/tech/figure/eventstream/mocks/MockNetAdapter.kt index e30108e9..ad8c25ff 100644 --- a/es-core/src/testFixtures/kotlin/tech/figure/eventstream/mocks/MockNetAdapter.kt +++ b/es-core/src/testFixtures/kotlin/tech/figure/eventstream/mocks/MockNetAdapter.kt @@ -23,6 +23,7 @@ import tech.figure.eventstream.utils.Template import io.reactivex.Flowable import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow +import tech.figure.eventstream.stream.models.GenesisResponse import java.util.concurrent.atomic.AtomicBoolean import kotlin.coroutines.CoroutineContext @@ -90,6 +91,11 @@ fun mockBlockFetcher(template: Template, currentHeight: Long? = null): BlockFetc return response!!.result!!.response.lastBlockHeight!! } + override suspend fun getInitialHeight(): Long { + val response = template.readAs(GenesisResponse::class.java, "genesis/success.json") + return response!!.result.genesis.initialHeight + } + override suspend fun getBlock(height: Long): BlockData { val block = template.readAs(BlockResponse::class.java, "block/$height.json") val results = template.readAs(BlockResultsResponse::class.java, "block_results/$height.json") diff --git a/es-core/src/testFixtures/kotlin/tech/figure/eventstream/mocks/MockTendermintServiceClient.kt b/es-core/src/testFixtures/kotlin/tech/figure/eventstream/mocks/MockTendermintServiceClient.kt index 8c75a97d..ceebb3e0 100644 --- a/es-core/src/testFixtures/kotlin/tech/figure/eventstream/mocks/MockTendermintServiceClient.kt +++ b/es-core/src/testFixtures/kotlin/tech/figure/eventstream/mocks/MockTendermintServiceClient.kt @@ -5,12 +5,15 @@ import tech.figure.eventstream.stream.models.BlockResultsResponse import tech.figure.eventstream.stream.models.BlockchainResponse import tech.figure.eventstream.stream.clients.TendermintServiceClient import tech.figure.eventstream.stream.models.ABCIInfoResponse +import tech.figure.eventstream.stream.models.GenesisResponse class MockTendermintServiceClient(mocker: ServiceMock) : TendermintServiceClient, ServiceMock by mocker { override suspend fun abciInfo() = respondWith("abciInfo") + override suspend fun genesis() = respondWith("genesis") + override suspend fun block(height: Long?) = respondWith("block", height) diff --git a/es-core/src/testFixtures/resources/templates/genesis/success.json b/es-core/src/testFixtures/resources/templates/genesis/success.json new file mode 100644 index 00000000..6ec211c2 --- /dev/null +++ b/es-core/src/testFixtures/resources/templates/genesis/success.json @@ -0,0 +1,758 @@ +{ + "jsonrpc": "2.0", + "id": -1, + "result": { + "genesis": { + "genesis_time": "2021-03-09T18:45:22.152625998Z", + "chain_id": "pio-testnet-1", + "initial_height": "${initial_height:-1}", + "consensus_params": { + "block": { + "max_bytes": "22020096", + "max_gas": "-1", + "time_iota_ms": "1000" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000", + "max_bytes": "1048576" + }, + "validator": { + "pub_key_types": [ + "ed25519" + ] + }, + "version": {} + }, + "app_hash": "", + "app_state": { + "attribute": { + "params": { + "max_value_length": 10000 + }, + "attributes": [] + }, + "auth": { + "params": { + "max_memo_characters": "256", + "tx_sig_limit": "7", + "tx_size_cost_per_byte": "10", + "sig_verify_cost_ed25519": "590", + "sig_verify_cost_secp256k1": "1000" + }, + "accounts": [ + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1s9c2asqtp4f6r5k4jsg97p5yekqc6rhqqv7vky", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp16hyrvw2905fkyjp66t46hua6thctu5d54as6n5", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1tgq6cpu6hmsrvkvdu82j99tsxxw7qqajvwg9uu", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1x299m72h6n88sswg2p9fp8lvkhrtqsvvnc7j9g", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1mhspjegunfnlac6cayd4uf5uvz3wfnymwy4p3t", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1kmaut7y3psh46lw53hgm4967zfxpq5ls2m2w7v", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1tk23vs7sr9mc04euvx3pcdfuagxd7rtmqs83m8", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1rc9yszgy5pcgkndz6p7734mqkqmasg2r6exe0c", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1vpuk0shj9v0y6dh64z858hh08q25kjcpuf09fw", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1jd9rpe6xwxkvmzu4lklpef5qla6tzxxd7g3j5s", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1wt29em7nkmzjayk755cn0f2u563d2f9kxtluqc", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1zk3qvk6dvpk6394chmvq5gtrw5arqzsag072h5", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1l4qpmuh2du6x9zrwfxe0yxwd9jmaqheztmftu8", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp1a5r00sn57g3efsk76lgj7mnyswjv09lljvjjz0", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/cosmos.auth.v1beta1.BaseAccount", + "address": "tp19fn5mlntyxafugetc8lyzzre6nnyqsq95449gt", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + { + "@type": "/provenance.marker.v1.MarkerAccount", + "base_account": { + "address": "tp1pr93cqdh4kfnmrknhwa87a5qrwxw9k3dhkszp0", + "pub_key": null, + "account_number": "0", + "sequence": "0" + }, + "manager": "", + "access_control": [ + { + "address": "tp1kmaut7y3psh46lw53hgm4967zfxpq5ls2m2w7v", + "permissions": [ + "ACCESS_WITHDRAW" + ] + } + ], + "status": "MARKER_STATUS_ACTIVE", + "denom": "nhash", + "supply": "100000000000000000000", + "marker_type": "MARKER_TYPE_COIN", + "supply_fixed": true, + "allow_governance_control": true + } + ] + }, + "bank": { + "params": { + "send_enabled": [], + "default_send_enabled": true + }, + "balances": [ + { + "address": "tp1zk3qvk6dvpk6394chmvq5gtrw5arqzsag072h5", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp1rc9yszgy5pcgkndz6p7734mqkqmasg2r6exe0c", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp19fn5mlntyxafugetc8lyzzre6nnyqsq95449gt", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp1x299m72h6n88sswg2p9fp8lvkhrtqsvvnc7j9g", + "coins": [ + { + "denom": "nhash", + "amount": "100000000000000000" + } + ] + }, + { + "address": "tp1tgq6cpu6hmsrvkvdu82j99tsxxw7qqajvwg9uu", + "coins": [ + { + "denom": "nhash", + "amount": "100000000000000000" + } + ] + }, + { + "address": "tp1tk23vs7sr9mc04euvx3pcdfuagxd7rtmqs83m8", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp1vpuk0shj9v0y6dh64z858hh08q25kjcpuf09fw", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp1wt29em7nkmzjayk755cn0f2u563d2f9kxtluqc", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp1s9c2asqtp4f6r5k4jsg97p5yekqc6rhqqv7vky", + "coins": [ + { + "denom": "nhash", + "amount": "100000000000000000" + } + ] + }, + { + "address": "tp1jd9rpe6xwxkvmzu4lklpef5qla6tzxxd7g3j5s", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp1kmaut7y3psh46lw53hgm4967zfxpq5ls2m2w7v", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp16hyrvw2905fkyjp66t46hua6thctu5d54as6n5", + "coins": [ + { + "denom": "nhash", + "amount": "100000000000000000" + } + ] + }, + { + "address": "tp1mhspjegunfnlac6cayd4uf5uvz3wfnymwy4p3t", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp1a5r00sn57g3efsk76lgj7mnyswjv09lljvjjz0", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + }, + { + "address": "tp1l4qpmuh2du6x9zrwfxe0yxwd9jmaqheztmftu8", + "coins": [ + { + "denom": "nhash", + "amount": "10000000000000000" + } + ] + } + ], + "supply": [], + "denom_metadata": [] + }, + "capability": { + "index": "1", + "owners": [] + }, + "crisis": { + "constant_fee": { + "denom": "nhash", + "amount": "1000" + } + }, + "distribution": { + "params": { + "community_tax": "0.020000000000000000", + "base_proposer_reward": "0.010000000000000000", + "bonus_proposer_reward": "0.040000000000000000", + "withdraw_addr_enabled": true + }, + "fee_pool": { + "community_pool": [] + }, + "delegator_withdraw_infos": [], + "previous_proposer": "", + "outstanding_rewards": [], + "validator_accumulated_commissions": [], + "validator_historical_rewards": [], + "validator_current_rewards": [], + "delegator_starting_infos": [], + "validator_slash_events": [] + }, + "evidence": { + "evidence": [] + }, + "genutil": { + "gen_txs": [ + { + "body": { + "messages": [ + { + "@type": "/cosmos.staking.v1beta1.MsgCreateValidator", + "description": { + "moniker": "validator-us-central1-0", + "identity": "", + "website": "https://figure.com", + "security_contact": "security@figure.com", + "details": "Figure's validator" + }, + "commission": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "min_self_delegation": "1", + "delegator_address": "tp16hyrvw2905fkyjp66t46hua6thctu5d54as6n5", + "validator_address": "tpvaloper16hyrvw2905fkyjp66t46hua6thctu5d525dwx3", + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "RF5q1uL0trmfMzdlVdCzfmCTcnXRRx02S5UihlNVsnQ=" + }, + "value": { + "denom": "nhash", + "amount": "100000000000000000" + } + } + ], + "memo": "04cf5772acaace2bb493114cff22d0f289ca61ee@10.20.20.10:26656", + "timeout_height": "0", + "extension_options": [], + "non_critical_extension_options": [] + }, + "auth_info": { + "signer_infos": [ + { + "public_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "AoKGDcOSzMNZeqj4JKqR74mm/zhaJxNUsapoF3z40a++" + }, + "mode_info": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "0" + } + ], + "fee": { + "amount": [], + "gas_limit": "200000", + "payer": "", + "granter": "" + } + }, + "signatures": [ + "RU/k8jy3cj4x86hLbfBRy5U/XwvHeR0Rd988KqOnOesVH4LhVDNmjnKAgH5JeaulGn0zpQADUJPA8GJ2VTcRKg==" + ] + }, + { + "body": { + "messages": [ + { + "@type": "/cosmos.staking.v1beta1.MsgCreateValidator", + "description": { + "moniker": "validator-us-east4-0", + "identity": "", + "website": "https://figure.com", + "security_contact": "security@figure.com", + "details": "Figure's validator" + }, + "commission": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "min_self_delegation": "1", + "delegator_address": "tp1x299m72h6n88sswg2p9fp8lvkhrtqsvvnc7j9g", + "validator_address": "tpvaloper1x299m72h6n88sswg2p9fp8lvkhrtqsvvv3rxsd", + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "ynN46KrMfGdSvaT7jam8c+qVxyBHyuLhIT+dRLZufk0=" + }, + "value": { + "denom": "nhash", + "amount": "100000000000000000" + } + } + ], + "memo": "30e1160011bfd71e2cde7031c9d441368ee8fe7a@10.40.20.10:26656", + "timeout_height": "0", + "extension_options": [], + "non_critical_extension_options": [] + }, + "auth_info": { + "signer_infos": [ + { + "public_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "Aoa9sMY4LLYmegd+FxcFachEfK2wxczWhve9NR85RIU6" + }, + "mode_info": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "0" + } + ], + "fee": { + "amount": [], + "gas_limit": "200000", + "payer": "", + "granter": "" + } + }, + "signatures": [ + "paYhU5azkwJSma9sN/EEvzKeOIccVPhFRvYWsUs+Sxs3oxdAwxc7+Qias8J2SCIuU5wGBUQ34JV/8YILHaScHw==" + ] + }, + { + "body": { + "messages": [ + { + "@type": "/cosmos.staking.v1beta1.MsgCreateValidator", + "description": { + "moniker": "validator-us-east1-0", + "identity": "", + "website": "https://figure.com", + "security_contact": "security@figure.com", + "details": "Figure's validator" + }, + "commission": { + "rate": "1.000000000000000000", + "max_rate": "1.000000000000000000", + "max_change_rate": "1.000000000000000000" + }, + "min_self_delegation": "1", + "delegator_address": "tp1tgq6cpu6hmsrvkvdu82j99tsxxw7qqajvwg9uu", + "validator_address": "tpvaloper1tgq6cpu6hmsrvkvdu82j99tsxxw7qqajn843fe", + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "LzdJZx+EMMiqr1dyOJ4lzCRzuqOnVEdOGnwu1zeBwZw=" + }, + "value": { + "denom": "nhash", + "amount": "100000000000000000" + } + } + ], + "memo": "98f9904846f0f65b1343915e79653536981c0072@10.30.20.10:26656", + "timeout_height": "0", + "extension_options": [], + "non_critical_extension_options": [] + }, + "auth_info": { + "signer_infos": [ + { + "public_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "A3xWNZdmLGuLCdbGozUg8nS6C8M5NtrvwEFO9bsEpoV4" + }, + "mode_info": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "0" + } + ], + "fee": { + "amount": [], + "gas_limit": "200000", + "payer": "", + "granter": "" + } + }, + "signatures": [ + "PIrfXZzGV43ro8MmKx6P6UsN+vGX4lKW6I1hEehw1XMnXDzItkMKclyjekYB4hEgTIHYnhhSTkSbwV9/gzXFwQ==" + ] + }, + { + "body": { + "messages": [ + { + "@type": "/cosmos.staking.v1beta1.MsgCreateValidator", + "description": { + "moniker": "validator-us-west1-0", + "identity": "", + "website": "https://figure.com", + "security_contact": "security@figure.com", + "details": "Figure's validator" + }, + "commission": { + "rate": "0.100000000000000000", + "max_rate": "0.200000000000000000", + "max_change_rate": "0.010000000000000000" + }, + "min_self_delegation": "1", + "delegator_address": "tp1s9c2asqtp4f6r5k4jsg97p5yekqc6rhqqv7vky", + "validator_address": "tpvaloper1s9c2asqtp4f6r5k4jsg97p5yekqc6rhql9rcrp", + "pubkey": { + "@type": "/cosmos.crypto.ed25519.PubKey", + "key": "45H2v0QgaOGwNkjCD3wC9LsDqOohllJqRW8I9h77no8=" + }, + "value": { + "denom": "nhash", + "amount": "100000000000000000" + } + } + ], + "memo": "ce3826bd25a71990769477392daddcf315baac79@10.10.20.10:26656", + "timeout_height": "0", + "extension_options": [], + "non_critical_extension_options": [] + }, + "auth_info": { + "signer_infos": [ + { + "public_key": { + "@type": "/cosmos.crypto.secp256k1.PubKey", + "key": "AzJlis4I25/oYSAbbOWJC0ScRmFKa567CtC9Za9lkoTd" + }, + "mode_info": { + "single": { + "mode": "SIGN_MODE_DIRECT" + } + }, + "sequence": "0" + } + ], + "fee": { + "amount": [], + "gas_limit": "200000", + "payer": "", + "granter": "" + } + }, + "signatures": [ + "5vIALoD7h4Lf5azMXxauh87WjxfLI0pf1mPKzLVV7u1NtNbNO3bldfSqij6y4D9Nojt7Bl1tEt/+W70NDoIN/g==" + ] + } + ] + }, + "gov": { + "starting_proposal_id": "1", + "deposits": [], + "votes": [], + "proposals": [], + "deposit_params": { + "min_deposit": [ + { + "denom": "nhash", + "amount": "10000000" + } + ], + "max_deposit_period": "172800s" + }, + "voting_params": { + "voting_period": "172800s" + }, + "tally_params": { + "quorum": "0.334000000000000000", + "threshold": "0.500000000000000000", + "veto_threshold": "0.334000000000000000" + } + }, + "ibc": { + "client_genesis": { + "clients": [], + "clients_consensus": [], + "clients_metadata": [], + "params": { + "allowed_clients": [ + "06-solomachine", + "07-tendermint" + ] + }, + "create_localhost": false, + "next_client_sequence": "0" + }, + "connection_genesis": { + "connections": [], + "client_connection_paths": [], + "next_connection_sequence": "0" + }, + "channel_genesis": { + "channels": [], + "acknowledgements": [], + "commitments": [], + "receipts": [], + "send_sequences": [], + "recv_sequences": [], + "ack_sequences": [], + "next_channel_sequence": "0" + } + }, + "marker": { + "params": { + "max_total_supply": "100000000000", + "enable_governance": true + }, + "markers": [] + }, + "metadata": { + "params": {}, + "scopes": [], + "sessions": [], + "records": [], + "scope_specifications": [], + "contract_specifications": [], + "record_specifications": [] + }, + "mint": { + "minter": { + "inflation": "0.000000000000000000", + "annual_provisions": "1.000000000000000000" + }, + "params": { + "mint_denom": "nhash", + "inflation_rate_change": "1.000000000000000000", + "inflation_max": "0.000000000000000000", + "inflation_min": "0.000000000000000000", + "goal_bonded": "1.000000000000000000", + "blocks_per_year": "6311520" + } + }, + "name": { + "params": { + "max_segment_length": 32, + "min_segment_length": 2, + "max_name_levels": 16, + "allow_unrestricted_names": true + }, + "bindings": [ + { + "name": "provenance", + "address": "tp1s9c2asqtp4f6r5k4jsg97p5yekqc6rhqqv7vky", + "restricted": true + }, + { + "name": "pb", + "address": "tp1s9c2asqtp4f6r5k4jsg97p5yekqc6rhqqv7vky", + "restricted": false + } + ] + }, + "params": null, + "slashing": { + "params": { + "signed_blocks_window": "100", + "min_signed_per_window": "0.500000000000000000", + "downtime_jail_duration": "600s", + "slash_fraction_double_sign": "0.050000000000000000", + "slash_fraction_downtime": "0.010000000000000000" + }, + "signing_infos": [], + "missed_blocks": [] + }, + "staking": { + "params": { + "unbonding_time": "1814400s", + "max_validators": 100, + "max_entries": 7, + "historical_entries": 10000, + "bond_denom": "nhash" + }, + "last_total_power": "0", + "last_validator_powers": [], + "validators": [], + "delegations": [], + "unbonding_delegations": [], + "redelegations": [], + "exported": false + }, + "transfer": { + "port_id": "transfer", + "denom_traces": [], + "params": { + "send_enabled": true, + "receive_enabled": true + } + }, + "upgrade": {}, + "vesting": {}, + "wasm": { + "params": { + "code_upload_access": { + "permission": "Everybody", + "address": "" + }, + "instantiate_default_permission": "Everybody", + "max_wasm_code_size": "614400" + }, + "codes": [], + "contracts": [], + "sequences": [], + "gen_msgs": [] + } + } + } + } +}