forked from cerc-io/cosmos-explorer
add state-sync and cosmwasm
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import { BaseRestClient } from "@/libs/client";
|
||||
import { adapter, type AbstractRegistry, type Request } from "@/libs/registry";
|
||||
import type { PaginabledAccounts } from "@/types";
|
||||
import { defineStore } from "pinia";
|
||||
import type { CodeInfo, PaginabledCodeInfos, PaginabledContractHistory, PaginabledContracts, PaginabledStates, WasmParam } from "./types";
|
||||
import { toBase64 } from "@cosmjs/encoding";
|
||||
import { useBlockchain } from "@/stores";
|
||||
|
||||
export interface WasmRequestRegistry extends AbstractRegistry {
|
||||
cosmwasm_code: Request<PaginabledCodeInfos>;
|
||||
cosmwasm_code_id: Request<CodeInfo>;
|
||||
cosmwasm_code_id_contracts: Request<PaginabledContracts>;
|
||||
cosmwasm_param: Request<WasmParam>;
|
||||
cosmwasm_contract_address: Request<any>;
|
||||
cosmwasm_contract_address_history: Request<PaginabledContractHistory>;
|
||||
cosmwasm_contract_address_raw_query_data: Request<any>;
|
||||
cosmwasm_contract_address_smart_query_data: Request<any>;
|
||||
cosmwasm_contract_address_state: Request<PaginabledStates>;
|
||||
}
|
||||
|
||||
export const DEFAULT: WasmRequestRegistry = {
|
||||
cosmwasm_code: { url: "/cosmwasm/wasm/v1/code", adapter },
|
||||
cosmwasm_code_id: { url: "/cosmwasm/wasm/v1/code/{code_id}", adapter },
|
||||
cosmwasm_code_id_contracts: { url: "/cosmwasm/wasm/v1/code/{code_id}/contracts", adapter },
|
||||
cosmwasm_param: { url: "/cosmwasm/wasm/v1/codes/params", adapter },
|
||||
cosmwasm_contract_address: { url: "/cosmwasm/wasm/v1/contract/{address}", adapter },
|
||||
cosmwasm_contract_address_history: { url: "/cosmwasm/wasm/v1/contract/{address}/history", adapter },
|
||||
cosmwasm_contract_address_raw_query_data: { url: "/cosmwasm/wasm/v1/contract/{address}/raw/{query_data}", adapter },
|
||||
cosmwasm_contract_address_smart_query_data: { url: "/cosmwasm/wasm/v1/contract/{address}/smart/{query_data}", adapter },
|
||||
cosmwasm_contract_address_state: { url: "/cosmwasm/wasm/v1/contract/{address}/state", adapter }
|
||||
}
|
||||
|
||||
class WasmRestClient extends BaseRestClient<WasmRequestRegistry> {
|
||||
getWasmCodeList() {
|
||||
return this.request(this.registry.cosmwasm_code, {})
|
||||
}
|
||||
getWasmCodeById(code_id: string) {
|
||||
return this.request(this.registry.cosmwasm_code, {code_id}) // `code_id` is a param in above url
|
||||
}
|
||||
getWasmCodeContracts(code_id: string) {
|
||||
return this.request(this.registry.cosmwasm_code_id_contracts, {code_id})
|
||||
}
|
||||
getWasmParams() {
|
||||
return this.request(this.registry.cosmwasm_param, {})
|
||||
}
|
||||
getWasmContracts(address: string) {
|
||||
return this.request(this.registry.cosmwasm_contract_address, {address})
|
||||
}
|
||||
getWasmContractHistory(address: string) {
|
||||
return this.request(this.registry.cosmwasm_contract_address_history, {address})
|
||||
}
|
||||
getWasmContractRawQuery(address: string, query: string) {
|
||||
const query_data = toBase64(new TextEncoder().encode(query))
|
||||
return this.request(this.registry.cosmwasm_contract_address_raw_query_data, {address, query_data})
|
||||
}
|
||||
getWasmContractSmartQuery(address: string, query: string) {
|
||||
const query_data = toBase64(new TextEncoder().encode(query))
|
||||
return this.request(this.registry.cosmwasm_contract_address_smart_query_data, {address, query_data})
|
||||
}
|
||||
getWasmContractStates(address: string) {
|
||||
return this.request(this.registry.cosmwasm_contract_address_state, {address})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const useWasmStore = defineStore('module-wasm', {
|
||||
state: () => {
|
||||
return {}
|
||||
},
|
||||
getters: {
|
||||
wasmClient() {
|
||||
const blockchain = useBlockchain()
|
||||
return new WasmRestClient(blockchain.endpoint.address, DEFAULT)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -0,0 +1,32 @@
|
||||
<script lang="ts" setup>
|
||||
import { useBlockchain, useFormatter } from '@/stores';
|
||||
import { useWasmStore } from '../WasmStore';
|
||||
import { ref } from 'vue';
|
||||
import type { PaginabledCodeInfos, PaginabledContracts } from '../types';
|
||||
|
||||
const props = defineProps(['code_id', 'chain', ])
|
||||
|
||||
const response = ref({} as PaginabledContracts)
|
||||
|
||||
const wasmStore = useWasmStore()
|
||||
wasmStore.wasmClient.getWasmCodeContracts(props.code_id).then(x =>{
|
||||
response.value = x
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<VCard>
|
||||
<VCardTitle>Contract List of Code: {{ props.code_id }}</VCardTitle>
|
||||
<VTable>
|
||||
<thead>
|
||||
<tr><th>Contract List</th><th>Actions</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="v in response.contracts">
|
||||
<td>{{ v }}</td><td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
</VCard>
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,43 @@
|
||||
<script lang="ts" setup>
|
||||
import { useBlockchain, useFormatter } from '@/stores';
|
||||
import { useWasmStore } from './WasmStore';
|
||||
import { ref } from 'vue';
|
||||
import type { PaginabledCodeInfos } from './types';
|
||||
|
||||
const props = defineProps(['chain'])
|
||||
|
||||
const codes = ref({} as PaginabledCodeInfos)
|
||||
|
||||
const wasmStore = useWasmStore()
|
||||
wasmStore.wasmClient.getWasmCodeList().then(x =>{
|
||||
codes.value = x
|
||||
})
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<VCard>
|
||||
<VCardTitle>Cosmos Wasm</VCardTitle>
|
||||
<VTable>
|
||||
<thead>
|
||||
<tr><th>Code Id</th><th>Creator</th><th>Code Hash</th><th>Permissions</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="v in codes.code_infos">
|
||||
<td>{{ v.code_id }}</td>
|
||||
<td>{{ v.creator }}</td>
|
||||
<td><RouterLink :to="`/${props.chain}/cosmwasm/${v.code_id}/contracts`"><div class="text-truncate" style="max-width: 200px;">{{ v.data_hash }}</div></RouterLink></td>
|
||||
<td>{{ v.instantiate_permission }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</VTable>
|
||||
</VCard>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<route>
|
||||
{
|
||||
meta: {
|
||||
i18n: 'cosmwasm'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
@@ -0,0 +1,53 @@
|
||||
import type { PaginatedResponse } from "@/types"
|
||||
|
||||
export interface CodeInfo {
|
||||
code_id: string,
|
||||
creator: string,
|
||||
data_hash: string,
|
||||
instantiate_permission: {
|
||||
permission: string,
|
||||
address: string,
|
||||
addresses: string[]
|
||||
}
|
||||
}
|
||||
|
||||
export interface WasmParam {
|
||||
params: {
|
||||
code_upload_access: {
|
||||
permission: string,
|
||||
address: string,
|
||||
addresses: string[]
|
||||
},
|
||||
instantiate_default_permission: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface HistoryEntry {
|
||||
operation: string,
|
||||
code_id: string,
|
||||
updated: {
|
||||
block_height: string,
|
||||
tx_index: string
|
||||
},
|
||||
msg: string
|
||||
}
|
||||
|
||||
export interface Models {
|
||||
key: string,
|
||||
value: string
|
||||
}
|
||||
|
||||
export interface PaginabledContractHistory extends PaginatedResponse {
|
||||
entries: HistoryEntry[]
|
||||
}
|
||||
|
||||
export interface PaginabledStates extends PaginatedResponse {
|
||||
models: Models[]
|
||||
}
|
||||
|
||||
export interface PaginabledCodeInfos extends PaginatedResponse {
|
||||
code_infos: CodeInfo[]
|
||||
}
|
||||
export interface PaginabledContracts extends PaginatedResponse {
|
||||
contracts: string[]
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<script lang="ts" setup>
|
||||
import { useBaseStore, useBlockchain, useFormatter } from '@/stores';
|
||||
import type { NodeInfo } from '@/types';
|
||||
import { fromBase64, toHex } from '@cosmjs/encoding';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
const props = defineProps(['hash', 'chain'])
|
||||
const blockchain = useBlockchain()
|
||||
const base = useBaseStore()
|
||||
const nodeInfo = ref({} as NodeInfo)
|
||||
|
||||
const state = computed(()=> {
|
||||
const rpcs = blockchain.current?.endpoints?.rpc?.map(x => x.address).join(',')
|
||||
return `[statesync]
|
||||
enable = true
|
||||
rpc_servers = "${rpcs}"
|
||||
trust_height = ${base.latest.block?.header?.height || 'loading'}
|
||||
trust_hash = "${base.latest.block_id? toHex(fromBase64(base.latest.block_id?.hash)) : ''}"
|
||||
trust_period = "168h" # 2/3 of unbonding time"
|
||||
`
|
||||
})
|
||||
|
||||
const appName = computed(()=> {
|
||||
return nodeInfo.value.application_version?.app_name || "gaiad"
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
blockchain.rpc.getBaseNodeInfo().then(x => {
|
||||
console.log('node info', x)
|
||||
nodeInfo.value = x
|
||||
})
|
||||
})
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div>
|
||||
<VCard>
|
||||
<VCardTitle>What's State Sync?</VCardTitle>
|
||||
<VCardText>
|
||||
The Tendermint Core 0.34 release includes support for state sync, which allows a new node to join a network by fetching a snapshot of the application state at a recent height instead of fetching and replaying all historical blocks. This can reduce the time needed to sync with the network from days to minutes. Click <a class="text-primary" href="https://blog.cosmos.network/cosmos-sdk-state-sync-guide-99e4cf43be2f">here</a> for more infomation.
|
||||
</VCardText>
|
||||
</VCard>
|
||||
|
||||
<VCard class="my-5">
|
||||
<VCardTitle>Starting New Node From State Sync</VCardTitle>
|
||||
<VCardItem>
|
||||
1. Install Binary ({{ appName }} Version: {{ nodeInfo.application_version?.version || "" }})
|
||||
<br>
|
||||
We need to install the binary first and make sure that the version is the one currently in use on mainnet.
|
||||
<br>
|
||||
2. Enable State Sync<br>
|
||||
We can configure Tendermint to use state sync in $DAEMON_HOME/config/config.toml.
|
||||
<VTextarea auto-grow :model-value="state"></VTextarea>
|
||||
3. Start the daemon: <code>{{ appName }} start</code>
|
||||
<br/>
|
||||
If you are resetting node, run <code>{{ appName }} unsafe-reset-all</code> or <code>{{ appName }} tendermint unsafe-reset-all --home ~/.HOME</code> before you start the daemon.
|
||||
</VCardItem>
|
||||
</VCard>
|
||||
|
||||
<VCard>
|
||||
<VCardTitle>Enable Snapshot For State Sync</VCardTitle>
|
||||
<VCardItem>
|
||||
To make state sync works, we can enable snapshot in $DAEMON_HOME/config/app.toml
|
||||
<VTextarea auto-grow model-value="[state-sync]
|
||||
# snapshot-interval specifies the block interval at which local state sync snapshots are
|
||||
# taken (0 to disable). Must be a multiple of pruning-keep-every.
|
||||
snapshot-interval = 1000
|
||||
|
||||
# snapshot-keep-recent specifies the number of recent snapshots to keep and serve (0 to keep all). Each snapshot is about 500MiB
|
||||
snapshot-keep-recent = 2">
|
||||
|
||||
</VTextarea>
|
||||
</VCardItem>
|
||||
</VCard>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<route>
|
||||
{
|
||||
meta: {
|
||||
i18n: 'state-sync'
|
||||
}
|
||||
}
|
||||
</route>
|
||||
Reference in New Issue
Block a user