From 8e4f4ba72a480bc8c5b8128674e81ef4f09a77b0 Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 4 Mar 2024 09:55:30 +1300 Subject: [PATCH 01/81] add kyve support, add matching tests --- packages/node/package.json | 2 + packages/node/src/utils/cosmos.ts | 1 + packages/node/src/utils/kyve.spec.ts | 77 +++++++++++ packages/node/src/utils/kyve.ts | 183 +++++++++++++++++++++++++++ 4 files changed, 263 insertions(+) create mode 100644 packages/node/src/utils/kyve.spec.ts create mode 100644 packages/node/src/utils/kyve.ts diff --git a/packages/node/package.json b/packages/node/package.json index 62e9fc0b8..ea086b15d 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -23,6 +23,8 @@ "@cosmjs/cosmwasm-stargate": "^0.32.3", "@cosmjs/proto-signing": "^0.32.3", "@cosmjs/stargate": "^0.32.3", + "@kyvejs/protocol": "^1.0.12", + "@kyvejs/sdk": "^1.1.1", "@nestjs/common": "^9.4.0", "@nestjs/core": "^9.4.0", "@nestjs/event-emitter": "^2.0.0", diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index 608d2d2d0..e95684593 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -334,6 +334,7 @@ export async function fetchBlocksBatches( blockArray: number[], ): Promise[]> { const blocks = await fetchCosmosBlocksArray(api, blockArray); + // todo add kyve support here return blocks.map(([blockInfo, blockResults]) => { try { assert( diff --git a/packages/node/src/utils/kyve.spec.ts b/packages/node/src/utils/kyve.spec.ts new file mode 100644 index 000000000..4732c3020 --- /dev/null +++ b/packages/node/src/utils/kyve.spec.ts @@ -0,0 +1,77 @@ +// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import { Tendermint37Client } from '@cosmjs/tendermint-rpc'; +import { isEqual } from 'lodash'; +import { HttpClient } from '../indexer/rpc-clients'; +import { KyveApi } from './kyve'; + +jest.setTimeout(100000); +describe('KyveClient', () => { + let kyveApi: KyveApi; + beforeAll(async () => { + kyveApi = new KyveApi('archway-1'); + await kyveApi.init(); + }); + + it('ensure correct bundle ID on binary search', async () => { + const a = Date.now(); + const v = await (kyveApi as any).getBundleId(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 + const b = Date.now(); + console.log(`${b - a}ms`); + expect(v).toBe(113773); + }); + it('block structure matches tendermint37 client', async () => { + const client = new HttpClient('https://rpc.mainnet.archway.io:443'); + const tendermint = await Tendermint37Client.create(client); + const height = 3489747; + + const [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ + tendermint.block(height), + tendermint.blockResults(height), + ]); + const [kyveBlockInfo, kyveBlockResult] = await kyveApi.getBlockByHeight( + height, + ); + + expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); + + // Note: block result will fail on expect due to deep nested array order being wrong + expect( + tendermintBlockResult.beginBlockEvents[4].attributes.find( + (a) => a.key === 'c2VuZGVy', + ), + ).toEqual( + kyveBlockResult.beginBlockEvents[4].attributes.find( + (a) => a.key === 'c2VuZGVy', + ), + ); + expect( + isEqual( + tendermintBlockResult.consensusUpdates, + kyveBlockResult.consensusUpdates, + ), + ).toBe(true); + expect(tendermintBlockResult.results.length).toBe( + kyveBlockResult.results.length, + ); + expect(tendermintBlockResult.validatorUpdates.length).toBe( + kyveBlockResult.validatorUpdates.length, + ); + expect(tendermintBlockResult.height).toBe(kyveBlockResult.height); + + expect( + tendermintBlockResult.endBlockEvents[2].attributes.find( + (a) => a.key === 'cmVjaXBpZW50', + ), + ).toEqual( + kyveBlockResult.endBlockEvents[2].attributes.find( + (a) => a.key === 'cmVjaXBpZW50', + ), + ); + }); + it('determine correct pool', () => { + expect((kyveApi as any).poolId).toBe('2'); + expect((kyveApi as any).chainId).toBe('archway-1'); + }); +}); diff --git a/packages/node/src/utils/kyve.ts b/packages/node/src/utils/kyve.ts new file mode 100644 index 000000000..7d20ff7de --- /dev/null +++ b/packages/node/src/utils/kyve.ts @@ -0,0 +1,183 @@ +// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import { adaptor37 } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; +import { + BlockResponse, + BlockResultsResponse, +} from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; +import { Gzip } from '@kyvejs/protocol/dist/src/reactors/compression/Gzip'; +import { Arweave } from '@kyvejs/protocol/dist/src/reactors/storageProviders/Arweave'; +import { Bundlr } from '@kyvejs/protocol/dist/src/reactors/storageProviders/Bundlr'; +import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; +import { SupportedChains } from '@kyvejs/sdk/src/constants'; + +const BUNDLE_TIMEOUT = 10000; //ms + +export class KyveApi { + private lcdClient: KyveLCDClientType; + private respAdaptor = adaptor37.responses; + private poolId: string; + private currentBundleId = 1; + // add a mem array for the unzipped data + + constructor( + private chainId: string, + kyveChainId: SupportedChains = 'kyve-1', + ) { + this.lcdClient = new KyveSDK(kyveChainId).createLCDClient(); + } + async init(): Promise { + this.currentBundleId = 1; // should be start key provided by the pool + await this.setPoolId(); + } + private async getAllPools() { + return this.lcdClient.kyve.query.v1beta1.pools(); + } + + private async setPoolId(): Promise { + const pools = await this.getAllPools(); + const pool = pools.pools.find( + (p) => JSON.parse(p.data.config).network === this.chainId, + ); + if (!pool) { + throw new Error(`${this.chainId} is not available on Kyve network`); + } + this.poolId = pool.id; + } + + // FinalizedBundle from kyve is not correct + private async retrieveBundleData( + bundleResponse: any, + ): Promise<{ storageId: string; storageData: any }> { + let data: { storageId: string; storageData: any }; + const { storage_id, storage_provider_id } = bundleResponse; + + if (storage_provider_id === '0') { + throw new Error('No storage, no existing stored data'); + } + + if (storage_provider_id === '1') { + // todo temp storage priv + data = await new Arweave('1').retrieveBundle(storage_id, BUNDLE_TIMEOUT); + } + + if (storage_provider_id === '2') { + // todo temp storage priv + data = await new Bundlr('1').retrieveBundle(storage_id, BUNDLE_TIMEOUT); + } + return data; + } + + private async unzipStorageData( + compressionId: string, + storageData: any, + ): Promise { + const g = new Gzip(); + if (parseInt(compressionId) === 0) { + throw new Error('No Compression'); + } + + const buffer = await g.decompress(storageData); + const parsedString = buffer.toString('utf-8'); + + return JSON.parse(parsedString); + } + + private decodeBlock(block: any) { + return this.respAdaptor.decodeBlock({ + id: 10, + jsonrpc: '2.0', + result: block, + }); + } + + private decodeBlockResult(blockResult: any) { + return this.respAdaptor.decodeBlockResults({ + id: 10, + jsonrpc: '2.0', + result: blockResult, + }); + } + + // TODO types + private async getBundleById(bundleId: string): Promise { + return this.lcdClient.kyve.query.v1beta1.finalizedBundle({ + pool_id: this.poolId, + id: bundleId, + }); + } + + private async getLatestBundleId() { + // TODO see if there is a better query that can get bundle total + return ( + await this.lcdClient.kyve.query.v1beta1.finalizedBundles({ + pool_id: this.poolId, + index: '160', // useless field kyve has wrong typing + pagination: { + limit: '1', + }, + }) + ).pagination.total; + } + + // TODO should use this for binary search to improve performance + private async getBundles(key?: string, offset?: string) { + return this.lcdClient.kyve.query.v1beta1.finalizedBundles({ + pool_id: this.poolId, + index: '160', // useless field kyve has wrong typing + pagination: { + key: key, + offset: offset, + }, + }); + } + private async getBundleId(height: number) { + // TODO use pagination instead + const latestBundleId = parseInt(await this.getLatestBundleId()); + + let low = this.currentBundleId; + let high = latestBundleId; + let startBundleId = -1; // Initialize to an invalid ID initially + + while (low <= high) { + const mid = Math.floor((low + high) / 2); + const midBundle = await this.getBundleById(mid.toString()); // You'll need to implement this method + + const fromKey = parseInt(midBundle.from_key); + const toKey = parseInt(midBundle.to_key); + + if (height > toKey) { + low = mid + 1; + } else if (height < fromKey) { + high = mid - 1; + } else { + startBundleId = mid; + break; + } + } + + this.currentBundleId = startBundleId; + return startBundleId; + } + + async getBlockByHeight( + height: number, + ): Promise<[BlockResponse, BlockResultsResponse]> { + const bundleId = await this.getBundleId(height); + const rawBundle = await this.getBundleById(bundleId.toString()); + const bundleData = await this.retrieveBundleData(rawBundle); + + const blockData = ( + await this.unzipStorageData( + rawBundle.compression_id, + bundleData.storageData, + ) + ).find((bk: { value: any; key: string }) => bk.key === height.toString()); + + return [ + this.decodeBlock(blockData.value.block), + this.decodeBlockResult(blockData.value.block_results), + ]; + } +} From 9ab621dfd1803579bd602652ba9331e9ecf826eb Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 4 Mar 2024 15:15:39 +1300 Subject: [PATCH 02/81] update comments --- packages/node/src/utils/kyve.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/utils/kyve.ts b/packages/node/src/utils/kyve.ts index 7d20ff7de..4b0c0baa5 100644 --- a/packages/node/src/utils/kyve.ts +++ b/packages/node/src/utils/kyve.ts @@ -19,7 +19,7 @@ export class KyveApi { private respAdaptor = adaptor37.responses; private poolId: string; private currentBundleId = 1; - // add a mem array for the unzipped data + // TODO in memory unzipped blocks constructor( private chainId: string, From 5938615bee5048cb85654abde2d5c4ec1bdd19e1 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 5 Mar 2024 00:59:24 +1300 Subject: [PATCH 03/81] add typing and add cached blocks --- packages/node/src/utils/kyve.spec.ts | 5 +++ packages/node/src/utils/kyve.ts | 64 ++++++++++++++++++---------- 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/packages/node/src/utils/kyve.spec.ts b/packages/node/src/utils/kyve.spec.ts index 4732c3020..7833c2b55 100644 --- a/packages/node/src/utils/kyve.spec.ts +++ b/packages/node/src/utils/kyve.spec.ts @@ -14,6 +14,11 @@ describe('KyveClient', () => { await kyveApi.init(); }); + it('getBundleById', async () => { + const v = await (kyveApi as any).getBundleById('113773'); + console.log(v); + }); + it('ensure correct bundle ID on binary search', async () => { const a = Date.now(); const v = await (kyveApi as any).getBundleId(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 diff --git a/packages/node/src/utils/kyve.ts b/packages/node/src/utils/kyve.ts index 4b0c0baa5..02221da58 100644 --- a/packages/node/src/utils/kyve.ts +++ b/packages/node/src/utils/kyve.ts @@ -1,6 +1,7 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 +import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; import { adaptor37 } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; import { BlockResponse, @@ -11,15 +12,22 @@ import { Arweave } from '@kyvejs/protocol/dist/src/reactors/storageProviders/Arw import { Bundlr } from '@kyvejs/protocol/dist/src/reactors/storageProviders/Bundlr'; import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; +import kyveQueryBundles from '@kyvejs/types/client/kyve/query/v1beta1/bundles'; const BUNDLE_TIMEOUT = 10000; //ms +interface UnZippedKyveBlockReponse { + // DataItem (if using kyve types) + value: { block: any; block_results: any }; + key: string; +} + export class KyveApi { private lcdClient: KyveLCDClientType; private respAdaptor = adaptor37.responses; private poolId: string; private currentBundleId = 1; - // TODO in memory unzipped blocks + private cachedBlocks: UnZippedKyveBlockReponse[]; constructor( private chainId: string, @@ -72,7 +80,7 @@ export class KyveApi { private async unzipStorageData( compressionId: string, storageData: any, - ): Promise { + ): Promise { const g = new Gzip(); if (parseInt(compressionId) === 0) { throw new Error('No Compression'); @@ -84,7 +92,7 @@ export class KyveApi { return JSON.parse(parsedString); } - private decodeBlock(block: any) { + private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { return this.respAdaptor.decodeBlock({ id: 10, jsonrpc: '2.0', @@ -92,7 +100,9 @@ export class KyveApi { }); } - private decodeBlockResult(blockResult: any) { + private decodeBlockResult( + blockResult: JsonRpcSuccessResponse, + ): BlockResultsResponse { return this.respAdaptor.decodeBlockResults({ id: 10, jsonrpc: '2.0', @@ -100,7 +110,7 @@ export class KyveApi { }); } - // TODO types + // TODO types kyveQueryBundles.QueryFinalizedBundleResponse, but I think the type is wrong private async getBundleById(bundleId: string): Promise { return this.lcdClient.kyve.query.v1beta1.finalizedBundle({ pool_id: this.poolId, @@ -108,8 +118,9 @@ export class KyveApi { }); } - private async getLatestBundleId() { + private async getLatestBundleId(): Promise { // TODO see if there is a better query that can get bundle total + // type: kyveQueryBundlesRes.QueryFinalizedBundlesResponse return ( await this.lcdClient.kyve.query.v1beta1.finalizedBundles({ pool_id: this.poolId, @@ -121,19 +132,9 @@ export class KyveApi { ).pagination.total; } - // TODO should use this for binary search to improve performance - private async getBundles(key?: string, offset?: string) { - return this.lcdClient.kyve.query.v1beta1.finalizedBundles({ - pool_id: this.poolId, - index: '160', // useless field kyve has wrong typing - pagination: { - key: key, - offset: offset, - }, - }); - } - private async getBundleId(height: number) { + private async getBundleId(height: number): Promise { // TODO use pagination instead + // TODO can cache the results here as well const latestBundleId = parseInt(await this.getLatestBundleId()); let low = this.currentBundleId; @@ -161,6 +162,12 @@ export class KyveApi { return startBundleId; } + private findBlockByHeight(height: number): UnZippedKyveBlockReponse { + return this.cachedBlocks.find( + (bk: UnZippedKyveBlockReponse) => bk.key === height.toString(), + ); + } + async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { @@ -168,16 +175,29 @@ export class KyveApi { const rawBundle = await this.getBundleById(bundleId.toString()); const bundleData = await this.retrieveBundleData(rawBundle); - const blockData = ( - await this.unzipStorageData( + if (!this.cachedBlocks) { + this.cachedBlocks = await this.unzipStorageData( rawBundle.compression_id, bundleData.storageData, - ) - ).find((bk: { value: any; key: string }) => bk.key === height.toString()); + ); + } + const blockData = this.findBlockByHeight(height); return [ this.decodeBlock(blockData.value.block), this.decodeBlockResult(blockData.value.block_results), ]; } + + // TODO should use this for binary search to improve performance + private async getBundles(key?: string, offset?: string) { + return this.lcdClient.kyve.query.v1beta1.finalizedBundles({ + pool_id: this.poolId, + index: '160', // useless field kyve has wrong typing + pagination: { + key: key, + offset: offset, + }, + }); + } } From bedd2c4e18aaf11f23c16fd76bcd391d3c5b079a Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 25 Mar 2024 19:09:15 +0800 Subject: [PATCH 04/81] fix up binary search, add tests --- packages/node/src/utils/cosmos.ts | 2 +- packages/node/src/utils/kyve.spec.ts | 94 +++++++++++++++++++++---- packages/node/src/utils/kyve.ts | 100 +++++++++++---------------- 3 files changed, 125 insertions(+), 71 deletions(-) diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index e95684593..6620a4854 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -355,7 +355,7 @@ export async function fetchBlocksBatches( }); } -class LazyBlockContent implements BlockContent { +export class LazyBlockContent implements BlockContent { private _wrappedBlock: CosmosBlock; private _wrappedTransaction: CosmosTransaction[]; private _wrappedMessage: CosmosMessage[]; diff --git a/packages/node/src/utils/kyve.spec.ts b/packages/node/src/utils/kyve.spec.ts index 7833c2b55..9b1c00869 100644 --- a/packages/node/src/utils/kyve.spec.ts +++ b/packages/node/src/utils/kyve.spec.ts @@ -1,32 +1,100 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 +import { GeneratedType, Registry } from '@cosmjs/proto-signing'; +import { defaultRegistryTypes } from '@cosmjs/stargate'; import { Tendermint37Client } from '@cosmjs/tendermint-rpc'; +import { + MsgClearAdmin, + MsgExecuteContract, + MsgInstantiateContract, + MsgMigrateContract, + MsgStoreCode, + MsgUpdateAdmin, +} from 'cosmjs-types/cosmwasm/wasm/v1/tx'; import { isEqual } from 'lodash'; +import { CosmosClient } from '../indexer/api.service'; import { HttpClient } from '../indexer/rpc-clients'; +import { LazyBlockContent } from './cosmos'; import { KyveApi } from './kyve'; jest.setTimeout(100000); describe('KyveClient', () => { let kyveApi: KyveApi; - beforeAll(async () => { + + it('getBundle by height', async () => { kyveApi = new KyveApi('archway-1'); await kyveApi.init(); + const v = await kyveApi.getBlockByHeight(3856726); + // todo expect // timing out + // expect(v).toEqual() }); - - it('getBundleById', async () => { - const v = await (kyveApi as any).getBundleById('113773'); - console.log(v); - }); - it('ensure correct bundle ID on binary search', async () => { + kyveApi = new KyveApi('archway-1'); + await kyveApi.init(); + const a = Date.now(); - const v = await (kyveApi as any).getBundleId(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 + const laterBundle = await (kyveApi as any).getBundleId(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 const b = Date.now(); console.log(`${b - a}ms`); - expect(v).toBe(113773); + + const firstBundle = await (kyveApi as any).getBundleId(120); // https://app.kyve.network/#/pools/2/bundles/0 + expect(firstBundle).toBe(0); + expect(laterBundle).toBe(113773); + }); + it('cosmos client with kyve', async () => { + kyveApi = new KyveApi('archway-1'); + await kyveApi.init(); + + const client = new HttpClient('https://rpc.mainnet.archway.io:443'); + const tendermint = await Tendermint37Client.create(client); + + const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ + ['/cosmwasm.wasm.v1.MsgClearAdmin', MsgClearAdmin], + ['/cosmwasm.wasm.v1.MsgExecuteContract', MsgExecuteContract], + ['/cosmwasm.wasm.v1.MsgMigrateContract', MsgMigrateContract], + ['/cosmwasm.wasm.v1.MsgStoreCode', MsgStoreCode], + ['/cosmwasm.wasm.v1.MsgInstantiateContract', MsgInstantiateContract], + ['/cosmwasm.wasm.v1.MsgUpdateAdmin', MsgUpdateAdmin], + ]; + const registry = new Registry([...defaultRegistryTypes, ...wasmTypes]); + const api = new CosmosClient(tendermint, registry); + // const height = 3489747; + const height = 1338; + // + const [kyveBlockInfo, kyveBlockResult] = await kyveApi.getBlockByHeight( + height, + ); + const [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ + tendermint.block(height), + tendermint.blockResults(height), + ]); + + const v = new LazyBlockContent(kyveBlockInfo, kyveBlockResult, api); + const tv = new LazyBlockContent( + tendermintBlockInfo, + tendermintBlockResult, + api, + ); + // TODO + }); + it('compare block info', async () => { + const height = 13885474; + + const client = new HttpClient('https://rpc.osmosis.zone:443'); + const tendermint = await Tendermint37Client.create(client); + + kyveApi = new KyveApi('osmosis-1'); + await kyveApi.init(); + + const tendermintBlockInfo = await tendermint.block(height); + const [kyveBlockInfo] = await kyveApi.getBlockByHeight(height); + expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); }); - it('block structure matches tendermint37 client', async () => { + it('compare block results', async () => { + kyveApi = new KyveApi('archway-1'); + await kyveApi.init(); + const client = new HttpClient('https://rpc.mainnet.archway.io:443'); const tendermint = await Tendermint37Client.create(client); const height = 3489747; @@ -42,9 +110,11 @@ describe('KyveClient', () => { expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); // Note: block result will fail on expect due to deep nested array order being wrong + // RPC uses base64 decoded, due to recent upgrade. + // However, kyve stores base64 encoded expect( tendermintBlockResult.beginBlockEvents[4].attributes.find( - (a) => a.key === 'c2VuZGVy', + (a) => a.key === 'sender', ), ).toEqual( kyveBlockResult.beginBlockEvents[4].attributes.find( @@ -67,7 +137,7 @@ describe('KyveClient', () => { expect( tendermintBlockResult.endBlockEvents[2].attributes.find( - (a) => a.key === 'cmVjaXBpZW50', + (a) => a.key === 'recipient', ), ).toEqual( kyveBlockResult.endBlockEvents[2].attributes.find( diff --git a/packages/node/src/utils/kyve.ts b/packages/node/src/utils/kyve.ts index 02221da58..64dad37c2 100644 --- a/packages/node/src/utils/kyve.ts +++ b/packages/node/src/utils/kyve.ts @@ -7,17 +7,16 @@ import { BlockResponse, BlockResultsResponse, } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; +// Currently these types are not exported import { Gzip } from '@kyvejs/protocol/dist/src/reactors/compression/Gzip'; import { Arweave } from '@kyvejs/protocol/dist/src/reactors/storageProviders/Arweave'; import { Bundlr } from '@kyvejs/protocol/dist/src/reactors/storageProviders/Bundlr'; import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; -import kyveQueryBundles from '@kyvejs/types/client/kyve/query/v1beta1/bundles'; -const BUNDLE_TIMEOUT = 10000; //ms +const BUNDLE_TIMEOUT = 100000; //ms interface UnZippedKyveBlockReponse { - // DataItem (if using kyve types) value: { block: any; block_results: any }; key: string; } @@ -26,7 +25,7 @@ export class KyveApi { private lcdClient: KyveLCDClientType; private respAdaptor = adaptor37.responses; private poolId: string; - private currentBundleId = 1; + private currentBundleId: number; private cachedBlocks: UnZippedKyveBlockReponse[]; constructor( @@ -36,7 +35,7 @@ export class KyveApi { this.lcdClient = new KyveSDK(kyveChainId).createLCDClient(); } async init(): Promise { - this.currentBundleId = 1; // should be start key provided by the pool + this.currentBundleId = 0; await this.setPoolId(); } private async getAllPools() { @@ -54,27 +53,24 @@ export class KyveApi { this.poolId = pool.id; } - // FinalizedBundle from kyve is not correct private async retrieveBundleData( bundleResponse: any, ): Promise<{ storageId: string; storageData: any }> { - let data: { storageId: string; storageData: any }; const { storage_id, storage_provider_id } = bundleResponse; - - if (storage_provider_id === '0') { - throw new Error('No storage, no existing stored data'); - } - - if (storage_provider_id === '1') { - // todo temp storage priv - data = await new Arweave('1').retrieveBundle(storage_id, BUNDLE_TIMEOUT); + switch (parseInt(storage_provider_id) ?? 0) { + case 0: + throw new Error('No storage, no existing stored data'); + case 1: + return new Arweave('1').retrieveBundle(storage_id, BUNDLE_TIMEOUT); + case 2: + return new Bundlr('1').retrieveBundle(storage_id, BUNDLE_TIMEOUT); + default: + throw new Error('Unsupported storage provider'); } + } - if (storage_provider_id === '2') { - // todo temp storage priv - data = await new Bundlr('1').retrieveBundle(storage_id, BUNDLE_TIMEOUT); - } - return data; + private async injectLogs() { + // TODO } private async unzipStorageData( @@ -110,32 +106,31 @@ export class KyveApi { }); } - // TODO types kyveQueryBundles.QueryFinalizedBundleResponse, but I think the type is wrong - private async getBundleById(bundleId: string): Promise { + private async getBundleById(bundleId: number): Promise { return this.lcdClient.kyve.query.v1beta1.finalizedBundle({ pool_id: this.poolId, - id: bundleId, + id: bundleId.toString(), }); } - private async getLatestBundleId(): Promise { - // TODO see if there is a better query that can get bundle total - // type: kyveQueryBundlesRes.QueryFinalizedBundlesResponse + private async getLatestBundleId(): Promise { return ( - await this.lcdClient.kyve.query.v1beta1.finalizedBundles({ - pool_id: this.poolId, - index: '160', // useless field kyve has wrong typing - pagination: { - limit: '1', - }, - }) - ).pagination.total; + parseInt( + ( + await this.lcdClient.kyve.query.v1beta1.finalizedBundles({ + pool_id: this.poolId, + index: '1', + pagination: { + limit: '1', + }, + }) + ).pagination.total, + ) - 1 + ); // bundle id starts from 0 } private async getBundleId(height: number): Promise { - // TODO use pagination instead - // TODO can cache the results here as well - const latestBundleId = parseInt(await this.getLatestBundleId()); + const latestBundleId = await this.getLatestBundleId(); let low = this.currentBundleId; let high = latestBundleId; @@ -143,23 +138,24 @@ export class KyveApi { while (low <= high) { const mid = Math.floor((low + high) / 2); - const midBundle = await this.getBundleById(mid.toString()); // You'll need to implement this method + const midBundle = await this.getBundleById(mid); const fromKey = parseInt(midBundle.from_key); const toKey = parseInt(midBundle.to_key); + if (height >= fromKey && height <= toKey) { + startBundleId = mid; + this.currentBundleId = startBundleId; + return startBundleId; + } + if (height > toKey) { low = mid + 1; - } else if (height < fromKey) { - high = mid - 1; } else { - startBundleId = mid; - break; + high = mid - 1; } } - - this.currentBundleId = startBundleId; - return startBundleId; + throw new Error('No suitable bundle found for the given height.'); } private findBlockByHeight(height: number): UnZippedKyveBlockReponse { @@ -172,7 +168,7 @@ export class KyveApi { height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { const bundleId = await this.getBundleId(height); - const rawBundle = await this.getBundleById(bundleId.toString()); + const rawBundle = await this.getBundleById(bundleId); const bundleData = await this.retrieveBundleData(rawBundle); if (!this.cachedBlocks) { @@ -188,16 +184,4 @@ export class KyveApi { this.decodeBlockResult(blockData.value.block_results), ]; } - - // TODO should use this for binary search to improve performance - private async getBundles(key?: string, offset?: string) { - return this.lcdClient.kyve.query.v1beta1.finalizedBundles({ - pool_id: this.poolId, - index: '160', // useless field kyve has wrong typing - pagination: { - key: key, - offset: offset, - }, - }); - } } From 460b7c67c344db4f5c91b7b639f1d0aef82d458c Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 25 Mar 2024 23:18:32 +0800 Subject: [PATCH 05/81] revert jest config changes --- jest.config.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jest.config.js b/jest.config.js index 8af1b601c..30d706e27 100644 --- a/jest.config.js +++ b/jest.config.js @@ -64,6 +64,11 @@ module.exports = { // A set of global variables that need to be available in all test environments // globals: {}, + globals: { + 'ts-jest': { + tsconfig: 'tsconfig.test.json', + }, + }, // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. // maxWorkers: "50%", @@ -176,12 +181,7 @@ module.exports = { // A map from regular expressions to paths to transformers transform: { - '^.+\\.(ts|tsx)?$': [ - 'ts-jest', - { - tsconfig: 'tsconfig.test.json' - } - ], + '^.+\\.(ts|tsx)?$': 'ts-jest', '^.+\\.(js|jsx)$': 'babel-jest', }, From c5511b7db2a5554586a8cec2419da45b14e2203e Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 25 Mar 2024 23:24:46 +0800 Subject: [PATCH 06/81] revert jest config chnages on bad rebase --- jest.config.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/jest.config.js b/jest.config.js index 30d706e27..8af1b601c 100644 --- a/jest.config.js +++ b/jest.config.js @@ -64,11 +64,6 @@ module.exports = { // A set of global variables that need to be available in all test environments // globals: {}, - globals: { - 'ts-jest': { - tsconfig: 'tsconfig.test.json', - }, - }, // The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers. // maxWorkers: "50%", @@ -181,7 +176,12 @@ module.exports = { // A map from regular expressions to paths to transformers transform: { - '^.+\\.(ts|tsx)?$': 'ts-jest', + '^.+\\.(ts|tsx)?$': [ + 'ts-jest', + { + tsconfig: 'tsconfig.test.json' + } + ], '^.+\\.(js|jsx)$': 'babel-jest', }, From 64ddf08d7338200aab458abd991fed9b6959c4c0 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 26 Mar 2024 12:49:17 +0800 Subject: [PATCH 07/81] wip on rebuild logs --- packages/node/src/indexer/api.service.ts | 18 ++++ packages/node/src/utils/cosmos.ts | 2 +- packages/node/src/utils/kyve.spec.ts | 117 ++++++++++------------- 3 files changed, 71 insertions(+), 66 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 5b7bf54e1..7d6ca6911 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -36,6 +36,7 @@ import { } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; import { SubqueryProject } from '../configure/SubqueryProject'; import * as CosmosUtil from '../utils/cosmos'; +import { KyveApi } from '../utils/kyve'; import { CosmosClientConnection } from './cosmosClient.connection'; import { BlockContent } from './types'; @@ -47,6 +48,7 @@ export class ApiService implements OnApplicationShutdown { private fetchBlocksBatches = CosmosUtil.fetchBlocksBatches; + private kyveClient: KyveApi; registry: Registry; constructor( @@ -138,8 +140,12 @@ export class ApiService return res; } } +// instead of using log, +// use events +// step 1. get rid of logs and use just events. export class CosmosClient extends CosmWasmClient { + private kyveClient: KyveApi; constructor( private readonly tendermintClient: Tendermint37Client, public registry: Registry, @@ -157,6 +163,18 @@ export class CosmosClient extends CosmWasmClient { } */ + // todo, a trigger for when kyve should used + async initKyveClient(chainId: string): Promise { + this.kyveClient = new KyveApi(chainId); + await this.kyveClient.init(); + } + + async kyveBlockByHeight( + height: number, + ): Promise<[BlockResponse, BlockResultsResponse]> { + return this.kyveClient.getBlockByHeight(height); + } + // eslint-disable-next-line @typescript-eslint/require-await async blockInfo(height?: number): Promise { return this.tendermintClient.block(height); diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index 6620a4854..fd532a1c0 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -184,6 +184,7 @@ export async function fetchCosmosBlocksArray( api: CosmosClient, blockArray: number[], ): Promise<[BlockResponse, BlockResultsResponse][]> { + // todo this is where kyve introduction should be. return Promise.all( blockArray.map(async (height) => getBlockByHeight(api, height)), ); @@ -334,7 +335,6 @@ export async function fetchBlocksBatches( blockArray: number[], ): Promise[]> { const blocks = await fetchCosmosBlocksArray(api, blockArray); - // todo add kyve support here return blocks.map(([blockInfo, blockResults]) => { try { assert( diff --git a/packages/node/src/utils/kyve.spec.ts b/packages/node/src/utils/kyve.spec.ts index 9b1c00869..f4349c920 100644 --- a/packages/node/src/utils/kyve.spec.ts +++ b/packages/node/src/utils/kyve.spec.ts @@ -21,18 +21,21 @@ import { KyveApi } from './kyve'; jest.setTimeout(100000); describe('KyveClient', () => { let kyveApi: KyveApi; + let tendermint: Tendermint37Client; - it('getBundle by height', async () => { + beforeAll(async () => { kyveApi = new KyveApi('archway-1'); await kyveApi.init(); + const client = new HttpClient('https://rpc.mainnet.archway.io:443'); + tendermint = await Tendermint37Client.create(client); + }); + + it('getBundle by height', async () => { const v = await kyveApi.getBlockByHeight(3856726); // todo expect // timing out // expect(v).toEqual() }); it('ensure correct bundle ID on binary search', async () => { - kyveApi = new KyveApi('archway-1'); - await kyveApi.init(); - const a = Date.now(); const laterBundle = await (kyveApi as any).getBundleId(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 const b = Date.now(); @@ -43,12 +46,6 @@ describe('KyveClient', () => { expect(laterBundle).toBe(113773); }); it('cosmos client with kyve', async () => { - kyveApi = new KyveApi('archway-1'); - await kyveApi.init(); - - const client = new HttpClient('https://rpc.mainnet.archway.io:443'); - const tendermint = await Tendermint37Client.create(client); - const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ ['/cosmwasm.wasm.v1.MsgClearAdmin', MsgClearAdmin], ['/cosmwasm.wasm.v1.MsgExecuteContract', MsgExecuteContract], @@ -79,71 +76,61 @@ describe('KyveClient', () => { // TODO }); it('compare block info', async () => { - const height = 13885474; - - const client = new HttpClient('https://rpc.osmosis.zone:443'); - const tendermint = await Tendermint37Client.create(client); - - kyveApi = new KyveApi('osmosis-1'); - await kyveApi.init(); + // todo, use a archway block + const height = 13885474; const tendermintBlockInfo = await tendermint.block(height); const [kyveBlockInfo] = await kyveApi.getBlockByHeight(height); expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); }); it('compare block results', async () => { - kyveApi = new KyveApi('archway-1'); - await kyveApi.init(); - - const client = new HttpClient('https://rpc.mainnet.archway.io:443'); - const tendermint = await Tendermint37Client.create(client); + // bundleId: 113773 const height = 3489747; - - const [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ - tendermint.block(height), - tendermint.blockResults(height), - ]); + // const [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ + // tendermint.block(height), + // tendermint.blockResults(height), + // ]); const [kyveBlockInfo, kyveBlockResult] = await kyveApi.getBlockByHeight( height, ); - - expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); - - // Note: block result will fail on expect due to deep nested array order being wrong - // RPC uses base64 decoded, due to recent upgrade. - // However, kyve stores base64 encoded - expect( - tendermintBlockResult.beginBlockEvents[4].attributes.find( - (a) => a.key === 'sender', - ), - ).toEqual( - kyveBlockResult.beginBlockEvents[4].attributes.find( - (a) => a.key === 'c2VuZGVy', - ), - ); - expect( - isEqual( - tendermintBlockResult.consensusUpdates, - kyveBlockResult.consensusUpdates, - ), - ).toBe(true); - expect(tendermintBlockResult.results.length).toBe( - kyveBlockResult.results.length, - ); - expect(tendermintBlockResult.validatorUpdates.length).toBe( - kyveBlockResult.validatorUpdates.length, - ); - expect(tendermintBlockResult.height).toBe(kyveBlockResult.height); - - expect( - tendermintBlockResult.endBlockEvents[2].attributes.find( - (a) => a.key === 'recipient', - ), - ).toEqual( - kyveBlockResult.endBlockEvents[2].attributes.find( - (a) => a.key === 'cmVjaXBpZW50', - ), - ); + // + // expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); + // + // // Note: block result will fail on expect due to deep nested array order being wrong + // // RPC uses base64 decoded, due to recent upgrade. + // // However, kyve stores base64 encoded + // expect( + // tendermintBlockResult.beginBlockEvents[4].attributes.find( + // (a) => a.key === 'sender', + // ), + // ).toEqual( + // kyveBlockResult.beginBlockEvents[4].attributes.find( + // (a) => a.key === 'c2VuZGVy', + // ), + // ); + // expect( + // isEqual( + // tendermintBlockResult.consensusUpdates, + // kyveBlockResult.consensusUpdates, + // ), + // ).toBe(true); + // expect(tendermintBlockResult.results.length).toBe( + // kyveBlockResult.results.length, + // ); + // expect(tendermintBlockResult.validatorUpdates.length).toBe( + // kyveBlockResult.validatorUpdates.length, + // ); + // expect(tendermintBlockResult.height).toBe(kyveBlockResult.height); + // + // expect( + // tendermintBlockResult.endBlockEvents[2].attributes.find( + // (a) => a.key === 'recipient', + // ), + // ).toEqual( + // kyveBlockResult.endBlockEvents[2].attributes.find( + // (a) => a.key === 'cmVjaXBpZW50', + // ), + // ); }); it('determine correct pool', () => { expect((kyveApi as any).poolId).toBe('2'); From 7aa1a5e009edb067128271f31f62be9b16bd5a8c Mon Sep 17 00:00:00 2001 From: bz888 Date: Thu, 28 Mar 2024 15:39:04 +0800 Subject: [PATCH 08/81] add parser for wrapEvents without using logs, add tests --- packages/node/src/utils/bundle.json | 3820 ++++++++++++++++++++++++++ packages/node/src/utils/cosmos.ts | 49 +- packages/node/src/utils/kyve.spec.ts | 165 +- packages/node/src/utils/kyve.ts | 2 +- 4 files changed, 3943 insertions(+), 93 deletions(-) create mode 100644 packages/node/src/utils/bundle.json diff --git a/packages/node/src/utils/bundle.json b/packages/node/src/utils/bundle.json new file mode 100644 index 000000000..f85e4ad06 --- /dev/null +++ b/packages/node/src/utils/bundle.json @@ -0,0 +1,3820 @@ +{ + "key": "3856726", + "value": { + "block": { + "block_id": { + "hash": "51223D03D35E04476553C309FA4094E8EE09570178B4B77EB5D663F2BF72AB9E", + "parts": { + "total": 1, + "hash": "2D95CC59E4000651933F9E1D3C63BBC06480C9B6BDD201CB8B1FB08E5354AE7D" + } + }, + "block": { + "header": { + "version": { + "block": "11" + }, + "chain_id": "archway-1", + "height": "3856726", + "time": "2024-03-25T06:14:27.24295008Z", + "last_block_id": { + "hash": "C9C081761B20353325F5C2D8A53068F0DD59BD739D562F1017D047825928DF0D", + "parts": { + "total": 1, + "hash": "B645EAA4F54247468C1BA020A71AFCEFB72EAF900E1F3D219EB3FBA5756E4F16" + } + }, + "last_commit_hash": "935D03A37FF6C9C7BF1C89F6DB1A65AC70FA4A0F7CCFC248ED25251E4151423A", + "data_hash": "CE02B6109F04A6C01EB71819F9D8EF1CE28C3D8B1E37B8EFBFF2A1134BF409C0", + "validators_hash": "BE08D7C9A03E52687DB305B8CEF14F96D353FD6DC66F694C0D21FB2BF4C9C4DB", + "next_validators_hash": "BE08D7C9A03E52687DB305B8CEF14F96D353FD6DC66F694C0D21FB2BF4C9C4DB", + "consensus_hash": "22E3FA2D1695AE7DB62E55677BF0C914B1EC88D64CD8D280CF2E29B2E06D0965", + "app_hash": "4F36440223B8AA53C357A9203054C4CC54F669E59714A5F587AD308C5BD4141C", + "last_results_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "evidence_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "proposer_address": "F183805F63AD6C429B7157D90D7199F2075280AA" + }, + "data": { + "txs": [ + "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" + ] + }, + "evidence": { + "evidence": [] + }, + "last_commit": { + "height": "3856725", + "round": 0, + "block_id": { + "hash": "C9C081761B20353325F5C2D8A53068F0DD59BD739D562F1017D047825928DF0D", + "parts": { + "total": 1, + "hash": "B645EAA4F54247468C1BA020A71AFCEFB72EAF900E1F3D219EB3FBA5756E4F16" + } + }, + "signatures": [ + { + "block_id_flag": 2, + "validator_address": "454BA446172211B1CB7A08E14161FB3BA1493F73", + "timestamp": "2024-03-25T06:14:27.198711863Z", + "signature": "2e8XvUA4Tbn1wEbARGH8NB1UmMK6MS5vMlZjNBV1x4K1+SOGkqSfMdm/ulWngwiOygqBwLgsvmq/rhikwa2rDw==" + }, + { + "block_id_flag": 2, + "validator_address": "5E026F83F8DDC51308008A80518530E9C03C7771", + "timestamp": "2024-03-25T06:14:27.302921022Z", + "signature": "lq2SyHxljxPnLImJIS2/fPAKqyyP4pmhdx3Zs3mAt6gjK6mZUCkTQ1GVF3GAAzDmQplkbnIT5/Vehi31pja5Ag==" + }, + { + "block_id_flag": 2, + "validator_address": "C64F7CF03BBB07B80E1B557A185032114C1F0201", + "timestamp": "2024-03-25T06:14:27.268900037Z", + "signature": "lY9GJMAD7/zGk0S3Kc7VhE80xggXs68AXiYhiJnG5aB+IhpdEorKdGxXWrw/Tl7V/NNGwfM1DM+naq6e3rBeBg==" + }, + { + "block_id_flag": 2, + "validator_address": "9396A4ECDC186B5F92600579AEC5E04D1059642D", + "timestamp": "2024-03-25T06:14:27.292183475Z", + "signature": "ndgHemJ5qlwxgpfQ/6Y2PqFRNfOkS58jJC1up4gQ5ZYUggDBIVxYdNSqWscmvgpBZkz6IrIfUukO/JnZqcpJDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "192D17EFD1F6012E52A8833717D8621178168264", + "timestamp": "2024-03-25T06:14:27.21504644Z", + "signature": "n2jli5HiR7rDMEI36JqQvUem3RNarjPr1N0tqTQReYslCn8m9r2KRvj13WpaWx1nyc9bjF4/tEBhTmn3DUuRAg==" + }, + { + "block_id_flag": 2, + "validator_address": "56AE16561016ECD1B64540DCE711C588F06E2DBA", + "timestamp": "2024-03-25T06:14:27.204804746Z", + "signature": "SgF01ZGHIwwNjmyGYhSnzf6+xgTJRAozD2c0C76zCHnU7b3lo/7Xg29fJh4AZZw4c4ol8CstNBDh2CCcMSWwAg==" + }, + { + "block_id_flag": 2, + "validator_address": "3ABC887FAAB038EBB82506305FD928270AD2867C", + "timestamp": "2024-03-25T06:14:27.359862997Z", + "signature": "60Jc13MrHdG1zk2OFXEx39n0VfXvRD4rSvsu6gqNJ9FqNM+TcnZGN6nhLQFJ9ijFhqZhJwODI31B+zWJzv+yAg==" + }, + { + "block_id_flag": 2, + "validator_address": "7CF3A6E06DA02BF700E33372951EA2E95AF6A7C6", + "timestamp": "2024-03-25T06:14:27.243732794Z", + "signature": "uYOWyHr8KmR7rsrvgzKo7LJOvP0bPnzA0s3yVePxt6JlzAK+bvOuV1HJ6GBm7cg7BBhJQUzB5YUZbUdGbqwGCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "E89799B6440988A1AAEE14ADA7050FCFBCBE31B5", + "timestamp": "2024-03-25T06:14:27.28412331Z", + "signature": "oz0OU8f0jpbkMPye9psiy+qnE+Hpa9fkh+IlFN8u80Mgi3pB1ABAn4SAt08qGQu3eu/Gnuv21tWnDnmUpGo+AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "E840B5676A5DA43F7ECA8385B461FA6BF0BE2CCB", + "timestamp": "2024-03-25T06:14:27.229527079Z", + "signature": "OY/V9y9gwWgKLgWPW6P4W73BPNAdcGR8KB+XnkM72My81/8NmzCh0F2OBysNRxYZ5qoV0TheXqc2WdVp2/SiDw==" + }, + { + "block_id_flag": 2, + "validator_address": "90FAA31CA9BE4E4BB8E4C9732EB69575F4C5B626", + "timestamp": "2024-03-25T06:14:27.251424274Z", + "signature": "25v4oL8wp+MbgxYl7V9LsCOvoohPeMejbim173bPKvmz9M8pKieyb5LoBO/9I0nHYvmLXuwLYTjj+iksIRy9Bw==" + }, + { + "block_id_flag": 2, + "validator_address": "CB8D061C7D78BAE099C50D6857B97AD4A9218776", + "timestamp": "2024-03-25T06:14:27.24295008Z", + "signature": "vUBPYARoWvUjAEqgp+UwXQSSmIGaW5Gajhi/E7PMOivzpY3trjjknomq3hzR9Jw4B0OQplviiJnRCn9voF/yAA==" + }, + { + "block_id_flag": 2, + "validator_address": "4630574528AEF5F2CE3BEA1BE9E092927E311F0E", + "timestamp": "2024-03-25T06:14:27.18719406Z", + "signature": "HwRudquc1x2MWz8e8a1B8EBhGYQIBMAFM24svk+SfjL/DMESJ2bEQwZvylYdNtRcuHsw6x17EfIHNuVNOAI3DA==" + }, + { + "block_id_flag": 2, + "validator_address": "B2FF86CCBBA2DB501E828E0E9D15EC14D50E0214", + "timestamp": "2024-03-25T06:14:27.191671125Z", + "signature": "y1shsVEvnmu7wPAcycLcpyqwsm2ZWyhpw/biuxFycx0/fhh+BlEX9QUIsJz1LDo52tPRIrbVNpmmTQ+9t4mBBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "CFBD265B3AB49045D2AEE7D001199ABD30BD1E5C", + "timestamp": "2024-03-25T06:14:27.209181671Z", + "signature": "IGfa6KghvryZkbonMVj/pXMQ6A+tsBDVN9OC1+KNBRl35eDe552hRjK07r1To4tMHM5+Fnz59a85ft7hconBCA==" + }, + { + "block_id_flag": 2, + "validator_address": "2348415EAAEAE89FE5A9412F2F45CA9AA5E73BBA", + "timestamp": "2024-03-25T06:14:27.348597083Z", + "signature": "MDv8yml9BxpRdKo/lTnhHfz/mCo9yeIEBbt5KjARvvTXlka5cwGwMW/hdCpNXMPqHqEv/I72mVQo/84tqyROCw==" + }, + { + "block_id_flag": 2, + "validator_address": "E4983569DBE9E32DC1C9C69CBE4DCF1CB82899AA", + "timestamp": "2024-03-25T06:14:27.242449608Z", + "signature": "43gXDvJMGoNR39pQdtx/w1moo3iGxEJM6CLxobXOx76WmtV0lT8izEqHXYOpPJFzd1alGpvmDWzFp7YAk5EuCw==" + }, + { + "block_id_flag": 2, + "validator_address": "F183805F63AD6C429B7157D90D7199F2075280AA", + "timestamp": "2024-03-25T06:14:27.205952311Z", + "signature": "ZotOXk+V0oh5eJFv0E/9l3oMnmLfdsrIu7+C1/Ufhl6W06g+Qx+FlGG6OcoJA4KKym/E7gLmkegZUKCz2B+DCA==" + }, + { + "block_id_flag": 2, + "validator_address": "5F647EE2AA22982E897765117160DA27BD8DD1AE", + "timestamp": "2024-03-25T06:14:27.21051342Z", + "signature": "SQuChlSd/54IYo9N4KAsUeoaXX21lD9Gvbq4tbSqa0QP8awWaav6S8pd0d5UN3Q5DaoJdgmP8JPNOWAowkNZDA==" + }, + { + "block_id_flag": 2, + "validator_address": "C6216B74B71AD3DD522E00D28BF1E7D7B9145869", + "timestamp": "2024-03-25T06:14:27.260030577Z", + "signature": "2ZBx8rLaNazZ93iQhmpAkYABtx424OfrXrDssBhZO3Cs+bO9StVeQOU06WXI0AQqtHD24Aw+Q5EqVAOBAWPNAg==" + }, + { + "block_id_flag": 2, + "validator_address": "31323915F9B0CBC60B4F371E454B5FB19B0AD26D", + "timestamp": "2024-03-25T06:14:27.296428597Z", + "signature": "gR96bGxmM/Xu5MBNPftimPjjgQDGagvG9tK4PA0UKARwf0wb3t4WspRcdv7sf8x05LWbx7CBb3DFoY5jcYA9AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "90F0753D72B15384CD536B1FAE023BD7FF7D250E", + "timestamp": "2024-03-25T06:14:27.294846688Z", + "signature": "urgxmnMfREsnkRtkhs6JaLTnY35UlkabmVDFnmB3qGfOfDeVurLUcBWIe2pAdJAsu5NGqYiKhWwRjPlNxbSHCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "9417D3AA3F23E9D96CDCBA2045A07B401C1E11DC", + "timestamp": "2024-03-25T06:14:27.21561313Z", + "signature": "DQWOigfi6ey6I1U9VGIb5gjEDY/QKXtRqGdxxUVnAPlI0Az+QpHXQ3FzhMj6ChteqVWg/OzIpU8YencUPT0/AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "38303246077ABA69E2782CB2C71C89DE9E2B7BCC", + "timestamp": "2024-03-25T06:14:27.273058159Z", + "signature": "ETdEehLafzgsITa1hBtEjKUcIg5SVPcrGUAmpW64Dju2AcfFoX7u0Hh8M3YW1JHb0ad0cZNC93q2Wm6NWtStBw==" + }, + { + "block_id_flag": 2, + "validator_address": "1D143C66358013DFA42A05A3BD9D00397AFDD6D4", + "timestamp": "2024-03-25T06:14:27.26998412Z", + "signature": "Xbhtj+DbTXVOLXc/eCszWFHCun34INCAn1OC9IxSM+pj261HVnUauh001rnFxzBjD52mxl7Wi2i4KoFd+TXxCA==" + }, + { + "block_id_flag": 2, + "validator_address": "8F41A1631BC7D5ED4915B673297D2F60A22C6E34", + "timestamp": "2024-03-25T06:14:27.208788012Z", + "signature": "vJts89t3tXLBb6LB/CF5UO1/l+gQP4teCQIOVj9Q3trUHB3SE4u1T9IPeQL5gblXTiwARrwkbccCuI0NUztlCw==" + }, + { + "block_id_flag": 2, + "validator_address": "8B714B0E76353D945D98D4974C8BD0B0748EC196", + "timestamp": "2024-03-25T06:14:27.233740258Z", + "signature": "hkqqwoCiTCNDURwo/9Pj4KqQ4cWKSnFnlqktW9wsohfmNdEZWjBCuFPfO7Etr2pfh0Cv5DVe7yTc5Sm4Nok8DQ==" + }, + { + "block_id_flag": 2, + "validator_address": "94B06CE54895A6138DB5D3E406E5914ED41445D9", + "timestamp": "2024-03-25T06:14:27.249889348Z", + "signature": "Fn/3ESz0Z8c79L37hKlyeSI3RR8ztarlrCmK8HLnU9CD7jaO1O9MJziqE56vATpHGAkDZEKPOSCbwJGu+cdgCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "ADADEE9B97C69600FEA8911323F3F5CB28906EE5", + "timestamp": "2024-03-25T06:14:27.399513013Z", + "signature": "Xb+eLvN/0KMqjCcYlq20t/gdR2tRf4f6p9w3IlcCseoR6F4p3RyHAV2RZ2TszcjUP8VYIAdCgukukIxofZhFCg==" + }, + { + "block_id_flag": 2, + "validator_address": "FD1E562DD7FA1296ACA834EF29AA0685A8AD8F33", + "timestamp": "2024-03-25T06:14:27.201830902Z", + "signature": "OMhImUqKrB6sbsBfDRcr5+F/+L4oNH8KuP+nBLmwp8RSXvW65oxMEyR/O9KqMtUl5Ib12TwI0BIHxNUWHDwaBA==" + }, + { + "block_id_flag": 2, + "validator_address": "A0212325DA0D8E777AA60AC5DA61DE409072726A", + "timestamp": "2024-03-25T06:14:27.208975888Z", + "signature": "nFEzQvXWCQzfQO1g7CAp5Qr8dgy2eOfF3WeWgcolIxq/2HSbLDO3uB+iIWMEkSTSkh9Zk/H1yCkeNfzMaFIuAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "CF65D933DAAD0646727C76795AAB0DE423B8C0E5", + "timestamp": "2024-03-25T06:14:27.216374782Z", + "signature": "GQZAf4We2Q3mKY1F8AVEirKOU/VXo/Ia1JJfkx0VreBDXqhAeJ0h/q64G7oXdw02Ed11Kc3CoqK7CtXuVAJBBg==" + }, + { + "block_id_flag": 2, + "validator_address": "80FF2FDD961F707F3C005A7FD41D55A74F076AA0", + "timestamp": "2024-03-25T06:14:27.224969374Z", + "signature": "tXcyjOQTYwoyhvsDhfAamhPjpLDytPKFsUIbVYeZO/hwmgnrZS8G6IH50gSS4BfhcMPQ6Bp0oRF0R8bBwldyAg==" + }, + { + "block_id_flag": 2, + "validator_address": "FF592BF088B8ADABFA6080AA820F7903F0F02046", + "timestamp": "2024-03-25T06:14:27.306082208Z", + "signature": "mqIIRczB6lyk6j5CqUK+VIun34fVFA/50fV6qcHZkJcCaYxZC+CKu88/KVPXfsCOHEEBxnvCC0d/AGpTPVbWAg==" + }, + { + "block_id_flag": 2, + "validator_address": "C5047A5B0C008A531993140151F3E54C1308A86F", + "timestamp": "2024-03-25T06:14:27.211417554Z", + "signature": "0qJEczrpIYdF8sdNT3p0gYivAFT/NeUvbml7mOkyDA/bsHGeXVDX+n5aLrkx/fYyqhs+rCB7bv23j7mI+Mn1Dw==" + }, + { + "block_id_flag": 2, + "validator_address": "43EAC69067530360F849375487ADA1F26FC026FE", + "timestamp": "2024-03-25T06:14:27.221068884Z", + "signature": "doK0ZlUgFFtnPJLgEXTp8W10EGXBBZC+u3YNYe1SD33W9LG4uTXfj0t0db4XsD7KIaZ7QWmdBP33ew0mStwKBg==" + }, + { + "block_id_flag": 2, + "validator_address": "5894E2D8B68C01CBC835985BADBF0AE378A5A6B6", + "timestamp": "2024-03-25T06:14:27.262841804Z", + "signature": "aQDifQtR7PY8mmujd353OZGJRJozbbPg9BpZP/WmjXQDLI/vuDDTMUJUfw0/JE9cDra42hnPQ5pf/8aarGWCCw==" + }, + { + "block_id_flag": 2, + "validator_address": "94A81ED9CF1EFE9672501231F0255F0C54A4F411", + "timestamp": "2024-03-25T06:14:27.213546159Z", + "signature": "SUpF6JTYtVLUX3QDVS5qNlSiJg8Nco3+3tO+XZ9ehfUFHqQ7hqchj4OFBHNbtF6KOZbolGz04ZSZrEaV6PTyDw==" + }, + { + "block_id_flag": 2, + "validator_address": "D78997B5A01D2D4E80C5189D930A14055002B478", + "timestamp": "2024-03-25T06:14:27.209686721Z", + "signature": "AiEAtstORITGefKUuruXaVLMV2PddgE+MvNgoefPNnaeTVRPRsgcMYCfk6TsLGDCkih4uTpGJIKyly/h1NIGCg==" + }, + { + "block_id_flag": 2, + "validator_address": "69C38FB90624F19356482DAA89E64D9957A37C00", + "timestamp": "2024-03-25T06:14:27.197381186Z", + "signature": "0zJHwlFfrnEX88Yhjwr7Mp/2UCaL66KY9K1H5DXwGjgBb6O7ozW5Ku36+RmT8/QFM+pQmQHUHf32De5nrpzIBw==" + }, + { + "block_id_flag": 2, + "validator_address": "2D63B9079FCAF8CEE74B072665A04599064BCB09", + "timestamp": "2024-03-25T06:14:27.187860932Z", + "signature": "FTIy7zamXLA6S/NzmMDHv7sy5/FGcIpChtLmNgzFhUz59P7uV2OT1RRVD56nWabrqCMOV6Qio1DEIdiptFoBDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "1AF66CF8C90E5D334FB095B4983210FDC2E2815F", + "timestamp": "2024-03-25T06:14:27.2934702Z", + "signature": "BmKsz5Lt6sxLRyv8UQDsYKuyTRJeuyG9NjAMzXgw5T1Da3Vx6EpRqhm5lY4ZpBzVLagXGD072Ix4q8Z56wV/DA==" + }, + { + "block_id_flag": 2, + "validator_address": "159424CD4756CBEF88083C1A11B6033423537A3A", + "timestamp": "2024-03-25T06:14:27.395386931Z", + "signature": "LP+S1UnorS51jwWhLUbepP/sgezYL1CJInFhR2c4oTc+k5iabeFofw04ZW/zQMNebDHXNF6oyWubaD2KnGc4CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "C406A6BFB29F36979ADA959B917DD4A2A780E519", + "timestamp": "2024-03-25T06:14:27.299496138Z", + "signature": "7HTkVqMSkgQc3PqfW7twXSI9sIrkgwfyn16KML7y6gB677rk2Wn3YvVL2rn7JfC2Cnbj5PS17o53y7+76wY6CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "92C0FD982DEC037B295494DC7ACF25FBB8E3EE5C", + "timestamp": "2024-03-25T06:14:21.339631074Z", + "signature": "9vtjqiTYXLoP6728kPDuJnt5Dq5cwauRcXs942pBJFw3go0TP2hWojpO5ljf9XqaUDdffIHqSsyclALtIqi5Bg==" + }, + { + "block_id_flag": 2, + "validator_address": "5883CB9214B4FE1A0CE68774D714425DC6024D52", + "timestamp": "2024-03-25T06:14:27.241979083Z", + "signature": "ILVsPy44TCgUW+VCQLazvEma7Knr/G9TgZF5UBHqRCkMu1loWS4WhfaLUeXYxWJ/oTzSt0B0eD1hoSYtJP3xAw==" + }, + { + "block_id_flag": 2, + "validator_address": "6C6412282FB32525FD92617157F154579434F9FC", + "timestamp": "2024-03-25T06:14:27.204271239Z", + "signature": "snrhUC6Qa3dhiQeIaI41CYAS41k91X544LpEnk24LHzEwSR0u9Qbrfum3ocvxfldTuC6N4S2URuGGIUfjU+0Cw==" + }, + { + "block_id_flag": 2, + "validator_address": "EEB553125D331715F799680FE763B33D4D8EC063", + "timestamp": "2024-03-25T06:14:27.233977273Z", + "signature": "gctjdRc+zF9OEV3xa6X/cjIaOoOVyOwWwumCbbomNmlv4VRyi6ctBJHVHtbrnampkDdT4EF1jwRriAznffzfDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "DB2D66F06C70A06818910685E8A51C73E6EF3324", + "timestamp": "2024-03-25T06:14:27.226749145Z", + "signature": "BIOK4yc3z8qjpeFyCAQ9deVWFd+N/JWBtyJCM3WoP6oeaCdImZlz1GMZpFdu/q910OlJ5ovLeVEPgKm2ygYeCA==" + }, + { + "block_id_flag": 2, + "validator_address": "07F4F6BEAC490B1508E93E38D9E5B3DC50716200", + "timestamp": "2024-03-25T06:14:27.325335199Z", + "signature": "PngsVhXlpeFwn/0SxHolgxNkKH5lXWkJKskaYJ6XlexUPImbJNT0dbHoWGqeMmaaHONyhvTL6rJZgZ+/SJtvAA==" + }, + { + "block_id_flag": 2, + "validator_address": "32F529A962B3F9D7896BD858D9970E3C1392570E", + "timestamp": "2024-03-25T06:14:27.435809271Z", + "signature": "P3b/VPqrxBgxf1uBMd+3oNssgAWvzJTYzSHTL+msiTEGNvXWJWO/iuzds59daZO5ZktKHLeebX/8hSO0LHPUCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "223BD658ADC0BE9E1A318EAEE26A927E9B782DFB", + "timestamp": "2024-03-25T06:14:27.298543778Z", + "signature": "22Ci/5gtqsUekp6U1XIPDU/6a4f9XJNuwPu5lNuU2GLcAeW5ztZqMHphb4kT0AHGdn04g41UFlKGaRMUmybbAA==" + }, + { + "block_id_flag": 2, + "validator_address": "B155936FBF30A4A21C2FD9B2A3CC1C2CACA9DDE7", + "timestamp": "2024-03-25T06:14:27.314051454Z", + "signature": "6DoBNRasJfqp5eTsWkX99hSTtq8aFYg7h1jydaYpB5DQAL/J5Tie0w1jd8gq981rZBOVUgfNuPkpl7OonwgsBw==" + }, + { + "block_id_flag": 2, + "validator_address": "D0810844A5202004AE1249CE17610A4AA5A1684E", + "timestamp": "2024-03-25T06:14:27.504915992Z", + "signature": "yB9nGNImbiz1x/fc/wMEnmbT5vahaPEWolorzE35PhOW+JveeTH5wXVfc8V2+PKIflFPn2ftbR/j7Jvns96GCw==" + }, + { + "block_id_flag": 2, + "validator_address": "0C170D04155D212B97B3D33AD24D0076053E70C2", + "timestamp": "2024-03-25T06:14:27.282067495Z", + "signature": "5S/h/C2XHP70XYO7WXAzOOHZCz0eyO+RLNO59c7VVfZcPloEomvwrVlyG+UOL1cHV0BxTqHOmy82+V0TE3tZAw==" + }, + { + "block_id_flag": 2, + "validator_address": "2859D4F84CABF0136BEAF3EFA339F5BF6F6CD39C", + "timestamp": "2024-03-25T06:14:27.229881613Z", + "signature": "GljjGBNXjaJdU3yObE7h58jJwbCoAoNLMtjvpMYG/UHtrk3vBvxiILksgS3nKxXnLYv+8UDqNaM9BYRs3cKlCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "195623E1DDC7F85D8E5015D79B9D0DA47A7F59C2", + "timestamp": "2024-03-25T06:14:27.238487848Z", + "signature": "UFjUdS/aJgk2DPWC/BJKgMmqIuGGQMrNwdAdLFKcRjHfjNmBS2JanaSt43Hrlrpha0USzAOUYecVp8Qnif+8Dw==" + }, + { + "block_id_flag": 2, + "validator_address": "7B0411064960AD679FC4A64A7066B401DF3C7F52", + "timestamp": "2024-03-25T06:14:27.294517354Z", + "signature": "xuSuad88AM2c9Jp3n3Q/tERfFoZrxBPv0I59ZJl1rLvqPE3nZBOuCBMwZPUCEa9136QsNfpXEemt/4jlliN5Cw==" + }, + { + "block_id_flag": 2, + "validator_address": "8066E3C72BE72F9CD84439FFB59D79B2C316C01D", + "timestamp": "2024-03-25T06:14:27.297025738Z", + "signature": "SsE4E3QYw+1rk9uhObCu3YUlHQSoREfMeVX456rSeQLhU+Lppat69YtxnG4FWGeBBzgMZ+jg+s+GyWhVOIjDBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "8CB1BE337D1427136EB8EDDD9232735E2405C50C", + "timestamp": "2024-03-25T06:14:27.248658018Z", + "signature": "SOO5yhm/Zs/qgTMYbId1yn44P4Bo/88BtNvJBEmziJeOwrpwV0So5q1FDQ2pK+ddAsc9ampt2pIA3gdlNimgDw==" + }, + { + "block_id_flag": 2, + "validator_address": "83CC77F0F60F418B9DE2A24642645777D2FBCC02", + "timestamp": "2024-03-25T06:14:27.254563507Z", + "signature": "aEt+2hSYgJibHGrvCK47cq4NOFSYyQR2lBn2qK7V9KJSRN0ccB5Bp/iM/OyhlJ7PrLOWanQghCqzotcQQb0KAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "D83516A8B94EA1DB899B7C80C76C05D0BE204004", + "timestamp": "2024-03-25T06:14:27.250738609Z", + "signature": "20E5FZHX7sCgykdz7wpaMpt/xCCUPy/3joMlb3vqagUT1OqVgFj5IonKpFPz8WDcZCDv2CEAjc2qzSb0zNAYCw==" + }, + { + "block_id_flag": 2, + "validator_address": "DBDE432B755C38F3136A75D2D3F530B5A74FBDF2", + "timestamp": "2024-03-25T06:14:27.226292884Z", + "signature": "OampF/a5bMIBndboMuM+rsJBoa6rDS1AKYQLf4QV3elgVSxYBPaWh32NGzKI0FvKtfNCo82GiWNyKKvBTXfiCA==" + }, + { + "block_id_flag": 2, + "validator_address": "8F9C9F4EC28C7E06F3D348394270FCA69DBA116B", + "timestamp": "2024-03-25T06:14:27.294859322Z", + "signature": "Aid0oQvPLKP2Ab78Nj2jnw/2TVc7ojnh8oi2q/dETrip9eEH8XSeQJ9+bKnFU2oKnmcK1FYkKwGzi5m2EfpEBg==" + }, + { + "block_id_flag": 2, + "validator_address": "F9F61FD65FB010A8C9365032D83CCAB9FEF69BFA", + "timestamp": "2024-03-25T06:14:27.20862173Z", + "signature": "Raa83ztno5967q1aeVw+SKas6WPNJz0xHOb3z4fAxrAZemNR5rkrEcBK5Dah6l8nQ70m0Y1OYRUEV1GE93e5Aw==" + }, + { + "block_id_flag": 2, + "validator_address": "02425C209B7A5BFDA29FEEC5876E12AEC64D4C81", + "timestamp": "2024-03-25T06:14:27.198883431Z", + "signature": "aFf3eD567PWOwcSWeKXFD156lM9AngvM6w738tUQGj9sI3sLLj+qHFDe2f54ZDx3ybBt01bpvk0Td1isEDhQBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "37CBD9EAD6B6632851646323C2D9127E79B1C37C", + "timestamp": "2024-03-25T06:14:27.250703418Z", + "signature": "aslqoF8TjiCalfO48S98TW5mdfUZ1IP3MK6JWupdwxaVwcEhDcr4wffSK5nqXSHdPhdFmSJsY16jN+4YfyCeAA==" + }, + { + "block_id_flag": 2, + "validator_address": "1DA762F8A91B63B90817D5D3A20D0A3E8CB240C9", + "timestamp": "2024-03-25T06:14:27.20908433Z", + "signature": "9kdJRK8+r0RRZ+q5eQQJPaP+17PKYyImLyHd5XOJqWU4JKS93eqQT6JHKJnTBGo0WAubVV90PI9DvgiWNtrpCw==" + }, + { + "block_id_flag": 2, + "validator_address": "012ED7FDCAFD53E87DBC4F98DCC93B73E30FFA2D", + "timestamp": "2024-03-25T06:14:27.270230258Z", + "signature": "gqwtVHmUbqy5DRDGg6eJjFS4nQgWmmM6e6t4Yx421IF/8/oWZeeMcjjFzlMxX4NonrEB8VBGHvY9hKL20/r2AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "E27C9D446FA6A9CFCE43802136CF958E7F939226", + "timestamp": "2024-03-25T06:14:27.216205479Z", + "signature": "PC05d40CuIxreCOcSWZ4mLm34hTYPWMMpBdcSHxOsQ/IU3MLP3PTikl8j2ugL3umg8OCxnxT2ef80z9df388BQ==" + }, + { + "block_id_flag": 2, + "validator_address": "0B854339BDCC14B85FB8711E41C2942377476F70", + "timestamp": "2024-03-25T06:14:27.209033257Z", + "signature": "l95YxnFCwAt1QuqXomDAkzc1Mo6R9j62BHT0tCSpj98rm6PCjsfIRvEP/+j+gQEqB4jJvqq2U6ZYosm3950NDg==" + }, + { + "block_id_flag": 2, + "validator_address": "ECEE73D95A77E41A4AC3148D75BE7AEB02CC147D", + "timestamp": "2024-03-25T06:14:27.300665187Z", + "signature": "X4XT2w9MkSXRn5NDElBwstWc9nhGGh5NJzO68WUXbZGH87DJlR+V2NdEtYz1/2gfaHw2DH1CLbVN9O9xL0zZDw==" + }, + { + "block_id_flag": 2, + "validator_address": "E3DE542C5573C78253BF5DA6F20E2119C0F1BA48", + "timestamp": "2024-03-25T06:14:27.240320031Z", + "signature": "HeMVDGr5kMtKJe0QRFy/CR3CcfY/xzYb1zawQtvfMb2G7gc06jJ4fd+4OM2JjUrZzG8W7wNx9EWYBzg3wHtwCg==" + }, + { + "block_id_flag": 2, + "validator_address": "1A0DD1BA9B3EF21F6414210D0AA35EE0F9A12BE0", + "timestamp": "2024-03-25T06:14:27.248713782Z", + "signature": "Q9bKIijvXNhhpTJw8GYCn4L6v91/pU6Zc1DjhEofzSkQCzn514glSpn6xs+WQxZw6br6Dn35k42jkdQ8fdT3Ag==" + }, + { + "block_id_flag": 2, + "validator_address": "3E01DF5EF729ABFB3CB4E8CBAE5062D685009FB7", + "timestamp": "2024-03-25T06:14:27.216058329Z", + "signature": "qUlOsW7hLc4RkBFDR2vSqGtpqRsaY2S4c0kr5qgR0rdCVwfOrkVjhBDrtM23nBiRmvzffpsYEUZm687WXmrgBg==" + }, + { + "block_id_flag": 2, + "validator_address": "10AC1B41D924B67539EA8D755FB0158D57B0F555", + "timestamp": "2024-03-25T06:14:27.260938966Z", + "signature": "QG/5BZ+4eq7sJkbrSeiQf41c+yZqbKanwFkIYGD/wiiNMYEhq1b3iZwS5bJKKRLb4zGprDKQ9vaohyN0eSdJDw==" + }, + { + "block_id_flag": 2, + "validator_address": "F5EFDE8E7BF30A548B847ACD250407CF0CC0539E", + "timestamp": "2024-03-25T06:14:27.211301742Z", + "signature": "1fdvlOuPcdAzrMFJxUgUGbRqX8OP1pb+PvxBUFGqaIFtxn+juxFXF15fvHiGjzG+MSF8w9SDzWjHBM323+0ZDA==" + }, + { + "block_id_flag": 2, + "validator_address": "E42A113076FE41D20780BC6F2FA1C700B2756193", + "timestamp": "2024-03-25T06:14:27.304878958Z", + "signature": "LiS/Ncw9LZpOZ7eSxl3mrflu4EFoK+92+81btwv8OH1112OLCcuoUP8FkukKyD2A3eP9asEmnFoGYecMxU/YAw==" + }, + { + "block_id_flag": 2, + "validator_address": "A468764E5AC834870F79453F1CA26060DEBFA629", + "timestamp": "2024-03-25T06:14:27.232074527Z", + "signature": "owk9vcDs3qppskTOF5ukfV40YvWd3uKT2O5OpB+RkvUhsN49HeUCBN+twoNN2yE99F2M0SEitXRdKD/0rqQZCw==" + }, + { + "block_id_flag": 2, + "validator_address": "7991CF87E4FF6C6D46376939E6E7214FA7473AE0", + "timestamp": "2024-03-25T06:14:27.24642099Z", + "signature": "5ekIibouYY03U0xtyEJH3b2DY5rBsQmmujd4q+P/Hz7Hu6fjqsDVe5r/w5Y+SyJW4Dpeu3IUBlHRLtMdWrU6CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "132A20818488C9362C9E37E529B879CBCD6FBDF3", + "timestamp": "2024-03-25T06:14:27.252922227Z", + "signature": "6XS3kXciqm/vyY5bILQ8+OIqNitOvmjcoTFECvuSwxQXonh3oLl9qDYMetl6TZzBfmWxOTwrvETU0YKanRP1Bg==" + }, + { + "block_id_flag": 2, + "validator_address": "4C10504F2614BE17668FB7EE4CCDC9BDBDC5E94D", + "timestamp": "2024-03-25T06:14:27.198949987Z", + "signature": "x0mukdGORqepq+INtUB8sifZ0EtHqhzXFZIgA1OMHyMEx3vg+m8qHdrxjfbN7QQcdkJGblG2UO9EMjQO5Tl6Bw==" + }, + { + "block_id_flag": 2, + "validator_address": "152DBAD504AF9B1C103D3D4BBBB472C45758F301", + "timestamp": "2024-03-25T06:14:27.301151981Z", + "signature": "JJ3DoJqBz2YjqdYElJT39L+viwFYy+svDpzgRBCflUGYDy41YyejvI7EoN21M3AbRylYVQrR3kF32aTvccTxDA==" + }, + { + "block_id_flag": 2, + "validator_address": "2191940572E2B2E4F477DA155AE95FA3697AF3D3", + "timestamp": "2024-03-25T06:14:27.222339495Z", + "signature": "RCpNsDllj2GCQ/wkgPlXPMB4a1b52U/kdFlasvR84uaZKhbf5vZKlQTlNMRk1UQ8OEduRfWuUUuVAnc8te+ICA==" + }, + { + "block_id_flag": 2, + "validator_address": "AF28D38FEA9D6F1A8559AE134EDA0F1FE1509768", + "timestamp": "2024-03-25T06:14:27.2892123Z", + "signature": "YvuPNZ2Pop9TeQjP231tgShezvdoIYj617baGJbRBfNxnuxzU2ZuouJOO2AtTgOr3yxxLmuntl7j21OYUugCBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "8D0008FE0C7A6EE7BDD1D59CAFFF96AE369C303F", + "timestamp": "2024-03-25T06:14:27.318615916Z", + "signature": "TMQnpCOmCG/XciqY1H1X+DRZn9d9a9ODBOgZAmGY1z98z3Le6ftIOtV4nBLNYbOw7JscKCy8HMTGOfUQTB32Ag==" + }, + { + "block_id_flag": 2, + "validator_address": "88102131B351CE7719EED9CADB15330217A9D038", + "timestamp": "2024-03-25T06:14:27.239020415Z", + "signature": "94mJSDK5AcChfp2Rs6w/LCl2Oa37J+S1wuqJD9MNDsSv8nx3ysxh7QkBqQrJmlO6z6zHQUw/H5frCFsAXqy9BA==" + }, + { + "block_id_flag": 2, + "validator_address": "9C3BFE7B68E53DFF9D3CF7B70E3B8115AFD42411", + "timestamp": "2024-03-25T06:14:27.402701022Z", + "signature": "8Pk9YesjiQUC9bTxL83CeDtofxEm6YesuPWfN3luxaBFY9crRetMZq6dVizo/lJz/teN2uLlVaKK4wmlivapDA==" + }, + { + "block_id_flag": 2, + "validator_address": "39BB490F1B1554AF3FB524CC89D1533EC5A02E2D", + "timestamp": "2024-03-25T06:14:27.203968116Z", + "signature": "tNL9c9RvIDEZr3sxrFzxxuzVnGZLFGNFabqtyEhDGzYp6fRtXHtcLOWkZoZVTBZsQ9TXRGADsNhxJbcTElenCA==" + }, + { + "block_id_flag": 2, + "validator_address": "750CA8CEE4ABA1CA93D1E0A524F26DA8A64EF7F7", + "timestamp": "2024-03-25T06:14:27.23364418Z", + "signature": "R318nz6/+S8PoN/2C/wHiT4zQdyqe5PlPP0C0ArZJ3DnK1NfM4O073tWOcQ/CTh24690+xhWRjOx32QfduEFBA==" + }, + { + "block_id_flag": 2, + "validator_address": "DBAC8BF532C03354ED8BCA5FB7992EA14C1B62C1", + "timestamp": "2024-03-25T06:14:27.263448028Z", + "signature": "1NFURpxVZOD3gXu9E7Bg77suvhIeJg6D5i+fVUTReoQnE38aJJwfCqrKPpnzkDOycHZlkONg/VkfMK0Cr5oVBg==" + }, + { + "block_id_flag": 2, + "validator_address": "E7F7CE3DC63D23B2AC7A233A432F8C7ED74B23B7", + "timestamp": "2024-03-25T06:14:27.192866526Z", + "signature": "n385e1IR/y0OfFgT/8284XFo+DP7hLA+LvNse0IhMnpZQpfn0z9Zwv5a6S16pcKGLtGcSS8bmTMgmifHOBb1Dg==" + }, + { + "block_id_flag": 2, + "validator_address": "23D911027C3A30470D63EBC2EDA4D71C91412543", + "timestamp": "2024-03-25T06:14:27.318050596Z", + "signature": "4ReDzyty2bN7bgbm5gqa+oHxL4oaxDzCOjqUIsbutxk+ydUQVoncqEbjVwn7xT69k6R5ZiHjzVrslJdGO72sCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "4B71B41D7DC82C7F44FADB7D527011678B14693D", + "timestamp": "2024-03-25T06:14:21.339631074Z", + "signature": "IGYRX6oOdKREREx+EmWDVYy4w7qsg3oaganYXH26V0S4hJLDb+ZbCDwIb1YNaolm2ASnA8ebbSf3eVwc7IkRAg==" + }, + { + "block_id_flag": 2, + "validator_address": "3A0C2AED56A4E76E52616CD336FBC311B3799322", + "timestamp": "2024-03-25T06:14:27.250498816Z", + "signature": "E2g6oC0ASeqUU8lUNRjGTkq6Nh7OjzjHgJAk2w9j44Xfl/iY0h1XClsASLOYBU5mi0jcwHtNGDiSebYszwhDCg==" + }, + { + "block_id_flag": 2, + "validator_address": "C071D8A87D78969620BC2D1AB55DCE5B683851ED", + "timestamp": "2024-03-25T06:14:27.217216828Z", + "signature": "/UaOablXzYlqttOw+DpJleRa2RbkOlFL+810RkWnMCN/kOKfaLXs283LOVVXcpfq3FL55m9/Se6WVysZZWoHBw==" + }, + { + "block_id_flag": 2, + "validator_address": "180049B647B4CE71C46D70E1AAAB869B2114D0A5", + "timestamp": "2024-03-25T06:14:27.276196465Z", + "signature": "0aUNZyRMWarl5PmjBpFFoZC0NQDIc9DWiVujKc/12VRpK7q2B8pmTRazKSKIPpCHyhccGuT8ZCnmzNXugG9fAw==" + }, + { + "block_id_flag": 2, + "validator_address": "C875B64A69611343F68BD7F1B81C16F971876720", + "timestamp": "2024-03-25T06:14:27.201976056Z", + "signature": "zt1C0dJQ2VM5LbntMfBNlo4FG45DoAJSydKY+siyF55pqdsxG3QW8lZY+QS/xNIDvB1zLce2d2pKNnqXiYmvDA==" + }, + { + "block_id_flag": 2, + "validator_address": "B6411041F5AA0C6E38612CC8E75BB70E74D0704E", + "timestamp": "2024-03-25T06:14:27.232543158Z", + "signature": "Q7HCCILuaWqAyYvcCLZAJ1Y0/K9DjXK3vi2ULYnBPLAUIMzK+6Vpqlf5qKwzyAyOJmFvg/iyGQp9SUgmTUunCA==" + }, + { + "block_id_flag": 2, + "validator_address": "ABE6553C7FCAB8753E1E2E0FCE046473F93CD6C3", + "timestamp": "2024-03-25T06:14:27.243673233Z", + "signature": "7jeKeynSTUFmxYOOWPXATSiL0Cw8aNY7zqyNqULCWANXBjrMIOOAFQi4MsUUxycX5fY+1bgWV/MWZvbq5UqOAw==" + } + ] + } + } + }, + "block_results": { + "height": "3856726", + "txs_results": [ + { + "code": 0, + "data": "Ei0KKy9pYmMuY29yZS5jbGllbnQudjEuTXNnVXBkYXRlQ2xpZW50UmVzcG9uc2USNQovL2liYy5jb3JlLmNoYW5uZWwudjEuTXNnQWNrbm93bGVkZ2VtZW50UmVzcG9uc2USAggC", + "info": "", + "gas_wanted": "484467", + "gas_used": "403673", + "events": [ + { + "type": "use_feegrant", + "attributes": [ + { + "key": "grantee", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" + }, + { + "key": "granter", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "update_feegrant", + "attributes": [ + { + "key": "grantee", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" + }, + { + "key": "granter", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "436020300000000000aarch" + }, + { + "key": "spender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "436020300000000000aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "436020300000000000aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "436020300000000000aarch" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4/16618" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "BumjcrR0vVFIKuVEKGTGEiunbHUhBwxCvRP/Xx1ZSstpmRuWGYXspOe1yhyOtjG3hGpDu21Tj4Pho2sPDwqAwA==" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/ibc.core.client.v1.MsgUpdateClient" + }, + { + "key": "sender", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" + } + ] + }, + { + "type": "update_client", + "attributes": [ + { + "key": "client_id", + "value": "07-tendermint-70" + }, + { + "key": "client_type", + "value": "07-tendermint" + }, + { + "key": "consensus_height", + "value": "2-15581441" + }, + { + "key": "consensus_heights", + "value": "2-15581441" + }, + { + "key": "header", + "value": "0a262f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e48656164657212c5a4010afd3e0a92030a02080b120a616b6173686e65742d32188182b707220b08c0ac84b00610c79bc8022a480a20922d44f2f302a137e504e1e13c5db35bcaee72048cad6c938c973a3a88cba31e122408041220e3a4c96bfb381a352849de7f701d75a65756fd247e2b66bca84c0486bade38b93220ff89aeb30b95970271355e66c5cf6f5a3759b8f98140b304e229da94be82aa2d3a20b00698a377c95210ab27810302fd90a4b3c92e7965e6e6ed0787d3f2740e2d1f4220e8d022f1af4597974007b2d1bb08b67c53b16a751b6c7c7f110adee60a6b433c4a2017bed346ba6ba721b8eda75e77e94874c944bf1a5c2a09b047ecbe62fa4d293e5220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20360989c22a580cf79524f65c84c33c84a19b148131ed545a8abbecc4f4cdd883622092ae11933d53f4bcf0f988bf0ded0a23182ef48b2b9737d9aeeb1522e044ae6b6a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572148fca7539afd32000bf2c928fc69737483c49b75b12e53b088182b7071a480a202aba4963d64d21e23de083b5628fa44af519509483a780126e8f683be0fcc4d9122408011220b8756df795d8a350b875893cc8d125dd48ea6a89a8547fcf44b81a25b5a3a6bd226808021214b1852d17fa66b5382a8f770725cc5b228b3577501a0c08c5ac84b00610cde3c89a032240859df3a1a0bded57a0c491cb2ff75fa76a9a7483d74105c558cbcfc6f7892f57791a8f3bc1f142e916a23ee75a3bc03f314b8b9a0d7bad967a3e351f21f844042268080212142abc4854b1a1c5aa8403c4ea853a81aca901cc761a0c08c5ac84b00610fb96c2a4032240cb64bc7eb090214ae00aedbe9752e66f7997fce1933142b8a7949ec747dcdd89e8e8d0019bb720344def6d4dff02ed0f176059489101dcb4a1792600d7a40a0322680802121425b40fd5ae2ac26b4382b746f6cddb8c73ce60251a0c08c5ac84b00610d1fcf8a6032240dab2c9cce83842bdce9d53819555f416f29077b0bad03d7f656c1ac3dc4ad3bc6c357d556eb9da5223f9edd47753804eb6f04a6a84e8745257edaedefbe5bb05220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212140549633adf0dd5e91ec75458cbeec35ae4331ad11a0c08c5ac84b006109189e1a3032240fb4af079d53daad6894e66eff8f5d8be255e30b59407ebdf106c66f004cdd5943b0cf8d22d088047d58be23dc5e39cf29615659aaa0f5f2f29009dd6ed7b7408220f08011a0b088092b8c398feffffff01226808021214fe1d612fc9c346e51fa20ed491ebd81162c0e1101a0c08c5ac84b0061095cacaa903224012903fa5ab2717225df16e12c51e01335c54fa5f6baf5e81d2bd273c9553e201799687f10f844067ff94683c05a51520766b2ac1993b6102025a3e632dcdb604220f08011a0b088092b8c398feffffff0122680802121439d8e563c1af1285095ff5bee373e235d63d0cae1a0c08c5ac84b00610df94e7a4032240d321a1c03391bcb663c0d1483015cacd1d82a30158a88b5a7e16e09dbaa0f28a994ad1ba549846994927a8eaa26cbfd3485a1c223c9f2cc356d404ce48f65d0922680802121459835dcbb6ce79f1d12b86702e8690e5f5c514e51a0c08c5ac84b006108cb3a29c032240502a742634bb3dfaf9698a12b679b9c5a376529d28c0bd96543a9f97b39e64ba67b45e025ebe7f69f295ad2c571f5b09f29f01ffc973877f8db84ba8b45f830a2268080212147bd85b0a30cfae183af900b65bc0ec0a28063c991a0c08c5ac84b00610beabdfa00322404cee5b1f3333a536b6a2ee8a88dab1bb8f9bb96a7adef3017d91bef73e4ee68b7cdcfb17a9a81c22072590e0751b3f1d38dc3c85b266ab7b27f015b180d2ef012268080212140218a7a051c04fec85b4f92bfb00a8c4da1a9bd51a0c08c5ac84b006109d9fb1a4032240e065dbd8ba81c1edc4b734364cd4508e1e13bf635f55b0cd960ab638eca7d0c4ee9bc71add507465589417cba9743b7a36eda7b762bf39e80fe450b25aedcf01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214fe849f301b09dacebd2dce15d3ca34d6ba4ca4731a0c08c5ac84b00610cfe9fca9032240de372dbf43b1d6eb45f0d7c7b883e7c6f12d135aa048d6d6591606bd612b97dee6d39c5d212f71d5e53e27b583dd7380368f40f1231f24f1ef749d7a3dfa44092268080212142d9790447341f3371ad11b4b706332313cce33c31a0c08c5ac84b00610f49eba8d032240c4d9b5c20c4c6f1eeadcd03276fe835d71d0f671da5922755156995b91c9e5b484c3e9e3f00f60fcf0832c54a73792d14b6744f7a70ec2c64689008f88d47e0c226808021214dfe3e4385652c2f176ebe59c3dbe4198fd30da901a0c08c5ac84b00610f1f88fa4032240905089e3124740c3af81f36139a014193d6409a7302f1968113156df7f8a84dde0b2da23a6d407c4c0b73db858a0d6a501128545fe81b76239ffcdf61af55709220f08011a0b088092b8c398feffffff012268080212148fca7539afd32000bf2c928fc69737483c49b75b1a0c08c5ac84b006108dddf6a403224072b6a0e54c29d81467082fdd2509e2956f769fb6abe7c8bf84264504f36d3b7318cf74461e70725aa1cef8b219a9c97d535728a8add54fd835e1d6a083a5fe07226808021214eab91d7b40213e14e850a90d7c28e662466dd7c61a0c08c5ac84b00610c9d3db850322402e6bff1624a5953964863100c0d131ed93497c893d3bc967bef501846941e89259b549de34ea6d0cf83b1e72f483397ea5bb88e4f06b1f096f76f6d1c18ac8082268080212142bded3e9a310eeedfb7d4db1778a9413e29d97b11a0c08c5ac84b00610adb8d1a60322407e25144dfcc7af4f7fbbecba576e504a739f7148904c38e697fe5147e5a6d52d701b04b32e133662e2eb89a777a4e84eadd465edf732bec01a3b3f42a4ac040c2268080212141856685db8ac33cb29b9b1d35c034f16511d48501a0c08c5ac84b00610c0c6d2aa032240d7aba48b01d06f8a6a9d99a414e9c09703fbec6a1d1fb933ce4feb17034b1a6786e27b379399403ae69a30f0673a2e7c4fa8f6753a15726529d81dedd0f35704226808021214fac8f77451006668f58b8937a73ae86aee68e2531a0c08c5ac84b00610b784c99a032240a70c848545d669d2e8ea4e9c9bc57ac15fd5b008d8cad2241c5f32e14f44279232874ec8689e121e57b48a79e8d3ce952f4ac3612f486f4939843d7d1557b404226808021214f8bf2150619f6d553ec0ee4427e09ae4cf085aef1a0c08c5ac84b00610cca5aeaa0322408b2fd4a1d57abede09f226812790555a95d3ed43c1ded2c82bb6b424563ff7b554538fa4338e2d9ca7e9432fd1425d70f6f16ed5f802b011a926c1cd384c3c08226808021214ebaaecf31ec18dc4234e01c82b749ae2cd7a95771a0c08c5ac84b0061083abb0b20322408e624290f7816ef1552e51cbe6f94cab4c113276b8ad50bd2280408f9e3e35b4e400677f8db92024ce9fe0d777bb605be7a777fd3fbd76223daf5b83b524da09226808021214c3c730090bf75fc5bfdfbb4bd26589cf1c7b74871a0c08c5ac84b00610c9a6b7850322402fffe20e969254879e78defaefe87a43efa3578bc3ec3727f31667995bc5ee239fdb7a3334a29d92bc3f247c06059fcd8c05b522c71772905f9b7bcb552c7103220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214706fab402d748242cd0a22b49012a6c039feec651a0c08c5ac84b00610f6b49aa90322405a598006423467706d4806c454bdc8e101bc58ad24286bec38964c29447767f93e0b3fe8beca13a9ee57935c05cd01b536282a8e23c1fb7e96723795dd4a5007226808021214b4fd96d19a44fe4b6b05370f200d89251fb68b401a0c08c5ac84b00610f8fc81a50322402c23e85d098e4c8efb6c3dd40a0b52dcf5e47e1a226a5dbaa0482032253732b0eb59de81a8c2e3b8443697f94c71cc6e2e577367ca4b711b6bd08c332f6af100220f08011a0b088092b8c398feffffff012268080212149c29fe719923138d4a27bde5704563e45afc705d1a0c08c5ac84b00610ca9fecaa03224039125eabe6237dbcf691370a9ececacc1b38e5204ca9654ada8325631bbae9741f6c79fd4694cb0bdc461f26b97ca82b7970a5a21f83bc1497787f719cd12c0c220f08011a0b088092b8c398feffffff012268080212144451050fc63430d28fedd2a37f3ba16353c7e60a1a0c08c5ac84b00610809893a70322409fcb186b8cf687398b6a3776f57dd70f7146a4b0be0ed1523ff577be61ea10460fb1eed891a7ad5f02802b9ce018d6cda0f432199e661f75ea27b161bc547f0d226808021214a6e68f4720f047480f3bee8502304baf0faaa7a71a0c08c5ac84b00610ece1e5820322408870aeba3646534181cd016e7631af3d0c486e8822f67ef10856609557fb6532afbd775284f59a50af6b2869b7ca5cb5da0b26f36e41b7f4a3361371750a70052268080212144249abbc6cccb87ef36b481b3016ec33912901891a0c08c5ac84b00610a5faafb3032240a834a3efb9619ac1db9685bbc521baeb9813d1dad7682fcf006cd58c2ef45c8eacc9b9385751913a3e98951db1b1398dbc91f66cbf17a80814b15a0e2824e409226808021214c3266367ddf27040547dc92d5ebb1623caf2903d1a0c08c5ac84b00610dad3ceaa032240188e056696305f22a67d9904a067f0be7f87f1124ade527ef5d3060591379dba30fe57fc4aadf802104e6a2ca50f6a223f867c0fde5de2a7bb24ec21ccb3840422680802121483ee1db3ddc3112b91ee8d6e652cd5eef38c46e01a0c08c5ac84b00610e9db958b03224058a25bdb113d463cd40e59db67510699410caeb3bbef857db839aade920089259d4e941056c92e580295efec5ba048c8ac9a55d50d10de70276527cef1c3d50a2268080212145e56a5d935a9529b8999e1291c64b0ba3f9fd6631a0c08c5ac84b00610f7ac85ab032240da8b69eb538c660dbefb1efd4ecaf28d57867597666b1b2f6540c75b9d536c1484d28c6540f5c485b4ecc20b47f16631ebefd3375d7060fb1c74cba4f4d4e100226808021214fed8e547546670aa5256f64ea16d8bf1a340a5a31a0c08c5ac84b00610c4828da60322406d123b9e2f8162ce671174e124cb77b5f6ac23b7c540b1fe3c09f1dd38a700f2b43d2653c036fd3332e74484e917862a18880fc49c9a4590173c91bc89126a0f22680802121438fbd1eaedfbb5791314bc0661e3b9d145074d901a0c08c5ac84b0061093c98085032240af406ed28fcdbf4f6e1ad92519b72d170dc22bfc82771efd350780df40526811fddeabe3793007ef978b631bdf00ab7161833ca036d143da4e638edc39d80e0922680802121484b7580e977f1fd0448c4cbab82a7d3719367d571a0c08c5ac84b00610eb8d86b40322402f1a1d6f8af2949868ad0bd77365c4f6c24350b676882e523936a47faeac781fbe6d53222f6dd042a78423b7e7d2d3cd90ddb5fb6ffe141f8bae6ad2a70c930d226808021214c24fc0f3780141b5124c8a3bec39de645fb385e41a0c08c5ac84b00610a3e9fba7032240ef1ff6b813753376af4b67e184ee3fed97431a0e5c5696a99cc3a09e336ff714f00140f954960f5962b04e686902f9e420951ff44eaab73e079465fadb905b082268080212146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af81a0c08c5ac84b00610bcb9d4a20322403cba7354f25c17e980c55459ce5de1ac71f210e134d460642e422162e1dd8b692a86ac491ab562268b34e9a4859672d5cf7997903a5cb2ba94814982741b8203220f08011a0b088092b8c398feffffff01226808021214da250934d695a5a2457708f417f688ff8d9cc3261a0c08c5ac84b00610c0d7daac032240f9b9069ec79d2db8c9da98076d1512498c409f57d9d9df96ab7e3e1f8dab47d09cabdf75057f0f18c5953abfde4d16313cfb970d8156eb42dae960580e0f580a220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d21a0c08c5ac84b00610b0c5cea70322407154c18b984e0f75389b45f95d954e69348f63409bf051fb9cbb64649213602e294f9dfadbba3d46281473bb9a9ad01ad499a7539eee51d3bf1b165dbc24110e22680802121462683a7647539e61d001866edb1fb7152e1f79631a0c08c5ac84b00610a3ced5ad0322405d568927456830e6d1bac28dc454175f69993c2ae140fda1739ee1a12498fd8eeff23c636de597d703d1a3fc728c7139426b1634627ce9f0783458e7ba96ac0f226808021214b15aeec05b39196f3a972f5ab8b7c822e3336c3a1a0c08c5ac84b00610dae48ab00322404fd1cab90aa77443f1c7f16cfe829f6f53ffbbd1f2a0b7be4c1d1009b4a1fc433dc9cf40bc91ee6a054d92dc8805a977989d86f34f0d906bf8cf277550e7d50c226808021214f8933325d7838f9f70bf3ad2d8054ed2826cece51a0c08c5ac84b006109aeaa2a803224011a410d587d561a90d5ecd9d794c8c2b83ffcd4edadb5a0dffa5e9dc3b483193e9b760fc5d6ae85f05b1fc3302386a7ee7b06e89b719f1922e18b1c53ed9540a220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214a5af3f1e0814ef41b0613da1a8bafa20513723201a0c08c5ac84b0061085d3cfa703224022bc591f0043a4f15107ffcea4a3100aed1b27bea45541b59773ac2f4d9b1dc73db3158a5a128b7abd9741002207f58bba56027f2c769f97f6d6875a51d98a0b220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214fad3de3292c242997bf4000af8ffd4551272eb621a0c08c5ac84b00610d5f595fe022240a018672598c67c9ea1d14862e4f2c1fe84abc56724b5f855bd7582f8bce34081e11a8ce09d4d2bf08aacb28b39bb2d39dc541662aecd2e3df6ee228f286ffc00226808021214812dc4bd67175c2c4a74a13a4c6990fe41037a5b1a0c08c5ac84b00610d9a692b5032240384f5d91dd77fea058585a881b16c7ce31c19effb85304af002904b86987666f83e853263f3c46fdbdc2c8897a8ba2b6c9d8e0bdc945121385620da79c213b04220f08011a0b088092b8c398feffffff0122680802121430412ba7032186c3a2b1a6b440272e1d4780ab981a0c08c5ac84b00610e0b1e68d03224028370eb4cfb5dcd9aed66fc6db8dbe789a4025fb07aaf1f5b5f4a34463ca49ba2d18effada1b6751e8997709b7c6aff34b4c736c03264652b597558185d061002268080212148d5e2c42b5d2f9d8203f2a7e9173b5358952576a1a0c08c5ac84b00610c1d3bc9f0322400601d8877836d4e7508255146c1398b7627f3935235c9d13a00f2203e83cce64a90484dad6d6d4fb14f43232a7118e92f5cab96b7f5b3074d2ec9a7aad85050b220f08011a0b088092b8c398feffffff01226808021214330b0dee27003d8e8b24be39f82159f375127d321a0c08c5ac84b006109a81c0a603224042ee5c09a22b86a32cba7a5cff74b7e0dbc9cfbbb37faf41921c16af5592e32fd11bde5b1a86237bbfa786456e927de4940a2489e23b4bc5a4f34f82f17b330422680802121458b9f2517dbf8c55573fcfa9853fff27066d86ed1a0c08c5ac84b00610bb908ea20322403d32ba4d917430f76f20a50172bd47221c6359e3ecf4da5a098ba6dc99d1e558f3023e640b2d5cad9cce5857177745241ee9d459927cc5b2a4d79420eb639e0e220f08011a0b088092b8c398feffffff0122680802121458aff9ec275a66e7ad086d31e30fc59e02b94b921a0c08c5ac84b00610948887b20322400e70a330ba99a86d5419e4ed893ebed6aa62067c8cef32f17d4b200c1358f48d0d27106e1f3720146da4f423262a216d3f0f1b70b71c73c53b35f341c07fbd02220f08011a0b088092b8c398feffffff01226808021214ee2a8b5958586c495b1e7bf7ecfc284d83136c151a0c08c5ac84b00610f092ab8703224059e2e0d4331ec786e542c950b6da7dd0e757ba790a3beeba849bb9be2e979d06901b4fbd5dbd3be985cf85374f7367cbbb0376acd7640c867ff9f99854747f092268080212146d8f5894ab17dc6821a7d82c31a05d81b71c17391a0c08c5ac84b00610bfabfaa0032240f2c30fe5b8a0a4d64171ebf508ebbdc63a48110066a2dfb7f0d3c23d17b6738af902d6f8c337bc28c595ded70d2b2ca8049e68714974720400b8c2e2ff4f55092268080212143096bed304a51710ccde2dcdeb5c364c7559e7351a0c08c5ac84b0061086a690ab03224095d1ad85bea361349e57ec4fd4e10dbc1648e679c06d7ecc3b907fb33e342228e664ca182e9110b50175d6d6a21a2dc291437c1d24adfc5427d149d94617e30c226808021214c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f1a0c08c5ac84b00610f4dde9fe0222402233bd14a55b315bacbb57de5091a6948628851a1e630c9188967419b58745852dd0a73d8ceff4d7db35939c992b15a2993eaa435da4e6e2c9c8a3cba01e2109226808021214784cd03b935c7c3e75419b1f35b283e03faa7c0c1a0c08c5ac84b006108f81899c0322400ea212a580087311d4e13d4862d2957b448b31ec5ea34db1092076448f1701b5b23fe8e265aba9148e46205beb663d0c64d97252429338a8388e90b5a2fab70b220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212145245f51eeb87311e0544086e64df6e737afa01521a0c08c5ac84b00610f7f1faa50322401e147cd0d6d40d9fc280001c792b1b027179bda63ae43019256b1796ee8a40c06cd462887b2a1fd68935c3ee2981dc1a98cabc61ae71491d26abd3968886f004226808021214e7dc29639166155dc9ef5d562e44cefec2d169ca1a0c08c5ac84b00610dde093ab032240bac3c333026946c6cef7b263f9ee2a8834a45b7a366b09d1a126b211683a518586d71cf2752c4fa2e52cb6f0d77489db550be12e20caaf82dd789a47144b1803220f08011a0b088092b8c398feffffff0122680802121483a05569feb3c027db1f5e85c48073d6994040ee1a0c08c5ac84b00610c29ee5b30322403523860032e460064bc7a274826dbf67e4577967644266114696cd1ca01bcde0f1a029c53caee332e7ae620a202c1ed4dc7e44c5c5509598efe3ec1dc200e40f226808021214618ca0614c7ea885243f3580790708979be7bd451a0c08c5ac84b00610afa485a5032240973420c1533fb165fe2cc2b345eca839ef3cd3e98b6df638601fb0a64619f31c66dea36915962583f4f78d7742ea386b2702f15624bd4000c6da55782928b902226808021214f8426ee2307c31165cce1cc4da9762ae74f84ec11a0c08c5ac84b00610f7fed0b303224099a1ea5beea3f8f9afb8766f797fb65f71a4bad207ea275077fd4e37c54c31c4de63fc52536dbe4d69986f72da593bc081069e3f42f976a5014435fd96092804226808021214f063a67840c7d6411bd0c4b9603a1c6c7440d3f91a0c08c5ac84b0061082f3b58303224049f91e2c1a96f7675715b2347b9e2fe04c0c7f6b1f5fa66c3e77667caf8d327765f57f6c74bb08395a9e32b05faba764f4289eb44c107efafbc8f8e2c2b83504226808021214c7ed8e58ed8bbc7c0e9911bfaa38c725c00383641a0c08c5ac84b00610bac6e299032240b3c8e95e5b76ab342e1059bae1eec41f572492383c16592a9b09c74d80dfd800555489cb7e0f4697673dadc52237e49ecb69731e2a0368a6a6b239d6156cd406226808021214bdc269f2f62e3b02d6eb049bd2a11a425cfe3f291a0c08c5ac84b00610f182d9a70322402cc04249565c79527bf8a2784351eed93d111aaa111aea25a689ec924adbd55021afd1799fcd2fc9e560536204da4a25f095e651f527695bcc19c1d5106af40d220f08011a0b088092b8c398feffffff012268080212140808a48a93fba44a17029c17b16ad5cb1ccccfce1a0c08c5ac84b00610bd81ad8b032240912941700df39f699fc34b21faed36ce15627db84dde35cf78ca722cbbce6d874ea36d3575cbe8f747cae1dbb9b4d4136f876c5f719bb98cbbae40d0f82acd0b22680802121465a73fb6a5b297299393c8cc9a342242b13697441a0c08c5ac84b00610acdd889e032240752a924c7393e9ffab930c86f04f1655fe1e741ee7f82012bba78fe3e3d4f95457a28eff334a17e51f7b4d53499c852ef6950224f79b133a2c18303808778a03220f08011a0b088092b8c398feffffff0122680802121472f92fd75727431194c7129be2411a9093e6d57c1a0c08c5ac84b00610d6f0aec60322403ae6ed72d3224c9d276162630709ef68412e77a29c4c234ccdde0afcf97d74c7c22ba7d5f2743bea49a766008b3f8211289b76178f636e0bb4e8320d28b0130422680802121411c30fd0a3bda953d88a2157a69b2cab52b41f051a0c08c5ac84b00610cafeed860322402f5d7772ce53445c16156edddf5f2e2590fd089d3d4d8be0761a686b4c658b46ad4f856180ff59bb0098ab01a47e366ec6f42b5a6db83ebf824aa0cd712ad80b22680802121409d7dd253fe3ea53eb16a5c4492166688b3c65801a0c08c5ac84b0061080d8e5ac03224069ddedc5a33917d6a39d334acc752e318bc84c968b473ff769d895f1f6e1d0649d91a2ff141bcca83a7f62a157595d9d569c25029ada94cfaf9efe053e8bc304226808021214f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a1a0c08c5ac84b00610e5a0eea3032240324a9848b8a67cb786a7783b490d6698f4a0e793defcef6e572d5e4b03d6e9d1ce04fe78555eedc6376e7007382bfc3a41c29124a3760170d300688f81591b05220f08011a0b088092b8c398feffffff0112db320a3f0a14b1852d17fa66b5382a8f770725cc5b228b35775012220a20ec06936d55936aca5c041b091c7a311b1f3065bd2b65b60be25ed09104feb8f318f4d3aa060a3f0a142abc4854b1a1c5aa8403c4ea853a81aca901cc7612220a201addaecd87a7fdaf28bb67bc3533bc705bdfb52007365b7d67685f1d65030dde18a8eea8030a3f0a1425b40fd5ae2ac26b4382b746f6cddb8c73ce602512220a203183f39d70ce25f0a8ea02a762e43dd6fa8ec4037e1bd210acfb49570cd0666f18be80f7020a3f0a148dab929d392163909bfc1b2c8be1d4ff5b058f8612220a20e75d7c6c4a161f130000560c02ad4bfb70709ec2b625d3157a19c50a2987cf8e1896b3ed020a3f0a14408b9882eaa1e636bd48998340babe0153050cc312220a20b0d65ae97827e39346b7e0c6390d116301139a6e2d9a189c4edf26782621a38e18f18ad2020a3f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f3010a3f0a140549633adf0dd5e91ec75458cbeec35ae4331ad112220a20cdb58d6d7fa134d2dac24605a3d616d48fe41f8ed872f8e4c98e9037666db16918daf7ea010a3f0a14fd46533e10d45d8fbfda2588c70f927d2e44bc7912220a20e7de761f86056b4946d8d50100da0515061465b0b26cfafd5ddf97f71b41a86e18e7b9e8010a3f0a14fe1d612fc9c346e51fa20ed491ebd81162c0e11012220a20b017d03e09d1d7283fc27775ad243788236939851a5a326ea084fa62a80bbae618c2fac9010a3f0a1483337fa8c2a5bf1283a58384c0ccee0811919e0a12220a20147ee0dd6069170d26c95238e5a979a0ad370b68178926e806b17775cb5d38e018beb8c7010a3f0a1439d8e563c1af1285095ff5bee373e235d63d0cae12220a20e383ebbe5ff6bd0539f2e8618dbd95dd5da15a4147575da0215cf14f3f386b8c18f1a6c1010a3f0a1459835dcbb6ce79f1d12b86702e8690e5f5c514e512220a20e2e8b19d9012cbd9b00e9bdbd3195ea5107d730d5beb9eb771efaf4e0b3a1dee18bb93bd010a3f0a147bd85b0a30cfae183af900b65bc0ec0a28063c9912220a20c68b2e6e48b7049594cf7e6f24a4f2323d7356233a614e7cf7fd5101cc9be97f18edacb6010a3f0a140218a7a051c04fec85b4f92bfb00a8c4da1a9bd512220a203d94dcb94e8d15630e1934ae4fa0bb644f962bfc81b9d9be368882c1017f983e1885afad010a3f0a143596e89e65d41be8200b436c2986e97e9dd1ecce12220a2003512e3640974bc65e350e91c68b130e769ee58eef0f68eff9fd0763a08d441a18c6bb9d010a3f0a14923b8fcd3097ba253408cf32f8a77da355bbc86312220a204137811e4eaf4874c7d64915b28c174eeb7a1be95d314c7b7822f6f93ec5470518f18198010a3f0a14fe849f301b09dacebd2dce15d3ca34d6ba4ca47312220a20a6322cef180e269ebc624714d13c4955dbba0f408cd8e10d997dc7024494f80418f49c95010a3f0a142d9790447341f3371ad11b4b706332313cce33c312220a20d927b9a6b67b352b9c5747c6595766c1ad25c7708d04264aa17e3c580fd98b2718929894010a3f0a14dfe3e4385652c2f176ebe59c3dbe4198fd30da9012220a2072e20f388f16bae585240348109645b102e2f29ab77cbbce7817b5d123bd0df018f2fb92010a3f0a14536c4cc1cf97c4df693b3e7e6604bf0b14f4257e12220a2003c83e556021016aaaffc2f6aa48fdf788d033c3da0924cd21ccdf6dd5cf32d518f7868c010a3f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018e6ad8b010a3f0a14eab91d7b40213e14e850a90d7c28e662466dd7c612220a20d683dd49bf1096490b5ef089100917f040751afd2f698f161e1f80bc2db9511a18e58384010a3e0a142bded3e9a310eeedfb7d4db1778a9413e29d97b112220a20d854ff20e923fd27aeaea258d784afcb9d87c9fe3927d9ad5ae0b1669d1c2d751892bd780a3e0a141856685db8ac33cb29b9b1d35c034f16511d485012220a20e8527069a1e7bfbe25eaafafad88a1ed0f32db8e4e0a1669972c796f6cad6a4e1889a16b0a3e0a14fac8f77451006668f58b8937a73ae86aee68e25312220a20e408946e01267bc86fb50deacc86dafdaedb3a805a9c45eba47810700fadd18618cbd6610a3e0a14f8bf2150619f6d553ec0ee4427e09ae4cf085aef12220a20c7c5ffac225b15476f87b43d652e06304a965e7491d18fb0d9a0a6a208dbf8e818fffa5f0a3e0a14ebaaecf31ec18dc4234e01c82b749ae2cd7a957712220a20755b3e61036e77ae0f9d8b69df1a9cfc0e47c1fcc6bfdb15a675d47def8061fb18bdef5e0a3e0a14c3c730090bf75fc5bfdfbb4bd26589cf1c7b748712220a20f9bbb0bd1d1e5502d4c4c35da60e4f4a738e18ee28455c77888aac7fc3114a7a18a9ec530a3e0a14b4058eebe8da7015a6c0c29f3c53451563478fb712220a20f45743b9d87fdab24ccd8d07f917679c2d29d0f1e1d71113a5d4d93961fc4ea118f0b5500a3e0a14795ad41bb274e23b8d82b32b4f878c30ff76f3ee12220a202687ca37348621f6f0d7bb0d8181b6d7036887940813b7061ca7999a48bd1f8c1895a54c0a3e0a14fabfce1baa453eaf8255bedc5ee8eff464aa37b512220a208ba26509d1dbd124081bef7bde188ede90cb2ade0f6aefe1fe71193800ba962a18b381410a3e0a14706fab402d748242cd0a22b49012a6c039feec6512220a20243bafe50ae8db47bb23976a2aa10d8e60fbf66a6b3400239bfbf6709aad11d518e3d83d0a3e0a14b4fd96d19a44fe4b6b05370f200d89251fb68b4012220a20e738929a9dd600112b677dfee30227dc396c0683beb26cf7ad1c4d439ee972e31899da390a3e0a14aa6786a7b42270295639f5980e8c3648286caea212220a2096a759920df5363c9aee820cd5220ae927c60b510ec497653d3dbf6ec63c8a9f18a5bd390a3e0a149c29fe719923138d4a27bde5704563e45afc705d12220a207017fbc65e3fb62fbebc1b894125a9cd147a8f5cf87bd37590d70a64c7f6401218818e380a3e0a14a21ccd762306bb2651b2a24cfa15ae537c8c633f12220a207ac3ae3da8ea25e443879b5c1b321c3fb05a5c8f793925eec64aa650629e362418ee8b380a3e0a144451050fc63430d28fedd2a37f3ba16353c7e60a12220a204b534106cdefad4f0da9ee1eec2d7c2985ce1c0cfbd47d9461382afd729dc2bb18cd88360a3e0a14a6e68f4720f047480f3bee8502304baf0faaa7a712220a20b217c1303ec5ae61af90f6a8a72caa57b6e59c416f12e8d256dd904b429998ca18e3ce350a3e0a144249abbc6cccb87ef36b481b3016ec339129018912220a203b9674d593af41c481890f6e1fc3aa279cbe5d58eac58671f35734c59f3743c118d1e1330a3e0a14c3266367ddf27040547dc92d5ebb1623caf2903d12220a203aa92f59e180f35d9419add9a3ce6ad0a608541b811424aa85df565d2032c3af189aa3320a3e0a1483ee1db3ddc3112b91ee8d6e652cd5eef38c46e012220a20d6af075513a9e2d25972bc4893c4807336f3a00d98ebd3749980b1afedef30dc18e3b62e0a3e0a145e56a5d935a9529b8999e1291c64b0ba3f9fd66312220a2008983fbb9c4eeb900ad180158ca77242a29063669ae1a4a32641572ddfda83c91888a32d0a3e0a14fed8e547546670aa5256f64ea16d8bf1a340a5a312220a20f89aeac801b13028472b4733dde75e161b1bfc186b587c469097c0a66b431aba18fb872d0a3e0a1438fbd1eaedfbb5791314bc0661e3b9d145074d9012220a208db395073ffa6278e1c05481ad6a52d50468a90d94efa80b42348f3c62eb0e05189ba52c0a3e0a1484b7580e977f1fd0448c4cbab82a7d3719367d5712220a20eea097ce993a3c7a4e47141404bf14c149be585520e763c22f5cb34909cfbad418dcd4290a3e0a14c24fc0f3780141b5124c8a3bec39de645fb385e412220a20047bbb54c5e59a5b740162e0fa02d35efdde81994b5317100fd79214de3529001891e2270a3e0a146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af812220a20ed9d6aa7a16df68792b42371f386b5308c347f3e8e2f9301a857dfc3f1e72e4718b4d2270a3e0a14373328b487c327e51cb513e60a8a1c5fdaff5b3012220a20647bc426173aa99f2a5bcac2145078d050c7eb72d3b361a4aedf21ac0e5ebb9618aff9250a3e0a14da250934d695a5a2457708f417f688ff8d9cc32612220a20a5bc8d67cf595fe8d576257a97d3832df9fc480216a7df493366f92f8736a0ed18f696240a3e0a144198498bc2c20053e5aaaa4ce9cb7e3b93b8e85e12220a20f69e8798c93227eefb3ccf7efc20c3bd96cae139281f2e699f5b4de17878756c18bd99230a3e0a14e28bf9e8ff9ef17268d26a50f7cd998bee4db3f012220a20ea21311aa1f222afdaf21a2c5cfac248ac8fbe816354e466ac4fafb4f60a513218c8b1220a3e0a14fb2ef7e3b80bf63f9ddc9e2431addbcdc6e7644a12220a203f282143c907b1ef86202f71ffd761693a40748b26961ef5c94930b7cde0812118f1af210a3e0a1479efa8b65cb1f1aa69373ad3d01f442dcfcf938112220a20c85bd96888a6971f1bb95ca0f354f681584c883d7746a7fb312239bc1322d48318f1ac200a3e0a1480524f180664c5a1ac66bdd30bcedb36bbac096a12220a20b00c9552aa825e3e8d0bb9e230fb8e558eb54a0c6fc2b6dde7ea466199e954e018bca8200a3e0a14b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d212220a2030534ef00c64b39ab07df356961b4b6420733389a599242ee26e94de6c76dd7a18daa2200a3e0a1462683a7647539e61d001866edb1fb7152e1f796312220a205040fe5690b8fb12333f1d1b85180a52a9deffa01cf759b6d0efa4e420cdf33018bb9a200a3e0a14b15aeec05b39196f3a972f5ab8b7c822e3336c3a12220a203b9adeab28a2e7165d38299fe0eeb6fb0b6aba7cc201fd5d4955b1fcb56cf9e4189981200a3e0a14f8933325d7838f9f70bf3ad2d8054ed2826cece512220a200a3812c57d816fb4a3ec3686c3b306938d6c72bfce34a23154acd414fa37c5f7189deb1f0a3e0a140d97b64748720fe5d1ddf647ef06eba901caee8612220a20d395877c653467006556d1476ac4b68c9902364ab7fb6507a1a7758f56863cda18f8bf1f0a3e0a145b205289e6d60f7bf3fb4a15db5343da30a2509e12220a200b37c2a9a04bc6a04a68cee15624ced60f603b0939fa9c3ae3c7ddebe96140b5188dab1f0a3e0a14a5af3f1e0814ef41b0613da1a8bafa205137232012220a208ae4723213b340fb244a0d54f6d316aec71776d0fe2cc36d32436f752a1fd44018eca31f0a3e0a149dc49bd022e7e81dbcead966fff4f9af77052f2a12220a207a12ce70a7e988b9ec8ffe03d3ed4758875105bbf15ae78d5d2f46ae67464afd18efcf1e0a3e0a14fd1df5c5f5ea867fb21aa05c00926fabd2639e1612220a20dbb0e5b2016dd75f871ff64f4c8d472fc0da4289690f515f5f173aba8892ab3518d1ec1d0a3e0a14f7a35051ba1ce4f9d5b43157c522275dd90a454212220a2035e4cd35fd12e58f067b8852369bded41708336daca6c176bcbc7cdd8161057818ebab1d0a3e0a14fad3de3292c242997bf4000af8ffd4551272eb6212220a207024974db2eac3a6d3b1106acb52b39e21506c7e26c9f5a61fa86a45e86ce832188eba1c0a3e0a14812dc4bd67175c2c4a74a13a4c6990fe41037a5b12220a20458370b1f37e8de7fa4bae977b90a569285ffe1d37c0460e5b138ad2ecdd738518d6a21b0a3e0a143ded012b42f48947bbb2bd8eef7c0d69d217dce012220a20c2a41771f5e9612ed358c08e997f94be52a4486b6567816e9f50e9f686899b7e18eec5190a3e0a1430412ba7032186c3a2b1a6b440272e1d4780ab9812220a2032307c624e438a213e57ac577044cf328cbb305cc604693611092f77dfe13adf18ce99190a3e0a148d5e2c42b5d2f9d8203f2a7e9173b5358952576a12220a206afd4890886c667d79ee871ae1c1b2b83fdcc26c6fb1cda40695e2091157b152189087190a3e0a143c70fac7857389b869696e8f3e1f48be0be0242912220a20dfdd72d0732e60bf39286432b6b41fb10c0d8905d70897bf2291989e1eeac26518cbda170a3e0a14330b0dee27003d8e8b24be39f82159f375127d3212220a203db48acea4cb759b208b418b3e826ab9c75a77ca3fc7eeb647b84b1ea422308a18bbdc160a3e0a1458b9f2517dbf8c55573fcfa9853fff27066d86ed12220a20d0fa86b1e1eca13d135c07d3dc25814367bff1fafe25e8d8872897d6a0bde59018d79d140a3e0a146f23af09898a93352392cd0977bd5be5c74ef70912220a205ae5773928fed10cbf6f4d5f80d6533501b66736864a3b50e96c58021389b20818a3bc120a3e0a1458aff9ec275a66e7ad086d31e30fc59e02b94b9212220a20640499f5afeeb7ab49c601221c44fb762f3c02d05d5032bde7bab27823a5827718a7a4120a3e0a14e357f35a66a72eb8162f5a66ea221b9025ff56bc12220a20ac38b9ef0c5f7314dec03f8ad4d2fedd35f9d49bc5bb9de48832b55c00d6571518c3f3110a3e0a14ee2a8b5958586c495b1e7bf7ecfc284d83136c1512220a2099a8eeb2d17d0dff6b915cf6c65ffd563606dfd60640a35b8e082d40f67dca3318a683110a3e0a146d8f5894ab17dc6821a7d82c31a05d81b71c173912220a2065348bed02c217dacb610d4c8b7ae45d00389078b18df73e644174a0752c3c8418ceac100a3e0a143096bed304a51710ccde2dcdeb5c364c7559e73512220a20d77807b7263fd82cd116f733f78d7415eb08ac78be46a5e31d20b5285565bfee18ecf70e0a3e0a14c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f12220a20d61e7cdcfae95db114e7dce184ca3b11d59fc64b9163bc02bc8728631b4b5f5718c9e40e0a3e0a14784cd03b935c7c3e75419b1f35b283e03faa7c0c12220a205364bf153a2c5eb3e916bf62c327bbe782ee6b275863c9a11f8af39f7bef4eed18a2e00c0a3e0a142640a32bf68b7f9723e001c2e4b4e32e00b9467912220a209e5d22a072e232bf5c277dffa170ebc80db49d5496c0b638b6af2c01ea993c0c18b1dd0c0a3e0a14caab75b9c6d41e924cd1b526f5e2d123db756bc412220a2091da6ce3e1debed393e42c02a9641e42e965fe5b4095699c3db096049b29b4ea18d9c10c0a3e0a145245f51eeb87311e0544086e64df6e737afa015212220a203df173fba4427fd0acd8bc0f6c83f8f13a7944e5ad20c5f365c7390e5382313918acc00b0a3e0a14e7dc29639166155dc9ef5d562e44cefec2d169ca12220a203f0eb2d5e935320f269d5ab878104d36be1a2bc38d5ef1b2fe66760814a93c9818affd0a0a3e0a1457f61959ff8a08562bb0aba4921c5ef1b307dc6312220a20f5d18e7d52e05100d55e2f5fd0aa9fa8ba710f0801d7f605985b9732063b1c58188fee0a0a3e0a1483a05569feb3c027db1f5e85c48073d6994040ee12220a2087e931b901b4fb3d4733e821ad082d39d13930a1705baf4f5876a941e12f22dd18e3b30a0a3e0a14618ca0614c7ea885243f3580790708979be7bd4512220a200ec759549c85f6a5a4dbc79f7b112de4592dff74e9562d71c45a8fd3161dc9f318fbfc090a3e0a14f8426ee2307c31165cce1cc4da9762ae74f84ec112220a202cb896fc05f2f31a15a470963122fad880de8d26bff2a259291fb18af4d5914418dcf7090a3e0a14f063a67840c7d6411bd0c4b9603a1c6c7440d3f912220a20f9b393d098812877c926b72ffb2acea890ef4e8d321595c8b3f6d2b6ad92dff118a5ac090a3e0a14c7ed8e58ed8bbc7c0e9911bfaa38c725c003836412220a2060d20c0dd3ac3a21ffdbb7a4f0e6e704ff5fc0a6d11b10d1ee194b1a1fedbf7518e788090a3e0a14bdc269f2f62e3b02d6eb049bd2a11a425cfe3f2912220a203cb375c0722fd44d8da62db992e0bb34036e931ab217862892eca2cbcfbb2e9218eff9080a3e0a14c1976fefd48939e2327cbf83f367841028b95e0e12220a208aaa1c11dc4b43e95603cb10d9d24b6215e0232c5d87bb80539d440d6792e22618bb88080a3e0a140808a48a93fba44a17029c17b16ad5cb1ccccfce12220a20cdee5cd83bf3e85634a60f171c51cabba3fe76257605782eeb11d3a9d735c31a1899fd070a3e0a1465a73fb6a5b297299393c8cc9a342242b136974412220a207887710424a3375409f13d31bfed217c1524fb0db7c4f64db96671a5bdcebbc418e48d070a3e0a140c714e67a83273e3c3e35b17ca8ee140551a536012220a203452cde83ab0a21e43c9b749851e03b2ed0421aea710281711ca57d448af7bc218fc90060a3e0a1472f92fd75727431194c7129be2411a9093e6d57c12220a208ed5b1abd4aa4593dcb9c790927ac89f866e54c73d593554e13ef1efd86ab66918c0eb050a3e0a1411c30fd0a3bda953d88a2157a69b2cab52b41f0512220a2079e66631b3171534f3bce2430e6f9a87d83b94d0fcc4d21068dfcd3e2002df3e18d788040a3e0a1409d7dd253fe3ea53eb16a5c4492166688b3c658012220a20a24599a1f46bad5422ffb0d05e83a4394b602ffa007fe3393c985569ee7aa07f18acff030a3e0a14f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a12220a205556636b3bbc09f22e546840fa79d6628e36b4e4ff8d6978d9b274a5a92d932b18abfe020a3d0a1413a56fa6f11adaa2b09d97e57b36277319f22df012220a20315f78bea93b18884bab79e68711a9c05c67953b78788979e80c7fb1fc4caad618ab73123f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018e6ad8b0118d988be3e1a07080210c080b70722db320a3f0a14b1852d17fa66b5382a8f770725cc5b228b35775012220a20ec06936d55936aca5c041b091c7a311b1f3065bd2b65b60be25ed09104feb8f318edd3aa060a3f0a142abc4854b1a1c5aa8403c4ea853a81aca901cc7612220a201addaecd87a7fdaf28bb67bc3533bc705bdfb52007365b7d67685f1d65030dde1894eea8030a3f0a1425b40fd5ae2ac26b4382b746f6cddb8c73ce602512220a203183f39d70ce25f0a8ea02a762e43dd6fa8ec4037e1bd210acfb49570cd0666f189d80f7020a3f0a148dab929d392163909bfc1b2c8be1d4ff5b058f8612220a20e75d7c6c4a161f130000560c02ad4bfb70709ec2b625d3157a19c50a2987cf8e1891b3ed020a3f0a14408b9882eaa1e636bd48998340babe0153050cc312220a20b0d65ae97827e39346b7e0c6390d116301139a6e2d9a189c4edf26782621a38e18dc8ad2020a3f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f3010a3f0a140549633adf0dd5e91ec75458cbeec35ae4331ad112220a20cdb58d6d7fa134d2dac24605a3d616d48fe41f8ed872f8e4c98e9037666db16918daf7ea010a3f0a14fd46533e10d45d8fbfda2588c70f927d2e44bc7912220a20e7de761f86056b4946d8d50100da0515061465b0b26cfafd5ddf97f71b41a86e18dab9e8010a3f0a14fe1d612fc9c346e51fa20ed491ebd81162c0e11012220a20b017d03e09d1d7283fc27775ad243788236939851a5a326ea084fa62a80bbae618c2fac9010a3f0a1483337fa8c2a5bf1283a58384c0ccee0811919e0a12220a20147ee0dd6069170d26c95238e5a979a0ad370b68178926e806b17775cb5d38e018beb8c7010a3f0a1439d8e563c1af1285095ff5bee373e235d63d0cae12220a20e383ebbe5ff6bd0539f2e8618dbd95dd5da15a4147575da0215cf14f3f386b8c18f1a6c1010a3f0a1459835dcbb6ce79f1d12b86702e8690e5f5c514e512220a20e2e8b19d9012cbd9b00e9bdbd3195ea5107d730d5beb9eb771efaf4e0b3a1dee18b593bd010a3f0a147bd85b0a30cfae183af900b65bc0ec0a28063c9912220a20c68b2e6e48b7049594cf7e6f24a4f2323d7356233a614e7cf7fd5101cc9be97f18edacb6010a3f0a140218a7a051c04fec85b4f92bfb00a8c4da1a9bd512220a203d94dcb94e8d15630e1934ae4fa0bb644f962bfc81b9d9be368882c1017f983e1885afad010a3f0a143596e89e65d41be8200b436c2986e97e9dd1ecce12220a2003512e3640974bc65e350e91c68b130e769ee58eef0f68eff9fd0763a08d441a18c6bb9d010a3f0a14923b8fcd3097ba253408cf32f8a77da355bbc86312220a204137811e4eaf4874c7d64915b28c174eeb7a1be95d314c7b7822f6f93ec5470518f18198010a3f0a14fe849f301b09dacebd2dce15d3ca34d6ba4ca47312220a20a6322cef180e269ebc624714d13c4955dbba0f408cd8e10d997dc7024494f80418f49c95010a3f0a142d9790447341f3371ad11b4b706332313cce33c312220a20d927b9a6b67b352b9c5747c6595766c1ad25c7708d04264aa17e3c580fd98b2718f29794010a3f0a14dfe3e4385652c2f176ebe59c3dbe4198fd30da9012220a2072e20f388f16bae585240348109645b102e2f29ab77cbbce7817b5d123bd0df018f2fb92010a3f0a14536c4cc1cf97c4df693b3e7e6604bf0b14f4257e12220a2003c83e556021016aaaffc2f6aa48fdf788d033c3da0924cd21ccdf6dd5cf32d518f7868c010a3f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018ddad8b010a3f0a14eab91d7b40213e14e850a90d7c28e662466dd7c612220a20d683dd49bf1096490b5ef089100917f040751afd2f698f161e1f80bc2db9511a18e58384010a3e0a142bded3e9a310eeedfb7d4db1778a9413e29d97b112220a20d854ff20e923fd27aeaea258d784afcb9d87c9fe3927d9ad5ae0b1669d1c2d751892bd780a3e0a141856685db8ac33cb29b9b1d35c034f16511d485012220a20e8527069a1e7bfbe25eaafafad88a1ed0f32db8e4e0a1669972c796f6cad6a4e1889a16b0a3e0a14fac8f77451006668f58b8937a73ae86aee68e25312220a20e408946e01267bc86fb50deacc86dafdaedb3a805a9c45eba47810700fadd18618cbd6610a3e0a14f8bf2150619f6d553ec0ee4427e09ae4cf085aef12220a20c7c5ffac225b15476f87b43d652e06304a965e7491d18fb0d9a0a6a208dbf8e818fefa5f0a3e0a14ebaaecf31ec18dc4234e01c82b749ae2cd7a957712220a20755b3e61036e77ae0f9d8b69df1a9cfc0e47c1fcc6bfdb15a675d47def8061fb18bdef5e0a3e0a14c3c730090bf75fc5bfdfbb4bd26589cf1c7b748712220a20f9bbb0bd1d1e5502d4c4c35da60e4f4a738e18ee28455c77888aac7fc3114a7a18a7ec530a3e0a14b4058eebe8da7015a6c0c29f3c53451563478fb712220a20f45743b9d87fdab24ccd8d07f917679c2d29d0f1e1d71113a5d4d93961fc4ea118f0b5500a3e0a14795ad41bb274e23b8d82b32b4f878c30ff76f3ee12220a202687ca37348621f6f0d7bb0d8181b6d7036887940813b7061ca7999a48bd1f8c1895a54c0a3e0a14fabfce1baa453eaf8255bedc5ee8eff464aa37b512220a208ba26509d1dbd124081bef7bde188ede90cb2ade0f6aefe1fe71193800ba962a18b381410a3e0a14706fab402d748242cd0a22b49012a6c039feec6512220a20243bafe50ae8db47bb23976a2aa10d8e60fbf66a6b3400239bfbf6709aad11d518e3d83d0a3e0a14b4fd96d19a44fe4b6b05370f200d89251fb68b4012220a20e738929a9dd600112b677dfee30227dc396c0683beb26cf7ad1c4d439ee972e31898da390a3e0a14aa6786a7b42270295639f5980e8c3648286caea212220a2096a759920df5363c9aee820cd5220ae927c60b510ec497653d3dbf6ec63c8a9f18a5bd390a3e0a149c29fe719923138d4a27bde5704563e45afc705d12220a207017fbc65e3fb62fbebc1b894125a9cd147a8f5cf87bd37590d70a64c7f6401218808e380a3e0a14a21ccd762306bb2651b2a24cfa15ae537c8c633f12220a207ac3ae3da8ea25e443879b5c1b321c3fb05a5c8f793925eec64aa650629e362418ee8b380a3e0a144451050fc63430d28fedd2a37f3ba16353c7e60a12220a204b534106cdefad4f0da9ee1eec2d7c2985ce1c0cfbd47d9461382afd729dc2bb18cd88360a3e0a14a6e68f4720f047480f3bee8502304baf0faaa7a712220a20b217c1303ec5ae61af90f6a8a72caa57b6e59c416f12e8d256dd904b429998ca18e3ce350a3e0a144249abbc6cccb87ef36b481b3016ec339129018912220a203b9674d593af41c481890f6e1fc3aa279cbe5d58eac58671f35734c59f3743c118d1e1330a3e0a14c3266367ddf27040547dc92d5ebb1623caf2903d12220a203aa92f59e180f35d9419add9a3ce6ad0a608541b811424aa85df565d2032c3af189aa3320a3e0a1483ee1db3ddc3112b91ee8d6e652cd5eef38c46e012220a20d6af075513a9e2d25972bc4893c4807336f3a00d98ebd3749980b1afedef30dc18e3b62e0a3e0a145e56a5d935a9529b8999e1291c64b0ba3f9fd66312220a2008983fbb9c4eeb900ad180158ca77242a29063669ae1a4a32641572ddfda83c91888a32d0a3e0a14fed8e547546670aa5256f64ea16d8bf1a340a5a312220a20f89aeac801b13028472b4733dde75e161b1bfc186b587c469097c0a66b431aba18fb872d0a3e0a1438fbd1eaedfbb5791314bc0661e3b9d145074d9012220a208db395073ffa6278e1c05481ad6a52d50468a90d94efa80b42348f3c62eb0e05189ba52c0a3e0a1484b7580e977f1fd0448c4cbab82a7d3719367d5712220a20eea097ce993a3c7a4e47141404bf14c149be585520e763c22f5cb34909cfbad418dcd4290a3e0a14c24fc0f3780141b5124c8a3bec39de645fb385e412220a20047bbb54c5e59a5b740162e0fa02d35efdde81994b5317100fd79214de3529001891e2270a3e0a146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af812220a20ed9d6aa7a16df68792b42371f386b5308c347f3e8e2f9301a857dfc3f1e72e4718b4d2270a3e0a14373328b487c327e51cb513e60a8a1c5fdaff5b3012220a20647bc426173aa99f2a5bcac2145078d050c7eb72d3b361a4aedf21ac0e5ebb9618aff9250a3e0a14da250934d695a5a2457708f417f688ff8d9cc32612220a20a5bc8d67cf595fe8d576257a97d3832df9fc480216a7df493366f92f8736a0ed18f696240a3e0a144198498bc2c20053e5aaaa4ce9cb7e3b93b8e85e12220a20f69e8798c93227eefb3ccf7efc20c3bd96cae139281f2e699f5b4de17878756c18bd99230a3e0a14e28bf9e8ff9ef17268d26a50f7cd998bee4db3f012220a20ea21311aa1f222afdaf21a2c5cfac248ac8fbe816354e466ac4fafb4f60a513218c8b1220a3e0a14fb2ef7e3b80bf63f9ddc9e2431addbcdc6e7644a12220a203f282143c907b1ef86202f71ffd761693a40748b26961ef5c94930b7cde0812118f1af210a3e0a1479efa8b65cb1f1aa69373ad3d01f442dcfcf938112220a20c85bd96888a6971f1bb95ca0f354f681584c883d7746a7fb312239bc1322d48318f1ac200a3e0a1480524f180664c5a1ac66bdd30bcedb36bbac096a12220a20b00c9552aa825e3e8d0bb9e230fb8e558eb54a0c6fc2b6dde7ea466199e954e018aba8200a3e0a14b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d212220a2030534ef00c64b39ab07df356961b4b6420733389a599242ee26e94de6c76dd7a18daa2200a3e0a1462683a7647539e61d001866edb1fb7152e1f796312220a205040fe5690b8fb12333f1d1b85180a52a9deffa01cf759b6d0efa4e420cdf33018bb9a200a3e0a14b15aeec05b39196f3a972f5ab8b7c822e3336c3a12220a203b9adeab28a2e7165d38299fe0eeb6fb0b6aba7cc201fd5d4955b1fcb56cf9e4189981200a3e0a14f8933325d7838f9f70bf3ad2d8054ed2826cece512220a200a3812c57d816fb4a3ec3686c3b306938d6c72bfce34a23154acd414fa37c5f7189deb1f0a3e0a140d97b64748720fe5d1ddf647ef06eba901caee8612220a20d395877c653467006556d1476ac4b68c9902364ab7fb6507a1a7758f56863cda18f8bf1f0a3e0a145b205289e6d60f7bf3fb4a15db5343da30a2509e12220a200b37c2a9a04bc6a04a68cee15624ced60f603b0939fa9c3ae3c7ddebe96140b5188dab1f0a3e0a14a5af3f1e0814ef41b0613da1a8bafa205137232012220a208ae4723213b340fb244a0d54f6d316aec71776d0fe2cc36d32436f752a1fd44018eca31f0a3e0a149dc49bd022e7e81dbcead966fff4f9af77052f2a12220a207a12ce70a7e988b9ec8ffe03d3ed4758875105bbf15ae78d5d2f46ae67464afd18efcf1e0a3e0a14fd1df5c5f5ea867fb21aa05c00926fabd2639e1612220a20dbb0e5b2016dd75f871ff64f4c8d472fc0da4289690f515f5f173aba8892ab3518d0ec1d0a3e0a14f7a35051ba1ce4f9d5b43157c522275dd90a454212220a2035e4cd35fd12e58f067b8852369bded41708336daca6c176bcbc7cdd8161057818ebab1d0a3e0a14fad3de3292c242997bf4000af8ffd4551272eb6212220a207024974db2eac3a6d3b1106acb52b39e21506c7e26c9f5a61fa86a45e86ce832188eba1c0a3e0a14812dc4bd67175c2c4a74a13a4c6990fe41037a5b12220a20458370b1f37e8de7fa4bae977b90a569285ffe1d37c0460e5b138ad2ecdd738518d6a21b0a3e0a143ded012b42f48947bbb2bd8eef7c0d69d217dce012220a20c2a41771f5e9612ed358c08e997f94be52a4486b6567816e9f50e9f686899b7e18eec5190a3e0a1430412ba7032186c3a2b1a6b440272e1d4780ab9812220a2032307c624e438a213e57ac577044cf328cbb305cc604693611092f77dfe13adf18ce99190a3e0a148d5e2c42b5d2f9d8203f2a7e9173b5358952576a12220a206afd4890886c667d79ee871ae1c1b2b83fdcc26c6fb1cda40695e2091157b152189087190a3e0a143c70fac7857389b869696e8f3e1f48be0be0242912220a20dfdd72d0732e60bf39286432b6b41fb10c0d8905d70897bf2291989e1eeac26518cbda170a3e0a14330b0dee27003d8e8b24be39f82159f375127d3212220a203db48acea4cb759b208b418b3e826ab9c75a77ca3fc7eeb647b84b1ea422308a18bbdc160a3e0a1458b9f2517dbf8c55573fcfa9853fff27066d86ed12220a20d0fa86b1e1eca13d135c07d3dc25814367bff1fafe25e8d8872897d6a0bde59018d79d140a3e0a146f23af09898a93352392cd0977bd5be5c74ef70912220a205ae5773928fed10cbf6f4d5f80d6533501b66736864a3b50e96c58021389b20818a3bc120a3e0a1458aff9ec275a66e7ad086d31e30fc59e02b94b9212220a20640499f5afeeb7ab49c601221c44fb762f3c02d05d5032bde7bab27823a5827718a7a4120a3e0a14e357f35a66a72eb8162f5a66ea221b9025ff56bc12220a20ac38b9ef0c5f7314dec03f8ad4d2fedd35f9d49bc5bb9de48832b55c00d6571518c3f3110a3e0a14ee2a8b5958586c495b1e7bf7ecfc284d83136c1512220a2099a8eeb2d17d0dff6b915cf6c65ffd563606dfd60640a35b8e082d40f67dca3318a683110a3e0a146d8f5894ab17dc6821a7d82c31a05d81b71c173912220a2065348bed02c217dacb610d4c8b7ae45d00389078b18df73e644174a0752c3c8418ceac100a3e0a143096bed304a51710ccde2dcdeb5c364c7559e73512220a20d77807b7263fd82cd116f733f78d7415eb08ac78be46a5e31d20b5285565bfee18ecf70e0a3e0a14c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f12220a20d61e7cdcfae95db114e7dce184ca3b11d59fc64b9163bc02bc8728631b4b5f5718c9e40e0a3e0a14784cd03b935c7c3e75419b1f35b283e03faa7c0c12220a205364bf153a2c5eb3e916bf62c327bbe782ee6b275863c9a11f8af39f7bef4eed18a2e00c0a3e0a142640a32bf68b7f9723e001c2e4b4e32e00b9467912220a209e5d22a072e232bf5c277dffa170ebc80db49d5496c0b638b6af2c01ea993c0c18b1dd0c0a3e0a14caab75b9c6d41e924cd1b526f5e2d123db756bc412220a2091da6ce3e1debed393e42c02a9641e42e965fe5b4095699c3db096049b29b4ea18d9c10c0a3e0a145245f51eeb87311e0544086e64df6e737afa015212220a203df173fba4427fd0acd8bc0f6c83f8f13a7944e5ad20c5f365c7390e5382313918acc00b0a3e0a14e7dc29639166155dc9ef5d562e44cefec2d169ca12220a203f0eb2d5e935320f269d5ab878104d36be1a2bc38d5ef1b2fe66760814a93c9818affd0a0a3e0a1457f61959ff8a08562bb0aba4921c5ef1b307dc6312220a20f5d18e7d52e05100d55e2f5fd0aa9fa8ba710f0801d7f605985b9732063b1c58188fee0a0a3e0a1483a05569feb3c027db1f5e85c48073d6994040ee12220a2087e931b901b4fb3d4733e821ad082d39d13930a1705baf4f5876a941e12f22dd18e3b30a0a3e0a14618ca0614c7ea885243f3580790708979be7bd4512220a200ec759549c85f6a5a4dbc79f7b112de4592dff74e9562d71c45a8fd3161dc9f318fbfc090a3e0a14f8426ee2307c31165cce1cc4da9762ae74f84ec112220a202cb896fc05f2f31a15a470963122fad880de8d26bff2a259291fb18af4d5914418dcf7090a3e0a14f063a67840c7d6411bd0c4b9603a1c6c7440d3f912220a20f9b393d098812877c926b72ffb2acea890ef4e8d321595c8b3f6d2b6ad92dff118a5ac090a3e0a14c7ed8e58ed8bbc7c0e9911bfaa38c725c003836412220a2060d20c0dd3ac3a21ffdbb7a4f0e6e704ff5fc0a6d11b10d1ee194b1a1fedbf7518e788090a3e0a14bdc269f2f62e3b02d6eb049bd2a11a425cfe3f2912220a203cb375c0722fd44d8da62db992e0bb34036e931ab217862892eca2cbcfbb2e9218eff9080a3e0a14c1976fefd48939e2327cbf83f367841028b95e0e12220a208aaa1c11dc4b43e95603cb10d9d24b6215e0232c5d87bb80539d440d6792e22618bb88080a3e0a140808a48a93fba44a17029c17b16ad5cb1ccccfce12220a20cdee5cd83bf3e85634a60f171c51cabba3fe76257605782eeb11d3a9d735c31a1899fd070a3e0a1465a73fb6a5b297299393c8cc9a342242b136974412220a207887710424a3375409f13d31bfed217c1524fb0db7c4f64db96671a5bdcebbc418da8d070a3e0a140c714e67a83273e3c3e35b17ca8ee140551a536012220a203452cde83ab0a21e43c9b749851e03b2ed0421aea710281711ca57d448af7bc218fc90060a3e0a1472f92fd75727431194c7129be2411a9093e6d57c12220a208ed5b1abd4aa4593dcb9c790927ac89f866e54c73d593554e13ef1efd86ab66918bceb050a3e0a1411c30fd0a3bda953d88a2157a69b2cab52b41f0512220a2079e66631b3171534f3bce2430e6f9a87d83b94d0fcc4d21068dfcd3e2002df3e18d788040a3e0a1409d7dd253fe3ea53eb16a5c4492166688b3c658012220a20a24599a1f46bad5422ffb0d05e83a4394b602ffa007fe3393c985569ee7aa07f18acff030a3e0a14f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a12220a205556636b3bbc09f22e546840fa79d6628e36b4e4ff8d6978d9b274a5a92d932b18abfe020a3d0a1413a56fa6f11adaa2b09d97e57b36277319f22df012220a20315f78bea93b18884bab79e68711a9c05c67953b78788979e80c7fb1fc4caad618ab73123f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f30118a287be3e" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "ibc_client" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/ibc.core.channel.v1.MsgAcknowledgement" + }, + { + "key": "sender", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" + } + ] + }, + { + "type": "acknowledge_packet", + "attributes": [ + { + "key": "connection_id", + "value": "connection-75" + }, + { + "key": "packet_channel_ordering", + "value": "ORDER_UNORDERED" + }, + { + "key": "packet_connection", + "value": "connection-75" + }, + { + "key": "packet_dst_channel", + "value": "channel-126" + }, + { + "key": "packet_dst_port", + "value": "transfer" + }, + { + "key": "packet_sequence", + "value": "988" + }, + { + "key": "packet_src_channel", + "value": "channel-104" + }, + { + "key": "packet_src_port", + "value": "transfer" + }, + { + "key": "packet_timeout_height", + "value": "0-0" + }, + { + "key": "packet_timeout_timestamp", + "value": "1711347430185000000" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "ibc_channel" + } + ] + }, + { + "type": "fungible_token_packet", + "attributes": [ + { + "key": "acknowledgement", + "value": "result:\"\\001\" " + }, + { + "key": "amount", + "value": "27978000" + }, + { + "key": "denom", + "value": "transfer/channel-104/uakt" + }, + { + "key": "memo", + "value": "" + }, + { + "key": "module", + "value": "transfer" + }, + { + "key": "receiver", + "value": "akash1t8np6xr8qr24yjyp3lkg9j4wyeazgf6frrzx4u" + }, + { + "key": "sender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "fungible_token_packet", + "attributes": [ + { + "key": "success", + "value": "\u0001" + } + ] + } + ], + "codespace": "" + } + ], + "begin_block_events": [ + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "20456465438196201488aarch" + }, + { + "key": "receiver", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coinbase", + "attributes": [ + { + "key": "amount", + "value": "20456465438196201488aarch" + }, + { + "key": "minter", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "spender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "spender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "receiver", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "recipient", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + }, + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "archway.rewards.v1.MinConsensusFeeSetEvent", + "attributes": [ + { + "key": "fee", + "value": "{\"denom\":\"aarch\",\"amount\":\"34094109063.660335813333333333\"}" + } + ] + }, + { + "type": "mint", + "attributes": [ + { + "key": "amount", + "value": "20456465438196201488" + }, + { + "key": "annual_provisions", + "value": "107592825618736741349012839.100000000000000000" + }, + { + "key": "bonded_ratio", + "value": "0.476278464914987794" + }, + { + "key": "inflation", + "value": "0.100000000000000000" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "spender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "receiver", + "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "recipient", + "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" + }, + { + "key": "sender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "47031267452693036.061160109957597621aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "940625349053860721.223202199151952412aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "38476736132757653.641375706228733112aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "769534722655153072.827514124574662242aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "25198563408572443.297487568120742094aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "503971268171448865.949751362414841889aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "38385179966923893.758115958837052080aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "479814749586548671.976449485463151006aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "20848080058682149.927238603944519387aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "416961601173642998.544772078890387735aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "18078103662935996.564316767356891825aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "361562073258719931.286335347137836505aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "16397185525293103.453610095140066692aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "327943710505862069.072201902801333835aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "321840969895750362.322698020897468527aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "321840969895750362.322698020897468527aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "15497002790178990.382878376219577609aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "309940055803579807.657567524391552185aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "14382002009562408.966451471365272199aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "287640040191248179.329029427305443980aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13893332467457515.070627762265926164aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "277866649349150301.412555245318523271aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13770849876624121.332192990936737311aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "275416997532482426.643859818734746213aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "12930798182518861.484757122871543030aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "258615963650377229.695142457430860592aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "12030364971758872.030268279538284386aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "240607299435177440.605365590765687724aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11189751818200215.104161320082748986aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "223795036364004302.083226401654979719aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "22284930786917069.309869240938732002aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "222849307869170693.098692409387320015aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "10622762200262906.250589114950164761aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "212455244005258125.011782299003295211aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "20593888085947895.310473392523510734aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "205938880859478953.104733925235107341aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "10233575111733853.664058333319530926aarch" + }, + { + "key": "validator", + "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "204671502234677073.281166666390618516aarch" + }, + { + "key": "validator", + "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9990294308427255.981021251439344373aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "199805886168545119.620425028786887454aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9956509646731535.147278403734301398aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "199130192934630702.945568074686027966aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "19126950729710299.665644427976706534aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "191269507297102996.656444279767065337aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3795328565503973.184141327894708544aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "189766428275198659.207066394735427181aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9442139614759897.331870324410660370aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "188842792295197946.637406488213207399aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "37171458291268257.131570065986651951aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "185857291456341285.657850329933259756aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8909997069263457.716045493806167155aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "178199941385269154.320909876123343102aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8410863836693763.423641845394010617aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "168217276733875268.472836907880212335aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "16287634795052974.555039143568147364aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "162876347950529745.550391435681473638aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8116318548809015.185851059708506321aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "162326370976180303.717021194170126423aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "14106818207670570.608562862410733280aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "156742424529673006.761809582341480886aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7817509546278174.286098972010596527aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "156350190925563485.721979440211930538aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7698025627362544.745416469488871318aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "153960512547250894.908329389777426363aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "1468691530058656.639589777369466772aarch" + }, + { + "key": "validator", + "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "146869153005865663.958977736946677172aarch" + }, + { + "key": "validator", + "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13254946033113129.332220275501974624aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "132549460331131293.322202755019746245aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6528176308965305.138762208357045787aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "130563526179306102.775244167140915739aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6427765125466552.035382663728815800aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "128555302509331040.707653274576315992aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6369673068788454.612640168190546461aarch" + }, + { + "key": "validator", + "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "127393461375769092.252803363810929221aarch" + }, + { + "key": "validator", + "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "12731049483598902.774539034875018554aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "127310494835989027.745390348750185539aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6188648127981006.239817584115334679aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "123772962559620124.796351682306693584aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6111735218698457.658597005193378472aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "122234704373969153.171940103867569443aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11920977472838526.728569377167360808aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "119209774728385267.285693771673608080aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11798931103635591.155836728325712191aarch" + }, + { + "key": "validator", + "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "117989311036355911.558367283257121914aarch" + }, + { + "key": "validator", + "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5734886166478625.892898092108881652aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "114697723329572517.857961842177633032aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9032987084354732.600540116550070865aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "112912338554434157.506751456875885809aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5622139761003751.922093399217840541aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "112442795220075038.441867984356810827aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5467151622868464.860068008108763923aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "109343032457369297.201360162175278454aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5147485597735517.675781608689883791aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "102949711954710353.515632173797675817aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5061348711718600.465891267895790323aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "101226974234372009.317825357915806467aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5029050017899537.493160438270993264aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "100581000357990749.863208765419865282aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4959406531013593.852444214136180672aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "99188130620271877.048884282723613441aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4784203038222939.406288267155309764aarch" + }, + { + "key": "validator", + "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "95684060764458788.125765343106195284aarch" + }, + { + "key": "validator", + "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4660416003997820.740312005440280988aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "93208320079956414.806240108805619764aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9300475936685287.242513541288714658aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "93004759366852872.425135412887146582aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4626325987160778.397378224627902136aarch" + }, + { + "key": "validator", + "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "92526519743215567.947564492558042714aarch" + }, + { + "key": "validator", + "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "902962733350027.401752135061459718aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "90296273335002740.175213506145971754aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8912165512916799.835861475013525979aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "89121655129167998.358614750135259792aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8781155492791221.494594506355942232aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "87811554927912214.945945063559422315aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6899333091057620.960224373610959541aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "86241663638220262.002804670136994266aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4310085005410204.100167898860593316aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "86201700108204082.003357977211866318aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4165137000608207.977714955807129321aarch" + }, + { + "key": "validator", + "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "83302740012164159.554299116142586422aarch" + }, + { + "key": "validator", + "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "823400410887391.655444942037895916aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "82340041088739165.544494203789591620aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8110953022754377.656552773692154718aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "81109530227543776.565527736921547177aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4049923832171419.900874945961500186aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "80998476643428398.017498919230003713aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4046835101594465.126102101748185146aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "80936702031889302.522042034963702927aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4015504538361708.968609533070971737aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "80310090767234179.372190661419434749aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3989445221024750.193829797927477751aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "79788904420495003.876595958549555022aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7819950980242190.974745026504499838aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "78199509802421909.747450265044998376aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3893314638170688.030671063618776405aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "77866292763413760.613421272375528109aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7356227686733312.614918000804230323aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "73562276867333126.149180008042303234aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3651595789734440.460813787200889911aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "73031915794688809.216275744017798219aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6336760568920340.042851852762609760aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "70408450765781556.031687252917886220aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3257159969974389.397733527606727682aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "65143199399487787.954670552134553635aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3241903470240747.643062868104794157aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "64838069404814952.861257362095883149aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6479357479850821.563309842818828243aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "64793574798508215.633098428188282433aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3181101210787609.253499528559273910aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "63622024215752185.069990571185478197aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6341244082981521.831817288858422522aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "63412440829815218.318172888584225217aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5963842014307592.847667445233562256aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "59638420143075928.476674452335622559aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5748320385530191.674253504092312988aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "57483203855301916.742535040923129879aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2852413840903474.221838280346566438aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "57048276818069484.436765606931328767aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2815496826467752.580425254170529570aarch" + }, + { + "key": "validator", + "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "56309936529355051.608505083410591406aarch" + }, + { + "key": "validator", + "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2778202691396666.747218384581883466aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "55564053827933334.944367691637669328aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2694434066683173.206122624486548955aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "53888681333663464.122452489730979101aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2652887474298394.524581334018800918aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "53057749485967890.491626680376018355aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4945956833129978.687897043942664985aarch" + }, + { + "key": "validator", + "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "49459568331299786.878970439426649847aarch" + }, + { + "key": "validator", + "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2348424476570194.306780348897158990aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "46968489531403886.135606977943179798aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4466388844269614.461180848095981218aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "44663888442696144.611808480959812180aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4410639719897042.568753264099370019aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "44106397198970425.687532640993700187aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2180926627806602.966830879190971933aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43618532556132059.336617583819438666aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4334790628526192.728785775490332845aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43347906285261927.287857754903328446aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4317353020640258.703423690157865934aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43173530206402587.034236901578659340aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4310621135865702.319268914397417516aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43106211358657023.192689143974175157aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2151546397411960.927938840521971384aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43030927948239218.558776810439427683aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4276970154992218.095443976355904791aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42769701549922180.954439763559047908aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4227209931455874.017210362427827103aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42272099314558740.172103624278271034aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4224035363719377.513891413189025352aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42240353637193775.138914131890253522aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "" + }, + { + "key": "validator", + "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "36137022017131114.228519325308756161aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3577726581699250.284220154744698892aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "35777265816992502.842201547446988919aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2466956306598184.675480716666651432aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "35242232951402638.221153095237877595aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "983390744674140.023941688397971514aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "32779691489138000.798056279932383792aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "1717680363758128.131106183256179516aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1yw5nl74hv609enqxsn70k55p3pychyc9cvznds" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "17176803637581281.311061832561795160aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1yw5nl74hv609enqxsn70k55p3pychyc9cvznds" + } + ] + } + ], + "end_block_events": [ + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "spender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "receiver", + "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "recipient", + "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" + }, + { + "key": "sender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + } + ], + "validator_updates": null, + "consensus_param_updates": { + "block": { + "max_bytes": "22020096", + "max_gas": "300000000" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000", + "max_bytes": "1048576" + }, + "validator": { + "pub_key_types": ["ed25519"] + } + } + } + } +} diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index fd532a1c0..f802f5ce8 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -267,6 +267,40 @@ export function wrapBlockBeginAndEndEvents( }, ); } +// TODO this should be replacing the current implementation, but then, the rpc request should be source of truth. +export function kyveWrapEvent( + block: CosmosBlock, + txs: CosmosTransaction[], + api: CosmosClient, + idxOffset: number, //use this offset to avoid clash with idx of begin block events +): CosmosEvent[] { + const events: CosmosEvent[] = []; + for (const tx of txs) { + let msgIndex = -1; + for (const event of tx.tx.events) { + if ( + event.type === 'message' && + event.attributes.find((e) => e.key === 'action') + ) { + msgIndex += 1; + } + + if (msgIndex >= 0) { + const msg = wrapCosmosMsg(block, tx, msgIndex, api); + const cosmosEvent: CosmosEvent = { + idx: idxOffset++, + msg, + tx, + block, + log: undefined, + event, + }; + events.push(cosmosEvent); + } + } + } + return events; +} export function wrapEvent( block: CosmosBlock, @@ -368,6 +402,7 @@ export class LazyBlockContent implements BlockContent { private _blockInfo: BlockResponse, private _results: BlockResultsResponse, private _api: CosmosClient, + private _kyveBlock = false, ) {} get block() { @@ -395,12 +430,14 @@ export class LazyBlockContent implements BlockContent { get events() { if (!this._wrappedEvent) { - this._wrappedEvent = wrapEvent( - this.block, - this.transactions, - this._api, - this._eventIdx, - ); + this._wrappedEvent = this._kyveBlock + ? kyveWrapEvent( + this.block, + this.transactions, + this._api, + this._eventIdx, + ) + : wrapEvent(this.block, this.transactions, this._api, this._eventIdx); this._eventIdx += this._wrappedEvent.length; } return this._wrappedEvent; diff --git a/packages/node/src/utils/kyve.spec.ts b/packages/node/src/utils/kyve.spec.ts index f4349c920..b73d558d0 100644 --- a/packages/node/src/utils/kyve.spec.ts +++ b/packages/node/src/utils/kyve.spec.ts @@ -18,22 +18,35 @@ import { HttpClient } from '../indexer/rpc-clients'; import { LazyBlockContent } from './cosmos'; import { KyveApi } from './kyve'; +const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ + ['/cosmwasm.wasm.v1.MsgClearAdmin', MsgClearAdmin], + ['/cosmwasm.wasm.v1.MsgExecuteContract', MsgExecuteContract], + ['/cosmwasm.wasm.v1.MsgMigrateContract', MsgMigrateContract], + ['/cosmwasm.wasm.v1.MsgStoreCode', MsgStoreCode], + ['/cosmwasm.wasm.v1.MsgInstantiateContract', MsgInstantiateContract], + ['/cosmwasm.wasm.v1.MsgUpdateAdmin', MsgUpdateAdmin], +]; + jest.setTimeout(100000); -describe('KyveClient', () => { +describe('KyveApi', () => { let kyveApi: KyveApi; let tendermint: Tendermint37Client; + let api: CosmosClient; + let registry: Registry; beforeAll(async () => { + registry = new Registry([...defaultRegistryTypes, ...wasmTypes]); + api = new CosmosClient(tendermint, registry); kyveApi = new KyveApi('archway-1'); await kyveApi.init(); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); }); + // TODO: all the test to fetch bundle from arweave is failing on timeout. it('getBundle by height', async () => { - const v = await kyveApi.getBlockByHeight(3856726); - // todo expect // timing out - // expect(v).toEqual() + const [, blockResponse] = await kyveApi.getBlockByHeight(3856726); + expect(blockResponse).toEqual(require('./bundle.json')); }); it('ensure correct bundle ID on binary search', async () => { const a = Date.now(); @@ -45,95 +58,75 @@ describe('KyveClient', () => { expect(firstBundle).toBe(0); expect(laterBundle).toBe(113773); }); - it('cosmos client with kyve', async () => { - const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ - ['/cosmwasm.wasm.v1.MsgClearAdmin', MsgClearAdmin], - ['/cosmwasm.wasm.v1.MsgExecuteContract', MsgExecuteContract], - ['/cosmwasm.wasm.v1.MsgMigrateContract', MsgMigrateContract], - ['/cosmwasm.wasm.v1.MsgStoreCode', MsgStoreCode], - ['/cosmwasm.wasm.v1.MsgInstantiateContract', MsgInstantiateContract], - ['/cosmwasm.wasm.v1.MsgUpdateAdmin', MsgUpdateAdmin], - ]; - const registry = new Registry([...defaultRegistryTypes, ...wasmTypes]); - const api = new CosmosClient(tendermint, registry); - // const height = 3489747; - const height = 1338; - // - const [kyveBlockInfo, kyveBlockResult] = await kyveApi.getBlockByHeight( - height, - ); - const [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ - tendermint.block(height), - tendermint.blockResults(height), - ]); - - const v = new LazyBlockContent(kyveBlockInfo, kyveBlockResult, api); - const tv = new LazyBlockContent( - tendermintBlockInfo, - tendermintBlockResult, - api, - ); - // TODO - }); it('compare block info', async () => { - // todo, use a archway block - - const height = 13885474; + const height = 3901476; const tendermintBlockInfo = await tendermint.block(height); const [kyveBlockInfo] = await kyveApi.getBlockByHeight(height); expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); }); - it('compare block results', async () => { - // bundleId: 113773 - const height = 3489747; - // const [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ - // tendermint.block(height), - // tendermint.blockResults(height), - // ]); - const [kyveBlockInfo, kyveBlockResult] = await kyveApi.getBlockByHeight( - height, - ); - // - // expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); - // - // // Note: block result will fail on expect due to deep nested array order being wrong - // // RPC uses base64 decoded, due to recent upgrade. - // // However, kyve stores base64 encoded - // expect( - // tendermintBlockResult.beginBlockEvents[4].attributes.find( - // (a) => a.key === 'sender', - // ), - // ).toEqual( - // kyveBlockResult.beginBlockEvents[4].attributes.find( - // (a) => a.key === 'c2VuZGVy', - // ), - // ); - // expect( - // isEqual( - // tendermintBlockResult.consensusUpdates, - // kyveBlockResult.consensusUpdates, - // ), - // ).toBe(true); - // expect(tendermintBlockResult.results.length).toBe( - // kyveBlockResult.results.length, - // ); - // expect(tendermintBlockResult.validatorUpdates.length).toBe( - // kyveBlockResult.validatorUpdates.length, - // ); - // expect(tendermintBlockResult.height).toBe(kyveBlockResult.height); - // - // expect( - // tendermintBlockResult.endBlockEvents[2].attributes.find( - // (a) => a.key === 'recipient', - // ), - // ).toEqual( - // kyveBlockResult.endBlockEvents[2].attributes.find( - // (a) => a.key === 'cmVjaXBpZW50', - // ), - // ); - }); it('determine correct pool', () => { expect((kyveApi as any).poolId).toBe('2'); expect((kyveApi as any).chainId).toBe('archway-1'); }); + describe('able to wrap kyveBlock', () => { + let rpcLazyBlockContent: LazyBlockContent; + let kyveLazyBlockContent: LazyBlockContent; + + beforeAll(async () => { + const height = 3856726; + const [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ + tendermint.block(height), + tendermint.blockResults(height), + ]); + const bundle_3856726 = require('./bundle.json'); + + const blockInfo = bundle_3856726.value.block; + const blockResults = bundle_3856726.value.block_results; + + const bi = (kyveApi as any).decodeBlock(blockInfo); + const br = (kyveApi as any).decodeBlockResult(blockResults); + + rpcLazyBlockContent = new LazyBlockContent( + tendermintBlockInfo, + tendermintBlockResult, + api, + ); + kyveLazyBlockContent = new LazyBlockContent(bi, br, api, true); + }); + it('wrapTransaction', () => { + // note: kyve log is undefined + expect(kyveLazyBlockContent.transactions[0].tx.data.length).toBe( + rpcLazyBlockContent.transactions[0].tx.data.length, + ); + expect(kyveLazyBlockContent.transactions[0].tx.events.length).toBe( + rpcLazyBlockContent.transactions[0].tx.events.length, + ); + expect(kyveLazyBlockContent.transactions.length).toBe( + rpcLazyBlockContent.transactions.length, + ); + }); + it('wrapMessages', () => { + kyveLazyBlockContent.messages.forEach((m, i) => { + expect(m.msg).toEqual(rpcLazyBlockContent.messages[i].msg); + }); + }); + it('wrapBlock', () => { + expect(kyveLazyBlockContent.block.blockId.hash.length).toBe( + rpcLazyBlockContent.block.blockId.hash.length, + ); + expect(kyveLazyBlockContent.block.block.id).toBe( + rpcLazyBlockContent.block.block.id, + ); + expect(kyveLazyBlockContent.block.block.header).toEqual( + rpcLazyBlockContent.block.block.header, + ); + }); + it('wrapEvents', () => { + kyveLazyBlockContent.events.forEach((e, i) => { + const rpcEvent = rpcLazyBlockContent.events[i].event; + expect(e.event.type).toBe(rpcEvent.type); + expect(e.event.attributes.length).toBe(rpcEvent.attributes.length); + }); + }); + }); }); diff --git a/packages/node/src/utils/kyve.ts b/packages/node/src/utils/kyve.ts index 64dad37c2..e1447331f 100644 --- a/packages/node/src/utils/kyve.ts +++ b/packages/node/src/utils/kyve.ts @@ -90,7 +90,7 @@ export class KyveApi { private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { return this.respAdaptor.decodeBlock({ - id: 10, + id: 10, // todo jsonrpc: '2.0', result: block, }); From 37787636f801e696836963c7f9b73bc9bda59719 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 29 Mar 2024 13:15:03 +0800 Subject: [PATCH 09/81] add cli support for kyve --- packages/node/src/indexer/api.service.ts | 28 ++++++++----------- .../src/indexer/cosmosClient.connection.ts | 11 ++++++++ packages/node/src/init.ts | 1 + packages/node/src/utils/cosmos.ts | 11 ++++++-- packages/node/src/utils/kyve.spec.ts | 2 +- packages/node/src/utils/kyve.ts | 5 +--- 6 files changed, 34 insertions(+), 24 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 7d6ca6911..e971095a0 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -37,6 +37,7 @@ import { import { SubqueryProject } from '../configure/SubqueryProject'; import * as CosmosUtil from '../utils/cosmos'; import { KyveApi } from '../utils/kyve'; +import { yargsOptions } from '../yargs'; import { CosmosClientConnection } from './cosmosClient.connection'; import { BlockContent } from './types'; @@ -89,6 +90,12 @@ export class ApiService this.registry = await this.buildRegistry(); + const { argv } = yargsOptions; + + if (argv.kyve) { + this.kyveClient = new KyveApi(network.chainId); + } + await this.createConnections( network, (endpoint) => @@ -96,6 +103,7 @@ export class ApiService endpoint, this.fetchBlocksBatches, this.registry, + this.kyveApi, ), (connection: CosmosClientConnection) => { const api = connection.unsafeApi; @@ -106,6 +114,10 @@ export class ApiService return this; } + get kyveApi(): KyveApi { + return this.kyveClient; + } + get api(): CosmosClient { return this.unsafeApi; } @@ -140,12 +152,8 @@ export class ApiService return res; } } -// instead of using log, -// use events -// step 1. get rid of logs and use just events. export class CosmosClient extends CosmWasmClient { - private kyveClient: KyveApi; constructor( private readonly tendermintClient: Tendermint37Client, public registry: Registry, @@ -163,18 +171,6 @@ export class CosmosClient extends CosmWasmClient { } */ - // todo, a trigger for when kyve should used - async initKyveClient(chainId: string): Promise { - this.kyveClient = new KyveApi(chainId); - await this.kyveClient.init(); - } - - async kyveBlockByHeight( - height: number, - ): Promise<[BlockResponse, BlockResultsResponse]> { - return this.kyveClient.getBlockByHeight(height); - } - // eslint-disable-next-line @typescript-eslint/require-await async blockInfo(height?: number): Promise { return this.tendermintClient.block(height); diff --git a/packages/node/src/indexer/cosmosClient.connection.ts b/packages/node/src/indexer/cosmosClient.connection.ts index bc19eccfd..d6783f7a4 100644 --- a/packages/node/src/indexer/cosmosClient.connection.ts +++ b/packages/node/src/indexer/cosmosClient.connection.ts @@ -12,6 +12,7 @@ import { NetworkMetadataPayload, } from '@subql/node-core'; import { getLogger } from '@subql/node-core/dist'; +import { KyveApi } from '../utils/kyve'; import { CosmosClient, CosmosSafeClient } from './api.service'; import { HttpClient, WebsocketClient } from './rpc-clients'; import { BlockContent } from './types'; @@ -38,6 +39,7 @@ export class CosmosClientConnection { private tmClient: Tendermint37Client; private registry: Registry; + private kyveApi?: KyveApi; readonly networkMeta: NetworkMetadataPayload; constructor( @@ -56,6 +58,7 @@ export class CosmosClientConnection endpoint: string, fetchBlocksBatches: FetchFunc, registry: Registry, + kyveApi?: KyveApi, ): Promise { const httpEndpoint: HttpEndpoint = { url: endpoint, @@ -86,6 +89,10 @@ export class CosmosClientConnection logger.info(`connected to ${endpoint}`); + if (kyveApi) { + connection.setKyveApi(kyveApi); + } + return connection; } @@ -93,6 +100,10 @@ export class CosmosClientConnection return new CosmosSafeClient(this.tmClient, height); } + private setKyveApi(kyveApi: KyveApi): void { + this.kyveApi = kyveApi; + } + private setTmClient(tmClient: Tendermint37Client): void { this.tmClient = tmClient; } diff --git a/packages/node/src/init.ts b/packages/node/src/init.ts index 535a50073..6775cf5f6 100644 --- a/packages/node/src/init.ts +++ b/packages/node/src/init.ts @@ -36,6 +36,7 @@ export async function bootstrap(): Promise { process.exit(1); } + console.log('argv at init', argv); if (argv.unsafe) { logger.warn( 'UNSAFE MODE IS ENABLED. This is not recommended for most projects and will not be supported by our hosted service', diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index f802f5ce8..fcefb58dd 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -27,6 +27,7 @@ import { import { isObjectLike } from 'lodash'; import { CosmosClient } from '../indexer/api.service'; import { BlockContent } from '../indexer/types'; +import { KyveApi } from './kyve'; const logger = getLogger('fetch'); @@ -183,10 +184,13 @@ async function getBlockByHeight( export async function fetchCosmosBlocksArray( api: CosmosClient, blockArray: number[], + kyve?: KyveApi, ): Promise<[BlockResponse, BlockResultsResponse][]> { // todo this is where kyve introduction should be. return Promise.all( - blockArray.map(async (height) => getBlockByHeight(api, height)), + blockArray.map(async (height) => + kyve ? kyve.getBlockByHeight(height) : getBlockByHeight(api, height), + ), ); } @@ -367,8 +371,9 @@ export function formatBlockUtil(block: B): IBlock { export async function fetchBlocksBatches( api: CosmosClient, blockArray: number[], + kyveApi?: KyveApi, ): Promise[]> { - const blocks = await fetchCosmosBlocksArray(api, blockArray); + const blocks = await fetchCosmosBlocksArray(api, blockArray, kyveApi); return blocks.map(([blockInfo, blockResults]) => { try { assert( @@ -402,7 +407,7 @@ export class LazyBlockContent implements BlockContent { private _blockInfo: BlockResponse, private _results: BlockResultsResponse, private _api: CosmosClient, - private _kyveBlock = false, + private _kyveBlock?: KyveApi, ) {} get block() { diff --git a/packages/node/src/utils/kyve.spec.ts b/packages/node/src/utils/kyve.spec.ts index b73d558d0..3b1d937d2 100644 --- a/packages/node/src/utils/kyve.spec.ts +++ b/packages/node/src/utils/kyve.spec.ts @@ -91,7 +91,7 @@ describe('KyveApi', () => { tendermintBlockResult, api, ); - kyveLazyBlockContent = new LazyBlockContent(bi, br, api, true); + kyveLazyBlockContent = new LazyBlockContent(bi, br, api, kyveApi); }); it('wrapTransaction', () => { // note: kyve log is undefined diff --git a/packages/node/src/utils/kyve.ts b/packages/node/src/utils/kyve.ts index e1447331f..6a82a23fd 100644 --- a/packages/node/src/utils/kyve.ts +++ b/packages/node/src/utils/kyve.ts @@ -69,10 +69,6 @@ export class KyveApi { } } - private async injectLogs() { - // TODO - } - private async unzipStorageData( compressionId: string, storageData: any, @@ -167,6 +163,7 @@ export class KyveApi { async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { + console.log('using kyve get block'); const bundleId = await this.getBundleId(height); const rawBundle = await this.getBundleById(bundleId); const bundleData = await this.retrieveBundleData(rawBundle); From 841287d4d21bb318081c15def45c928f8bd16e5b Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 29 Mar 2024 13:15:17 +0800 Subject: [PATCH 10/81] add cli support for kyve --- packages/node/src/utils/kyve.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/node/src/utils/kyve.ts b/packages/node/src/utils/kyve.ts index 6a82a23fd..421aed14a 100644 --- a/packages/node/src/utils/kyve.ts +++ b/packages/node/src/utils/kyve.ts @@ -163,7 +163,6 @@ export class KyveApi { async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { - console.log('using kyve get block'); const bundleId = await this.getBundleId(height); const rawBundle = await this.getBundleById(bundleId); const bundleData = await this.retrieveBundleData(rawBundle); From e4b7def0150c176d3fa7b1c25c1058f6f37006a5 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 2 Apr 2024 23:29:14 +0800 Subject: [PATCH 11/81] use nodeConfig for kyve cli integration, update kyve api, add storage retriever --- packages/node/src/configure/NodeConfig.ts | 30 ++++ packages/node/src/indexer/api.service.ts | 22 +-- .../src/indexer/cosmosClient.connection.ts | 12 +- .../src/indexer/worker/worker-fetch.module.ts | 3 + packages/node/src/init.ts | 1 - .../node/src/subcommands/testing.module.ts | 3 + packages/node/src/utils/cosmos.ts | 51 +----- .../node/src/utils/{ => kyve}/kyve.spec.ts | 47 +++++- packages/node/src/utils/{ => kyve}/kyve.ts | 146 ++++++++++++++---- packages/node/src/utils/kyve/kyveTypes.ts | 30 ++++ .../node/src/utils/kyve/storageRetriever.ts | 31 ++++ packages/node/src/yargs.ts | 7 + .../utils => test/kyve_block}/bundle.json | 0 13 files changed, 283 insertions(+), 100 deletions(-) create mode 100644 packages/node/src/configure/NodeConfig.ts rename packages/node/src/utils/{ => kyve}/kyve.spec.ts (78%) rename packages/node/src/utils/{ => kyve}/kyve.ts (54%) create mode 100644 packages/node/src/utils/kyve/kyveTypes.ts create mode 100644 packages/node/src/utils/kyve/storageRetriever.ts rename packages/node/{src/utils => test/kyve_block}/bundle.json (100%) diff --git a/packages/node/src/configure/NodeConfig.ts b/packages/node/src/configure/NodeConfig.ts new file mode 100644 index 000000000..162d6ab06 --- /dev/null +++ b/packages/node/src/configure/NodeConfig.ts @@ -0,0 +1,30 @@ +// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import { IConfig, NodeConfig } from '@subql/node-core'; + +export interface ICosmosConfig extends IConfig { + kyve: string; +} + +export class CosmosNodeConfig extends NodeConfig { + /** + * This is a wrapper around the core NodeConfig to get additional properties that are provided through args or node runner options + * NOTE: This isn't injected anywhere so you need to wrap the injected node config + * + * @example + * constructor( + * nodeConfig: NodeConfig, + * ) { + * this.nodeConfig = new EthereumNodeConfig(nodeConfig); + * } + * */ + constructor(config: NodeConfig) { + // Rebuild with internal config + super((config as any)._config, (config as any)._isTest); + } + + get kyve(): string { + return this._config.kyve; + } +} diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index e971095a0..bceacdce0 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -24,6 +24,7 @@ import { ConnectionPoolService, ApiService as BaseApiService, IBlock, + NodeConfig, } from '@subql/node-core'; import { CosmWasmSafeClient } from '@subql/types-cosmos/interfaces'; import { @@ -34,10 +35,10 @@ import { MsgStoreCode, MsgUpdateAdmin, } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; +import { CosmosNodeConfig } from '../configure/NodeConfig'; import { SubqueryProject } from '../configure/SubqueryProject'; import * as CosmosUtil from '../utils/cosmos'; -import { KyveApi } from '../utils/kyve'; -import { yargsOptions } from '../yargs'; +import { KyveApi } from '../utils/kyve/kyve'; import { CosmosClientConnection } from './cosmosClient.connection'; import { BlockContent } from './types'; @@ -49,15 +50,18 @@ export class ApiService implements OnApplicationShutdown { private fetchBlocksBatches = CosmosUtil.fetchBlocksBatches; - private kyveClient: KyveApi; + private kyve: KyveApi; + private nodeConfig: CosmosNodeConfig; registry: Registry; constructor( @Inject('ISubqueryProject') private project: SubqueryProject, connectionPoolService: ConnectionPoolService, eventEmitter: EventEmitter2, + nodeConfig: NodeConfig, ) { super(connectionPoolService, eventEmitter); + this.nodeConfig = new CosmosNodeConfig(nodeConfig); } private async buildRegistry(): Promise { @@ -90,10 +94,11 @@ export class ApiService this.registry = await this.buildRegistry(); - const { argv } = yargsOptions; + if (this.nodeConfig.kyve) { + this.kyve = new KyveApi(network.chainId, this.nodeConfig.kyve); + await this.kyve.init(); - if (argv.kyve) { - this.kyveClient = new KyveApi(network.chainId); + this.fetchBlocksBatches = this.kyve.fetchBlocksBatches.bind(this.kyve); } await this.createConnections( @@ -103,7 +108,6 @@ export class ApiService endpoint, this.fetchBlocksBatches, this.registry, - this.kyveApi, ), (connection: CosmosClientConnection) => { const api = connection.unsafeApi; @@ -114,10 +118,6 @@ export class ApiService return this; } - get kyveApi(): KyveApi { - return this.kyveClient; - } - get api(): CosmosClient { return this.unsafeApi; } diff --git a/packages/node/src/indexer/cosmosClient.connection.ts b/packages/node/src/indexer/cosmosClient.connection.ts index d6783f7a4..651a6b101 100644 --- a/packages/node/src/indexer/cosmosClient.connection.ts +++ b/packages/node/src/indexer/cosmosClient.connection.ts @@ -12,7 +12,7 @@ import { NetworkMetadataPayload, } from '@subql/node-core'; import { getLogger } from '@subql/node-core/dist'; -import { KyveApi } from '../utils/kyve'; +import { KyveApi } from '../utils/kyve/kyve'; import { CosmosClient, CosmosSafeClient } from './api.service'; import { HttpClient, WebsocketClient } from './rpc-clients'; import { BlockContent } from './types'; @@ -39,7 +39,7 @@ export class CosmosClientConnection { private tmClient: Tendermint37Client; private registry: Registry; - private kyveApi?: KyveApi; + private kyve?: KyveApi; readonly networkMeta: NetworkMetadataPayload; constructor( @@ -58,7 +58,7 @@ export class CosmosClientConnection endpoint: string, fetchBlocksBatches: FetchFunc, registry: Registry, - kyveApi?: KyveApi, + kyve?: KyveApi, ): Promise { const httpEndpoint: HttpEndpoint = { url: endpoint, @@ -89,8 +89,8 @@ export class CosmosClientConnection logger.info(`connected to ${endpoint}`); - if (kyveApi) { - connection.setKyveApi(kyveApi); + if (kyve) { + connection.setKyveApi(kyve); } return connection; @@ -101,7 +101,7 @@ export class CosmosClientConnection } private setKyveApi(kyveApi: KyveApi): void { - this.kyveApi = kyveApi; + this.kyve = kyveApi; } private setTmClient(tmClient: Tendermint37Client): void { diff --git a/packages/node/src/indexer/worker/worker-fetch.module.ts b/packages/node/src/indexer/worker/worker-fetch.module.ts index b9b92111d..7c6840fa7 100644 --- a/packages/node/src/indexer/worker/worker-fetch.module.ts +++ b/packages/node/src/indexer/worker/worker-fetch.module.ts @@ -10,6 +10,7 @@ import { WorkerConnectionPoolStateManager, InMemoryCacheService, WorkerInMemoryCacheService, + NodeConfig, } from '@subql/node-core'; import { SubqueryProject } from '../../configure/SubqueryProject'; import { ApiService } from '../api.service'; @@ -38,11 +39,13 @@ import { WorkerUnfinalizedBlocksService } from './worker.unfinalizedBlocks.servi project: SubqueryProject, connectionPoolService: ConnectionPoolService, eventEmitter: EventEmitter2, + nodeConfig: NodeConfig, ) => { const apiService = new ApiService( project, connectionPoolService, eventEmitter, + nodeConfig, ); await apiService.init(); return apiService; diff --git a/packages/node/src/init.ts b/packages/node/src/init.ts index 6775cf5f6..535a50073 100644 --- a/packages/node/src/init.ts +++ b/packages/node/src/init.ts @@ -36,7 +36,6 @@ export async function bootstrap(): Promise { process.exit(1); } - console.log('argv at init', argv); if (argv.unsafe) { logger.warn( 'UNSAFE MODE IS ENABLED. This is not recommended for most projects and will not be supported by our hosted service', diff --git a/packages/node/src/subcommands/testing.module.ts b/packages/node/src/subcommands/testing.module.ts index ed2f90e57..1a9aac47b 100644 --- a/packages/node/src/subcommands/testing.module.ts +++ b/packages/node/src/subcommands/testing.module.ts @@ -9,6 +9,7 @@ import { ConnectionPoolStateManager, DbModule, InMemoryCacheService, + NodeConfig, PoiService, PoiSyncService, StoreCacheService, @@ -50,11 +51,13 @@ import { UnfinalizedBlocksService } from '../indexer/unfinalizedBlocks.service'; project: SubqueryProject, connectionPoolService: ConnectionPoolService, eventEmitter: EventEmitter2, + nodeConfig: NodeConfig, ) => { const apiService = new ApiService( project, connectionPoolService, eventEmitter, + nodeConfig, ); await apiService.init(); return apiService; diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index fcefb58dd..d793177f9 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -27,7 +27,7 @@ import { import { isObjectLike } from 'lodash'; import { CosmosClient } from '../indexer/api.service'; import { BlockContent } from '../indexer/types'; -import { KyveApi } from './kyve'; +import { KyveApi } from './kyve/kyve'; const logger = getLogger('fetch'); @@ -184,13 +184,9 @@ async function getBlockByHeight( export async function fetchCosmosBlocksArray( api: CosmosClient, blockArray: number[], - kyve?: KyveApi, ): Promise<[BlockResponse, BlockResultsResponse][]> { - // todo this is where kyve introduction should be. return Promise.all( - blockArray.map(async (height) => - kyve ? kyve.getBlockByHeight(height) : getBlockByHeight(api, height), - ), + blockArray.map(async (height) => getBlockByHeight(api, height)), ); } @@ -219,7 +215,7 @@ export function wrapTx( })); } -function wrapCosmosMsg( +export function wrapCosmosMsg( block: CosmosBlock, tx: CosmosTransaction, idx: number, @@ -271,40 +267,6 @@ export function wrapBlockBeginAndEndEvents( }, ); } -// TODO this should be replacing the current implementation, but then, the rpc request should be source of truth. -export function kyveWrapEvent( - block: CosmosBlock, - txs: CosmosTransaction[], - api: CosmosClient, - idxOffset: number, //use this offset to avoid clash with idx of begin block events -): CosmosEvent[] { - const events: CosmosEvent[] = []; - for (const tx of txs) { - let msgIndex = -1; - for (const event of tx.tx.events) { - if ( - event.type === 'message' && - event.attributes.find((e) => e.key === 'action') - ) { - msgIndex += 1; - } - - if (msgIndex >= 0) { - const msg = wrapCosmosMsg(block, tx, msgIndex, api); - const cosmosEvent: CosmosEvent = { - idx: idxOffset++, - msg, - tx, - block, - log: undefined, - event, - }; - events.push(cosmosEvent); - } - } - } - return events; -} export function wrapEvent( block: CosmosBlock, @@ -371,7 +333,6 @@ export function formatBlockUtil(block: B): IBlock { export async function fetchBlocksBatches( api: CosmosClient, blockArray: number[], - kyveApi?: KyveApi, ): Promise[]> { const blocks = await fetchCosmosBlocksArray(api, blockArray, kyveApi); return blocks.map(([blockInfo, blockResults]) => { @@ -407,7 +368,7 @@ export class LazyBlockContent implements BlockContent { private _blockInfo: BlockResponse, private _results: BlockResultsResponse, private _api: CosmosClient, - private _kyveBlock?: KyveApi, + private _kyve?: KyveApi, ) {} get block() { @@ -435,8 +396,8 @@ export class LazyBlockContent implements BlockContent { get events() { if (!this._wrappedEvent) { - this._wrappedEvent = this._kyveBlock - ? kyveWrapEvent( + this._wrappedEvent = this._kyve + ? this._kyve.wrapEvent( this.block, this.transactions, this._api, diff --git a/packages/node/src/utils/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts similarity index 78% rename from packages/node/src/utils/kyve.spec.ts rename to packages/node/src/utils/kyve/kyve.spec.ts index 3b1d937d2..b625d984f 100644 --- a/packages/node/src/utils/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -1,6 +1,7 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 +import path from 'path'; import { GeneratedType, Registry } from '@cosmjs/proto-signing'; import { defaultRegistryTypes } from '@cosmjs/stargate'; import { Tendermint37Client } from '@cosmjs/tendermint-rpc'; @@ -13,9 +14,9 @@ import { MsgUpdateAdmin, } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; import { isEqual } from 'lodash'; -import { CosmosClient } from '../indexer/api.service'; -import { HttpClient } from '../indexer/rpc-clients'; -import { LazyBlockContent } from './cosmos'; +import { CosmosClient } from '../../indexer/api.service'; +import { HttpClient } from '../../indexer/rpc-clients'; +import { LazyBlockContent } from '../cosmos'; import { KyveApi } from './kyve'; const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ @@ -27,6 +28,12 @@ const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ ['/cosmwasm.wasm.v1.MsgUpdateAdmin', MsgUpdateAdmin], ]; +const kyveBundlePath = path.join( + __dirname, + '../../../test/kyve_block/bundle.json', +); +const bundle_3856726 = require(kyveBundlePath); + jest.setTimeout(100000); describe('KyveApi', () => { let kyveApi: KyveApi; @@ -37,7 +44,7 @@ describe('KyveApi', () => { beforeAll(async () => { registry = new Registry([...defaultRegistryTypes, ...wasmTypes]); api = new CosmosClient(tendermint, registry); - kyveApi = new KyveApi('archway-1'); + kyveApi = new KyveApi('archway-1', 'https://arweave.net'); await kyveApi.init(); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); @@ -46,15 +53,40 @@ describe('KyveApi', () => { // TODO: all the test to fetch bundle from arweave is failing on timeout. it('getBundle by height', async () => { const [, blockResponse] = await kyveApi.getBlockByHeight(3856726); - expect(blockResponse).toEqual(require('./bundle.json')); + expect(blockResponse).toEqual(bundle_3856726); + }); + it('ensure bundleDetails', async () => { + const bundleDetails = await (kyveApi as any).getBundleById(0); + expect(bundleDetails).toEqual({ + pool_id: '2', + id: '0', + storage_id: 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', + uploader: 'kyve1z6wduz3psfuhp87r4enfnaelhcf94uksgjs0qj', + from_index: '0', + to_index: '150', + from_key: '1', + to_key: '150', + bundle_summary: '150', + data_hash: + 'a5915a350030e60224909c82c0c7058f7096d401202fb8a05724e059d89ff7a5', + finalized_at: { height: '2589775', timestamp: '2023-09-06T12:20:22Z' }, + storage_provider_id: '2', + compression_id: '1', + stake_security: { + valid_vote_power: '954119472714', + total_vote_power: '1185083547399', + }, + }); }); + it('ensure correct bundle ID on binary search', async () => { + await kyveApi.init(); // reset cached bundle Id const a = Date.now(); - const laterBundle = await (kyveApi as any).getBundleId(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 + const firstBundle = await (kyveApi as any).getBundleId(120); // https://app.kyve.network/#/pools/2/bundles/0 const b = Date.now(); console.log(`${b - a}ms`); - const firstBundle = await (kyveApi as any).getBundleId(120); // https://app.kyve.network/#/pools/2/bundles/0 + const laterBundle = await (kyveApi as any).getBundleId(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 expect(firstBundle).toBe(0); expect(laterBundle).toBe(113773); }); @@ -78,7 +110,6 @@ describe('KyveApi', () => { tendermint.block(height), tendermint.blockResults(height), ]); - const bundle_3856726 = require('./bundle.json'); const blockInfo = bundle_3856726.value.block; const blockResults = bundle_3856726.value.block_results; diff --git a/packages/node/src/utils/kyve.ts b/packages/node/src/utils/kyve/kyve.ts similarity index 54% rename from packages/node/src/utils/kyve.ts rename to packages/node/src/utils/kyve/kyve.ts index 421aed14a..67eef1ae9 100644 --- a/packages/node/src/utils/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -1,6 +1,7 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 +import assert from 'assert'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; import { adaptor37 } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; import { @@ -9,12 +10,23 @@ import { } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; // Currently these types are not exported import { Gzip } from '@kyvejs/protocol/dist/src/reactors/compression/Gzip'; -import { Arweave } from '@kyvejs/protocol/dist/src/reactors/storageProviders/Arweave'; -import { Bundlr } from '@kyvejs/protocol/dist/src/reactors/storageProviders/Bundlr'; import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; +import { getLogger } from '@subql/node-core'; +import { + CosmosBlock, + CosmosEvent, + CosmosTransaction, +} from '@subql/types-cosmos'; +import { CosmosClient } from '../../indexer/api.service'; +import { BlockContent } from '../../indexer/types'; +import { LazyBlockContent, wrapCosmosMsg } from '../cosmos'; +import { BundleDetails } from './kyveTypes'; +import { StorageRetriever } from './storageRetriever'; + +const BUNDLE_TIMEOUT = 10000; //ms -const BUNDLE_TIMEOUT = 100000; //ms +const logger = getLogger('kyve-fetch'); interface UnZippedKyveBlockReponse { value: { block: any; block_results: any }; @@ -27,16 +39,21 @@ export class KyveApi { private poolId: string; private currentBundleId: number; private cachedBlocks: UnZippedKyveBlockReponse[]; + private cachedBundle: any; // storage Data + private storageUrl: string; constructor( private chainId: string, + storageUrl: string, kyveChainId: SupportedChains = 'kyve-1', ) { + this.storageUrl = storageUrl; this.lcdClient = new KyveSDK(kyveChainId).createLCDClient(); } async init(): Promise { this.currentBundleId = 0; await this.setPoolId(); + logger.info('kyve-api init'); } private async getAllPools() { return this.lcdClient.kyve.query.v1beta1.pools(); @@ -54,19 +71,12 @@ export class KyveApi { } private async retrieveBundleData( - bundleResponse: any, + storageId: string, ): Promise<{ storageId: string; storageData: any }> { - const { storage_id, storage_provider_id } = bundleResponse; - switch (parseInt(storage_provider_id) ?? 0) { - case 0: - throw new Error('No storage, no existing stored data'); - case 1: - return new Arweave('1').retrieveBundle(storage_id, BUNDLE_TIMEOUT); - case 2: - return new Bundlr('1').retrieveBundle(storage_id, BUNDLE_TIMEOUT); - default: - throw new Error('Unsupported storage provider'); - } + return new StorageRetriever(this.storageUrl).retrieveBundle( + storageId, + BUNDLE_TIMEOUT, + ); } private async unzipStorageData( @@ -102,11 +112,13 @@ export class KyveApi { }); } - private async getBundleById(bundleId: number): Promise { - return this.lcdClient.kyve.query.v1beta1.finalizedBundle({ - pool_id: this.poolId, - id: bundleId.toString(), - }); + private async getBundleById(bundleId: number): Promise { + const bundleDetail = + await this.lcdClient.kyve.query.v1beta1.finalizedBundle({ + pool_id: this.poolId, + id: bundleId.toString(), + }); + return bundleDetail as BundleDetails; } private async getLatestBundleId(): Promise { @@ -151,7 +163,7 @@ export class KyveApi { high = mid - 1; } } - throw new Error('No suitable bundle found for the given height.'); + throw new Error(`No suitable bundle found for height ${height}}`); } private findBlockByHeight(height: number): UnZippedKyveBlockReponse { @@ -160,19 +172,29 @@ export class KyveApi { ); } + private async validateCache(height: number, bundleDetails: BundleDetails) { + if (!this.cachedBundle || parseInt(bundleDetails.to_key) > height) { + this.cachedBundle = await this.retrieveBundleData( + bundleDetails.storage_id, + ); + + this.cachedBlocks = await this.unzipStorageData( + bundleDetails.compression_id, + this.cachedBundle.storageData, + ); + } + } + async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { const bundleId = await this.getBundleId(height); - const rawBundle = await this.getBundleById(bundleId); - const bundleData = await this.retrieveBundleData(rawBundle); + const bundleDetails = await this.getBundleById(bundleId); + console.log('fetching from kyve'); + + await this.validateCache(height, bundleDetails); + console.log('fetched from kyve'); - if (!this.cachedBlocks) { - this.cachedBlocks = await this.unzipStorageData( - rawBundle.compression_id, - bundleData.storageData, - ); - } const blockData = this.findBlockByHeight(height); return [ @@ -180,4 +202,70 @@ export class KyveApi { this.decodeBlockResult(blockData.value.block_results), ]; } + + wrapEvent( + block: CosmosBlock, + txs: CosmosTransaction[], + api: CosmosClient, + idxOffset: number, //use this offset to avoid clash with idx of begin block events + ): CosmosEvent[] { + const events: CosmosEvent[] = []; + for (const tx of txs) { + let msgIndex = -1; + for (const event of tx.tx.events) { + if ( + event.type === 'message' && + event.attributes.find((e) => e.key === 'action') + ) { + msgIndex += 1; + } + + if (msgIndex >= 0) { + const msg = wrapCosmosMsg(block, tx, msgIndex, api); + const cosmosEvent: CosmosEvent = { + idx: idxOffset++, + msg, + tx, + block, + log: undefined, + event, + }; + events.push(cosmosEvent); + } + } + } + return events; + } + + private async fetchBlocksArray( + blockArray: number[], + ): Promise<[BlockResponse, BlockResultsResponse][]> { + logger.info('using kyve blocks'); + return Promise.all( + blockArray.map(async (height) => this.getBlockByHeight(height)), + ); + } + + async fetchBlocksBatches( + api: CosmosClient, + blockArray: number[], + ): Promise { + const blocks = await this.fetchBlocksArray(blockArray); + return blocks.map(([blockInfo, blockResults]) => { + try { + assert( + blockResults.results.length === blockInfo.block.txs.length, + `txInfos doesn't match up with block (${blockInfo.block.header.height}) transactions expected ${blockInfo.block.txs.length}, received: ${blockResults.results.length}`, + ); + + return new LazyBlockContent(blockInfo, blockResults, api, this); + } catch (e) { + logger.error( + e, + `Failed to fetch and prepare block ${blockInfo.block.header.height}`, + ); + throw e; + } + }); + } } diff --git a/packages/node/src/utils/kyve/kyveTypes.ts b/packages/node/src/utils/kyve/kyveTypes.ts new file mode 100644 index 000000000..9fb9df6bb --- /dev/null +++ b/packages/node/src/utils/kyve/kyveTypes.ts @@ -0,0 +1,30 @@ +// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +// Note: this is due to incorrect typings provided by kyvejs +export interface BundleDetails { + pool_id: string; + id: string; + storage_id: string; + uploader: string; + from_index: string; + to_index: string; + from_key: string; + to_key: string; + bundle_summary: string; + data_hash: string; + finalized_at: FinalizedAt; + storage_provider_id: string; + compression_id: string; + stake_security: StakeSecurity; +} + +interface FinalizedAt { + height: string; + timestamp: string; +} + +interface StakeSecurity { + valid_vote_power: string; + total_vote_power: string; +} diff --git a/packages/node/src/utils/kyve/storageRetriever.ts b/packages/node/src/utils/kyve/storageRetriever.ts new file mode 100644 index 000000000..775a6b136 --- /dev/null +++ b/packages/node/src/utils/kyve/storageRetriever.ts @@ -0,0 +1,31 @@ +// Copyright 2020-2023 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import { StorageReceipt } from '@kyvejs/protocol'; +import axios, { AxiosRequestConfig } from 'axios'; + +interface IStorageRetriever { + retrieveBundle(storageId: string, timeout: number): Promise; +} + +export class StorageRetriever implements IStorageRetriever { + private readonly storageUrl: string; + constructor(url: string) { + this.storageUrl = url; + } + async retrieveBundle( + storageId: string, + timeout: number, + ): Promise { + const axiosConfig: AxiosRequestConfig = { + method: 'get', + url: `/${storageId}`, + baseURL: this.storageUrl, + responseType: 'arraybuffer', + timeout, + }; + const { data: storageData } = await axios(axiosConfig); + + return { storageId, storageData }; + } +} diff --git a/packages/node/src/yargs.ts b/packages/node/src/yargs.ts index 857d19a71..4104e7610 100644 --- a/packages/node/src/yargs.ts +++ b/packages/node/src/yargs.ts @@ -22,4 +22,11 @@ export const yargsOptions = yargsBuilder({ const { reindexInit } = require('./subcommands/reindex.init'); return reindexInit(targetHeight); }, + runOptions: { + kyve: { + demandOption: false, + describe: 'Use blocks from kyve instead of rpc', + type: 'string', + }, + }, }); diff --git a/packages/node/src/utils/bundle.json b/packages/node/test/kyve_block/bundle.json similarity index 100% rename from packages/node/src/utils/bundle.json rename to packages/node/test/kyve_block/bundle.json From e17a4e970285d9fce61b99f2279a904f41082adc Mon Sep 17 00:00:00 2001 From: bz888 Date: Thu, 4 Apr 2024 11:42:08 +0800 Subject: [PATCH 12/81] add kyveConnection class, refactor cosmos wrappers to use registry over api. update based on review --- packages/node/src/configure/NodeConfig.ts | 10 +-- packages/node/src/indexer/api.service.ts | 60 +++++-------- .../src/indexer/cosmosClient.connection.ts | 14 +-- packages/node/src/utils/cosmos.spec.ts | 6 +- packages/node/src/utils/cosmos.ts | 71 +++++++++++---- packages/node/src/utils/kyve/kyve.spec.ts | 4 +- packages/node/src/utils/kyve/kyve.ts | 83 +++++++++++------- .../node/src/utils/kyve/kyveConnection.ts | 87 +++++++++++++++++++ .../node/src/utils/kyve/storageRetriever.ts | 31 ------- 9 files changed, 228 insertions(+), 138 deletions(-) create mode 100644 packages/node/src/utils/kyve/kyveConnection.ts delete mode 100644 packages/node/src/utils/kyve/storageRetriever.ts diff --git a/packages/node/src/configure/NodeConfig.ts b/packages/node/src/configure/NodeConfig.ts index 162d6ab06..25b41aaa3 100644 --- a/packages/node/src/configure/NodeConfig.ts +++ b/packages/node/src/configure/NodeConfig.ts @@ -4,19 +4,19 @@ import { IConfig, NodeConfig } from '@subql/node-core'; export interface ICosmosConfig extends IConfig { - kyve: string; + kyveEndpoint: string; } export class CosmosNodeConfig extends NodeConfig { /** * This is a wrapper around the core NodeConfig to get additional properties that are provided through args or node runner options - * NOTE: This isn't injected anywhere so you need to wrap the injected node config + * NOTE: This isn't injected anywhere, so you need to wrap the injected node config * * @example * constructor( * nodeConfig: NodeConfig, * ) { - * this.nodeConfig = new EthereumNodeConfig(nodeConfig); + * this.nodeConfig = new CosmosNodeConfig(nodeConfig); * } * */ constructor(config: NodeConfig) { @@ -24,7 +24,7 @@ export class CosmosNodeConfig extends NodeConfig { super((config as any)._config, (config as any)._isTest); } - get kyve(): string { - return this._config.kyve; + get kyveEndpoint(): string { + return this._config.kyveEndpoint; } } diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index bceacdce0..7915ca6ba 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -39,6 +39,7 @@ import { CosmosNodeConfig } from '../configure/NodeConfig'; import { SubqueryProject } from '../configure/SubqueryProject'; import * as CosmosUtil from '../utils/cosmos'; import { KyveApi } from '../utils/kyve/kyve'; +import { KyveConnection } from '../utils/kyve/kyveConnection'; import { CosmosClientConnection } from './cosmosClient.connection'; import { BlockContent } from './types'; @@ -50,7 +51,6 @@ export class ApiService implements OnApplicationShutdown { private fetchBlocksBatches = CosmosUtil.fetchBlocksBatches; - private kyve: KyveApi; private nodeConfig: CosmosNodeConfig; registry: Registry; @@ -94,27 +94,28 @@ export class ApiService this.registry = await this.buildRegistry(); - if (this.nodeConfig.kyve) { - this.kyve = new KyveApi(network.chainId, this.nodeConfig.kyve); - await this.kyve.init(); - - this.fetchBlocksBatches = this.kyve.fetchBlocksBatches.bind(this.kyve); + if (this.nodeConfig.kyveEndpoint) { + await KyveConnection.create( + network.chainId, + this.nodeConfig.kyveEndpoint, + this.registry, + ); + } else { + await this.createConnections( + network, + (endpoint) => + CosmosClientConnection.create( + endpoint, + this.fetchBlocksBatches, + this.registry, + ), + (connection: CosmosClientConnection) => { + const api = connection.unsafeApi; + return api.getChainId(); + }, + ); } - await this.createConnections( - network, - (endpoint) => - CosmosClientConnection.create( - endpoint, - this.fetchBlocksBatches, - this.registry, - ), - (connection: CosmosClientConnection) => { - const api = connection.unsafeApi; - return api.getChainId(); - }, - ); - return this; } @@ -186,25 +187,6 @@ export class CosmosClient extends CosmWasmClient { return this.tendermintClient.blockResults(height); } - decodeMsg(msg: DecodeObject): T { - try { - const decodedMsg = this.registry.decode(msg); - if ( - [ - '/cosmwasm.wasm.v1.MsgExecuteContract', - '/cosmwasm.wasm.v1.MsgMigrateContract', - '/cosmwasm.wasm.v1.MsgInstantiateContract', - ].includes(msg.typeUrl) - ) { - decodedMsg.msg = JSON.parse(new TextDecoder().decode(decodedMsg.msg)); - } - return decodedMsg; - } catch (e) { - logger.error(e, 'Failed to decode message'); - throw e; - } - } - static handleError(e: Error): Error { const formatted_error: Error = e; try { diff --git a/packages/node/src/indexer/cosmosClient.connection.ts b/packages/node/src/indexer/cosmosClient.connection.ts index 651a6b101..51f3a0fe7 100644 --- a/packages/node/src/indexer/cosmosClient.connection.ts +++ b/packages/node/src/indexer/cosmosClient.connection.ts @@ -24,9 +24,10 @@ const RETRY_DELAY = 2_500; const logger = getLogger('cosmos-client-connection'); -type FetchFunc = ( - api: CosmosClient, +export type FetchFunc = ( + registry: Registry, batch: number[], + api?: CosmosClient, ) => Promise[]>; export class CosmosClientConnection @@ -58,7 +59,6 @@ export class CosmosClientConnection endpoint: string, fetchBlocksBatches: FetchFunc, registry: Registry, - kyve?: KyveApi, ): Promise { const httpEndpoint: HttpEndpoint = { url: endpoint, @@ -89,10 +89,6 @@ export class CosmosClientConnection logger.info(`connected to ${endpoint}`); - if (kyve) { - connection.setKyveApi(kyve); - } - return connection; } @@ -100,10 +96,6 @@ export class CosmosClientConnection return new CosmosSafeClient(this.tmClient, height); } - private setKyveApi(kyveApi: KyveApi): void { - this.kyve = kyveApi; - } - private setTmClient(tmClient: Tendermint37Client): void { this.tmClient = tmClient; } diff --git a/packages/node/src/utils/cosmos.spec.ts b/packages/node/src/utils/cosmos.spec.ts index 7e3b41a3a..ab3b23142 100644 --- a/packages/node/src/utils/cosmos.spec.ts +++ b/packages/node/src/utils/cosmos.spec.ts @@ -25,7 +25,7 @@ import { } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; import { CosmosClient } from '../indexer/api.service'; import { HttpClient } from '../indexer/rpc-clients'; -import { filterMessageData, wrapEvent } from './cosmos'; +import { decodeMsg, filterMessageData, wrapEvent } from './cosmos'; const ENDPOINT = 'https://rpc-archive.junonetwork.io/'; @@ -113,7 +113,7 @@ describe('CosmosUtils', () => { msg: { typeUrl: decodedTx.body.messages[0].typeUrl, get decodedMsg() { - return api.decodeMsg(decodedTx.body.messages[0]); + return decodeMsg(decodedTx.body.messages[0], registry); }, }, }; @@ -157,7 +157,7 @@ describe('CosmosUtils', () => { hash: '', decodedTx: {} as DecodedTxRaw, }; - const events = wrapEvent({} as CosmosBlock, [tx], api, 0); + const events = wrapEvent({} as CosmosBlock, [tx], api.registry, 0); expect(events.length).toEqual(0); }); diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index d793177f9..5c02ba9ee 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -2,9 +2,10 @@ // SPDX-License-Identifier: GPL-3.0 import assert from 'assert'; +import { TextDecoder } from 'util'; import { sha256 } from '@cosmjs/crypto'; import { toHex } from '@cosmjs/encoding'; -import { decodeTxRaw } from '@cosmjs/proto-signing'; +import { DecodeObject, decodeTxRaw, Registry } from '@cosmjs/proto-signing'; import { fromTendermintEvent } from '@cosmjs/stargate'; import { Log, parseRawLog } from '@cosmjs/stargate/build/logs'; import { @@ -31,6 +32,28 @@ import { KyveApi } from './kyve/kyve'; const logger = getLogger('fetch'); +export function decodeMsg( + msg: DecodeObject, + registry: Registry, +): T { + try { + const decodedMsg = registry.decode(msg); + if ( + [ + '/cosmwasm.wasm.v1.MsgExecuteContract', + '/cosmwasm.wasm.v1.MsgMigrateContract', + '/cosmwasm.wasm.v1.MsgInstantiateContract', + ].includes(msg.typeUrl) + ) { + decodedMsg.msg = JSON.parse(new TextDecoder().decode(decodedMsg.msg)); + } + return decodedMsg; + } catch (e) { + logger.error(e, 'Failed to decode message'); + throw e; + } +} + export function filterBlock( data: CosmosBlock, filter?: CosmosBlockFilter, @@ -167,9 +190,9 @@ export function filterEvents( return filteredEvents; } -async function getBlockByHeight( - api: CosmosClient, +async function getBlockByHeightByRpc( height: number, + api: CosmosClient, ): Promise<[BlockResponse, BlockResultsResponse]> { return Promise.all([ api.blockInfo(height).catch((e) => { @@ -181,12 +204,16 @@ async function getBlockByHeight( ]); } -export async function fetchCosmosBlocksArray( - api: CosmosClient, +export async function fetchCosmosBlocksArray( + getBlockByHeight: ( + height: number, + api: T, + ) => Promise<[BlockResponse, BlockResultsResponse]>, blockArray: number[], + api: T, ): Promise<[BlockResponse, BlockResultsResponse][]> { return Promise.all( - blockArray.map(async (height) => getBlockByHeight(api, height)), + blockArray.map(async (height) => getBlockByHeight(height, api)), ); } @@ -219,7 +246,7 @@ export function wrapCosmosMsg( block: CosmosBlock, tx: CosmosTransaction, idx: number, - api: CosmosClient, + registry: Registry, ): CosmosMessage { const rawMessage = tx.decodedTx.body.messages[idx]; return { @@ -230,7 +257,8 @@ export function wrapCosmosMsg( typeUrl: rawMessage.typeUrl, get decodedMsg() { delete this.decodedMsg; - return (this.decodedMsg = api.decodeMsg(rawMessage)); + // TODO, unsure how this will impact the decode + return (this.decodedMsg = decodeMsg(rawMessage, registry)); }, }, }; @@ -239,12 +267,12 @@ export function wrapCosmosMsg( function wrapMsg( block: CosmosBlock, txs: CosmosTransaction[], - api: CosmosClient, + registry: Registry, ): CosmosMessage[] { const msgs: CosmosMessage[] = []; for (const tx of txs) { for (let i = 0; i < tx.decodedTx.body.messages.length; i++) { - msgs.push(wrapCosmosMsg(block, tx, i, api)); + msgs.push(wrapCosmosMsg(block, tx, i, registry)); } } return msgs; @@ -271,7 +299,7 @@ export function wrapBlockBeginAndEndEvents( export function wrapEvent( block: CosmosBlock, txs: CosmosTransaction[], - api: CosmosClient, + registry: Registry, idxOffset: number, //use this offset to avoid clash with idx of begin block events ): CosmosEvent[] { const events: CosmosEvent[] = []; @@ -287,7 +315,7 @@ export function wrapEvent( for (const log of logs) { let msg: CosmosMessage; try { - msg = wrapCosmosMsg(block, tx, log.msg_index, api); + msg = wrapCosmosMsg(block, tx, log.msg_index, registry); } catch (e) { // Example where this can happen https://sei.explorers.guru/transaction/8D4CA68E917E15652E10CB960DE604AEEB1B183D6E94A85E9CD98403F15550B7 logger.warn( @@ -331,7 +359,7 @@ export function formatBlockUtil(block: B): IBlock { } export async function fetchBlocksBatches( - api: CosmosClient, + registry: Registry, blockArray: number[], ): Promise[]> { const blocks = await fetchCosmosBlocksArray(api, blockArray, kyveApi); @@ -367,7 +395,7 @@ export class LazyBlockContent implements BlockContent { constructor( private _blockInfo: BlockResponse, private _results: BlockResultsResponse, - private _api: CosmosClient, + private _registry: Registry, private _kyve?: KyveApi, ) {} @@ -389,7 +417,11 @@ export class LazyBlockContent implements BlockContent { get messages() { if (!this._wrappedMessage) { - this._wrappedMessage = wrapMsg(this.block, this.transactions, this._api); + this._wrappedMessage = wrapMsg( + this.block, + this.transactions, + this._registry, + ); } return this._wrappedMessage; } @@ -400,10 +432,15 @@ export class LazyBlockContent implements BlockContent { ? this._kyve.wrapEvent( this.block, this.transactions, - this._api, + this._registry, this._eventIdx, ) - : wrapEvent(this.block, this.transactions, this._api, this._eventIdx); + : wrapEvent( + this.block, + this.transactions, + this._registry, + this._eventIdx, + ); this._eventIdx += this._wrappedEvent.length; } return this._wrappedEvent; diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index b625d984f..34fdb3824 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -120,9 +120,9 @@ describe('KyveApi', () => { rpcLazyBlockContent = new LazyBlockContent( tendermintBlockInfo, tendermintBlockResult, - api, + registry, ); - kyveLazyBlockContent = new LazyBlockContent(bi, br, api, kyveApi); + kyveLazyBlockContent = new LazyBlockContent(bi, br, registry, kyveApi); }); it('wrapTransaction', () => { // note: kyve log is undefined diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 67eef1ae9..bae62dd13 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -3,30 +3,35 @@ import assert from 'assert'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; +import { Registry } from '@cosmjs/proto-signing'; import { adaptor37 } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; import { BlockResponse, BlockResultsResponse, } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; // Currently these types are not exported +import { StorageReceipt } from '@kyvejs/protocol'; import { Gzip } from '@kyvejs/protocol/dist/src/reactors/compression/Gzip'; import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; +import { PoolResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; import { getLogger } from '@subql/node-core'; import { CosmosBlock, CosmosEvent, CosmosTransaction, } from '@subql/types-cosmos'; -import { CosmosClient } from '../../indexer/api.service'; +import axios, { AxiosRequestConfig } from 'axios'; import { BlockContent } from '../../indexer/types'; import { LazyBlockContent, wrapCosmosMsg } from '../cosmos'; import { BundleDetails } from './kyveTypes'; -import { StorageRetriever } from './storageRetriever'; const BUNDLE_TIMEOUT = 10000; //ms +const RADIX = 10; -const logger = getLogger('kyve-fetch'); +const parseIntRadix = (value: string) => parseInt(value, RADIX); + +const logger = getLogger('kyve'); interface UnZippedKyveBlockReponse { value: { block: any; block_results: any }; @@ -53,7 +58,6 @@ export class KyveApi { async init(): Promise { this.currentBundleId = 0; await this.setPoolId(); - logger.info('kyve-api init'); } private async getAllPools() { return this.lcdClient.kyve.query.v1beta1.pools(); @@ -61,22 +65,27 @@ export class KyveApi { private async setPoolId(): Promise { const pools = await this.getAllPools(); - const pool = pools.pools.find( - (p) => JSON.parse(p.data.config).network === this.chainId, - ); + + let pool: PoolResponse; + for (const p of pools.pools) { + try { + const config = JSON.parse(p.data.config); + if (config.network === this.chainId) { + pool = p as unknown as PoolResponse; + break; + } + } catch (error) { + throw new Error( + `Error parsing JSON for pool with id ${p.id}:, ${error}`, + ); + } + } + if (!pool) { throw new Error(`${this.chainId} is not available on Kyve network`); } - this.poolId = pool.id; - } - private async retrieveBundleData( - storageId: string, - ): Promise<{ storageId: string; storageData: any }> { - return new StorageRetriever(this.storageUrl).retrieveBundle( - storageId, - BUNDLE_TIMEOUT, - ); + this.poolId = pool.id; } private async unzipStorageData( @@ -84,7 +93,7 @@ export class KyveApi { storageData: any, ): Promise { const g = new Gzip(); - if (parseInt(compressionId) === 0) { + if (parseIntRadix(compressionId) === 0) { throw new Error('No Compression'); } @@ -96,7 +105,7 @@ export class KyveApi { private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { return this.respAdaptor.decodeBlock({ - id: 10, // todo + id: 1, jsonrpc: '2.0', result: block, }); @@ -106,7 +115,7 @@ export class KyveApi { blockResult: JsonRpcSuccessResponse, ): BlockResultsResponse { return this.respAdaptor.decodeBlockResults({ - id: 10, + id: 1, jsonrpc: '2.0', result: blockResult, }); @@ -123,7 +132,7 @@ export class KyveApi { private async getLatestBundleId(): Promise { return ( - parseInt( + parseIntRadix( ( await this.lcdClient.kyve.query.v1beta1.finalizedBundles({ pool_id: this.poolId, @@ -148,8 +157,8 @@ export class KyveApi { const mid = Math.floor((low + high) / 2); const midBundle = await this.getBundleById(mid); - const fromKey = parseInt(midBundle.from_key); - const toKey = parseInt(midBundle.to_key); + const fromKey = parseIntRadix(midBundle.from_key); + const toKey = parseIntRadix(midBundle.to_key); if (height >= fromKey && height <= toKey) { startBundleId = mid; @@ -173,9 +182,10 @@ export class KyveApi { } private async validateCache(height: number, bundleDetails: BundleDetails) { - if (!this.cachedBundle || parseInt(bundleDetails.to_key) > height) { + if (!this.cachedBundle || parseIntRadix(bundleDetails.to_key) > height) { this.cachedBundle = await this.retrieveBundleData( bundleDetails.storage_id, + BUNDLE_TIMEOUT, ); this.cachedBlocks = await this.unzipStorageData( @@ -190,10 +200,8 @@ export class KyveApi { ): Promise<[BlockResponse, BlockResultsResponse]> { const bundleId = await this.getBundleId(height); const bundleDetails = await this.getBundleById(bundleId); - console.log('fetching from kyve'); await this.validateCache(height, bundleDetails); - console.log('fetched from kyve'); const blockData = this.findBlockByHeight(height); @@ -206,7 +214,7 @@ export class KyveApi { wrapEvent( block: CosmosBlock, txs: CosmosTransaction[], - api: CosmosClient, + registry: Registry, idxOffset: number, //use this offset to avoid clash with idx of begin block events ): CosmosEvent[] { const events: CosmosEvent[] = []; @@ -221,7 +229,7 @@ export class KyveApi { } if (msgIndex >= 0) { - const msg = wrapCosmosMsg(block, tx, msgIndex, api); + const msg = wrapCosmosMsg(block, tx, msgIndex, registry); const cosmosEvent: CosmosEvent = { idx: idxOffset++, msg, @@ -240,14 +248,29 @@ export class KyveApi { private async fetchBlocksArray( blockArray: number[], ): Promise<[BlockResponse, BlockResultsResponse][]> { - logger.info('using kyve blocks'); return Promise.all( blockArray.map(async (height) => this.getBlockByHeight(height)), ); } + private async retrieveBundleData( + storageId: string, + timeout: number, + ): Promise { + const axiosConfig: AxiosRequestConfig = { + method: 'get', + url: `/${storageId}`, + baseURL: this.storageUrl, + responseType: 'arraybuffer', + timeout, + }; + const { data: storageData } = await axios(axiosConfig); + + return { storageId, storageData }; + } + async fetchBlocksBatches( - api: CosmosClient, + registry: Registry, blockArray: number[], ): Promise { const blocks = await this.fetchBlocksArray(blockArray); @@ -258,7 +281,7 @@ export class KyveApi { `txInfos doesn't match up with block (${blockInfo.block.header.height}) transactions expected ${blockInfo.block.txs.length}, received: ${blockResults.results.length}`, ); - return new LazyBlockContent(blockInfo, blockResults, api, this); + return new LazyBlockContent(blockInfo, blockResults, registry, this); } catch (e) { logger.error( e, diff --git a/packages/node/src/utils/kyve/kyveConnection.ts b/packages/node/src/utils/kyve/kyveConnection.ts new file mode 100644 index 000000000..b0247b2a0 --- /dev/null +++ b/packages/node/src/utils/kyve/kyveConnection.ts @@ -0,0 +1,87 @@ +// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import { Registry } from '@cosmjs/proto-signing'; +import { + ApiConnectionError, + ApiErrorType, + getLogger, + IApiConnectionSpecific, + NetworkMetadataPayload, +} from '@subql/node-core'; +import { FetchFunc } from '../../indexer/cosmosClient.connection'; +import { BlockContent } from '../../indexer/types'; +import { KyveApi } from './kyve'; + +const logger = getLogger('kyve-API'); + +export class KyveConnection + implements IApiConnectionSpecific +{ + readonly networkMeta: NetworkMetadataPayload; // this is not needed + unsafeApi: any; // this isnt needed + private registry: Registry; + + constructor( + private fetchBlocksBatches: FetchFunc, + private chainId: string, + ) // todo do i need registry ? + { + this.networkMeta = { + chain: this.chainId, + specName: undefined, + genesisHash: undefined, + }; + } + + static async create( + chainId: string, + kyveEndpoint: string, + registry: Registry, + ): Promise { + const kyveApi = new KyveApi(chainId, kyveEndpoint); + await kyveApi.init(); + + const connection = new KyveConnection( + kyveApi.fetchBlocksBatches.bind(kyveApi), + chainId, + ); + connection.setRegistry(registry); + + logger.info(`connected to Kyve via ${kyveEndpoint}`); + + return connection; + } + + async fetchBlocks(heights: number[]): Promise { + const blocks = await this.fetchBlocksBatches(this.registry, heights); + return blocks; + } + + handleError = KyveConnection.handleError; + + static handleError(error: Error): ApiConnectionError { + return new ApiConnectionError( + 'KyveError', + error.message, + ApiErrorType.Default, + ); + } + + private setRegistry(registry: Registry): void { + this.registry = registry; + } + + // No safeAPi + safeApi(height: number): any { + return undefined; + } + + async apiConnect(): Promise { + return Promise.resolve(undefined); + } + + async apiDisconnect(): Promise { + return Promise.resolve(undefined); + } +} diff --git a/packages/node/src/utils/kyve/storageRetriever.ts b/packages/node/src/utils/kyve/storageRetriever.ts deleted file mode 100644 index 775a6b136..000000000 --- a/packages/node/src/utils/kyve/storageRetriever.ts +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2020-2023 SubQuery Pte Ltd authors & contributors -// SPDX-License-Identifier: GPL-3.0 - -import { StorageReceipt } from '@kyvejs/protocol'; -import axios, { AxiosRequestConfig } from 'axios'; - -interface IStorageRetriever { - retrieveBundle(storageId: string, timeout: number): Promise; -} - -export class StorageRetriever implements IStorageRetriever { - private readonly storageUrl: string; - constructor(url: string) { - this.storageUrl = url; - } - async retrieveBundle( - storageId: string, - timeout: number, - ): Promise { - const axiosConfig: AxiosRequestConfig = { - method: 'get', - url: `/${storageId}`, - baseURL: this.storageUrl, - responseType: 'arraybuffer', - timeout, - }; - const { data: storageData } = await axios(axiosConfig); - - return { storageId, storageData }; - } -} From 0e850fc8703efce17b5dadaec46df4e719587a0f Mon Sep 17 00:00:00 2001 From: bz888 Date: Thu, 4 Apr 2024 17:36:39 +0800 Subject: [PATCH 13/81] update and refactor based on review --- packages/node/src/configure/NodeConfig.ts | 11 +++ packages/node/src/indexer/api.service.ts | 57 +++++++++------ .../src/indexer/cosmosClient.connection.ts | 18 +++-- packages/node/src/utils/cosmos.ts | 42 +++++------ packages/node/src/utils/kyve/kyve.spec.ts | 18 ++--- packages/node/src/utils/kyve/kyve.ts | 72 +++++++++++++------ .../node/src/utils/kyve/kyveConnection.ts | 41 +++++------ packages/node/src/yargs.ts | 17 ++++- 8 files changed, 175 insertions(+), 101 deletions(-) diff --git a/packages/node/src/configure/NodeConfig.ts b/packages/node/src/configure/NodeConfig.ts index 25b41aaa3..4a5367261 100644 --- a/packages/node/src/configure/NodeConfig.ts +++ b/packages/node/src/configure/NodeConfig.ts @@ -1,10 +1,13 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 +import { SupportedChains } from '@kyvejs/sdk/src/constants'; import { IConfig, NodeConfig } from '@subql/node-core'; export interface ICosmosConfig extends IConfig { + kyveChainId: SupportedChains; kyveEndpoint: string; + storageUrl: string; } export class CosmosNodeConfig extends NodeConfig { @@ -27,4 +30,12 @@ export class CosmosNodeConfig extends NodeConfig { get kyveEndpoint(): string { return this._config.kyveEndpoint; } + + get kyveChainId(): SupportedChains { + return this._config.kyveChainId; + } + + get storageUrl(): string { + return this._config.storageUrl; + } } diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 7915ca6ba..569137ede 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -1,7 +1,6 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 -import { TextDecoder } from 'util'; import { CosmWasmClient, IndexedTx } from '@cosmjs/cosmwasm-stargate'; import { toHex } from '@cosmjs/encoding'; import { Uint53 } from '@cosmjs/math'; @@ -25,6 +24,8 @@ import { ApiService as BaseApiService, IBlock, NodeConfig, + IndexerEvent, + IApiConnectionSpecific, } from '@subql/node-core'; import { CosmWasmSafeClient } from '@subql/types-cosmos/interfaces'; import { @@ -38,7 +39,6 @@ import { import { CosmosNodeConfig } from '../configure/NodeConfig'; import { SubqueryProject } from '../configure/SubqueryProject'; import * as CosmosUtil from '../utils/cosmos'; -import { KyveApi } from '../utils/kyve/kyve'; import { KyveConnection } from '../utils/kyve/kyveConnection'; import { CosmosClientConnection } from './cosmosClient.connection'; import { BlockContent } from './types'; @@ -89,33 +89,48 @@ export class ApiService await this.connectionPoolService.onApplicationShutdown(); } + private async createKyveConnection( + network: CosmosNetworkConfig, + createConnection: (chainId: string) => Promise, + ) { + const connection = await createConnection(network.chainId); + + this.eventEmitter.emit(IndexerEvent.ApiConnected, { + value: 1, + apiIndex: 0, + endpoint: this.nodeConfig.kyveEndpoint, + }); + } + async init(): Promise { const { network } = this.project; this.registry = await this.buildRegistry(); - if (this.nodeConfig.kyveEndpoint) { - await KyveConnection.create( - network.chainId, - this.nodeConfig.kyveEndpoint, - this.registry, - ); - } else { - await this.createConnections( - network, - (endpoint) => - CosmosClientConnection.create( - endpoint, - this.fetchBlocksBatches, - this.registry, - ), - (connection: CosmosClientConnection) => { - const api = connection.unsafeApi; - return api.getChainId(); - }, + if (this.nodeConfig.kyveChainId || this.nodeConfig.kyveEndpoint) { + await this.createKyveConnection(network, () => + KyveConnection.create(network.chainId, this.registry, { + storageUrl: this.nodeConfig.storageUrl ?? 'https://arweave.net', + kyveChainId: this.nodeConfig.kyveChainId ?? 'kyve-1', + kyveEndpoint: this.nodeConfig.kyveEndpoint, + }), ); } + await this.createConnections( + network, + (endpoint) => + CosmosClientConnection.create( + endpoint, + this.fetchBlocksBatches, + this.registry, + ), + (connection: CosmosClientConnection) => { + const api = connection.unsafeApi; + return api.getChainId(); + }, + ); + return this; } diff --git a/packages/node/src/indexer/cosmosClient.connection.ts b/packages/node/src/indexer/cosmosClient.connection.ts index 51f3a0fe7..0bb612994 100644 --- a/packages/node/src/indexer/cosmosClient.connection.ts +++ b/packages/node/src/indexer/cosmosClient.connection.ts @@ -12,7 +12,12 @@ import { NetworkMetadataPayload, } from '@subql/node-core'; import { getLogger } from '@subql/node-core/dist'; -import { KyveApi } from '../utils/kyve/kyve'; +import { + CosmosBlock, + CosmosEvent, + CosmosTransaction, +} from '@subql/types-cosmos'; +import { wrapEvent } from '../utils/cosmos'; import { CosmosClient, CosmosSafeClient } from './api.service'; import { HttpClient, WebsocketClient } from './rpc-clients'; import { BlockContent } from './types'; @@ -24,10 +29,16 @@ const RETRY_DELAY = 2_500; const logger = getLogger('cosmos-client-connection'); -export type FetchFunc = ( +type FetchFunc = ( registry: Registry, batch: number[], - api?: CosmosClient, + api: CosmosClient, + wrapEventsFunc: ( + block: CosmosBlock, + txs: CosmosTransaction[], + registry: Registry, + eventIdx: number, + ) => CosmosEvent[], ) => Promise[]>; export class CosmosClientConnection @@ -40,7 +51,6 @@ export class CosmosClientConnection { private tmClient: Tendermint37Client; private registry: Registry; - private kyve?: KyveApi; readonly networkMeta: NetworkMetadataPayload; constructor( diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index 5c02ba9ee..21538b08f 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -28,7 +28,6 @@ import { import { isObjectLike } from 'lodash'; import { CosmosClient } from '../indexer/api.service'; import { BlockContent } from '../indexer/types'; -import { KyveApi } from './kyve/kyve'; const logger = getLogger('fetch'); @@ -191,8 +190,8 @@ export function filterEvents( } async function getBlockByHeightByRpc( - height: number, api: CosmosClient, + height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { return Promise.all([ api.blockInfo(height).catch((e) => { @@ -207,13 +206,11 @@ async function getBlockByHeightByRpc( export async function fetchCosmosBlocksArray( getBlockByHeight: ( height: number, - api: T, ) => Promise<[BlockResponse, BlockResultsResponse]>, blockArray: number[], - api: T, ): Promise<[BlockResponse, BlockResultsResponse][]> { return Promise.all( - blockArray.map(async (height) => getBlockByHeight(height, api)), + blockArray.map(async (height) => getBlockByHeight(height)), ); } @@ -361,8 +358,13 @@ export function formatBlockUtil(block: B): IBlock { export async function fetchBlocksBatches( registry: Registry, blockArray: number[], + api: CosmosClient, ): Promise[]> { - const blocks = await fetchCosmosBlocksArray(api, blockArray, kyveApi); + const blocks = await fetchCosmosBlocksArray( + (height: number) => getBlockByHeightByRpc(api, height), + blockArray, + ); + return blocks.map(([blockInfo, blockResults]) => { try { assert( @@ -371,7 +373,7 @@ export async function fetchBlocksBatches( ); return formatBlockUtil( - new LazyBlockContent(blockInfo, blockResults, api), + new LazyBlockContent(blockInfo, blockResults, registry, wrapEvent) ); } catch (e) { logger.error( @@ -396,7 +398,12 @@ export class LazyBlockContent implements BlockContent { private _blockInfo: BlockResponse, private _results: BlockResultsResponse, private _registry: Registry, - private _kyve?: KyveApi, + private wrapEventsFunc: ( + block: CosmosBlock, + txs: CosmosTransaction[], + registry: Registry, + eventIdx: number, + ) => CosmosEvent[], ) {} get block() { @@ -428,19 +435,12 @@ export class LazyBlockContent implements BlockContent { get events() { if (!this._wrappedEvent) { - this._wrappedEvent = this._kyve - ? this._kyve.wrapEvent( - this.block, - this.transactions, - this._registry, - this._eventIdx, - ) - : wrapEvent( - this.block, - this.transactions, - this._registry, - this._eventIdx, - ); + this._wrappedEvent = this.wrapEventsFunc( + this.block, + this.transactions, + this._registry, + this._eventIdx, + ); this._eventIdx += this._wrappedEvent.length; } return this._wrappedEvent; diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 34fdb3824..ef707f22a 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -14,9 +14,8 @@ import { MsgUpdateAdmin, } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; import { isEqual } from 'lodash'; -import { CosmosClient } from '../../indexer/api.service'; import { HttpClient } from '../../indexer/rpc-clients'; -import { LazyBlockContent } from '../cosmos'; +import { LazyBlockContent, wrapEvent } from '../cosmos'; import { KyveApi } from './kyve'; const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ @@ -38,14 +37,11 @@ jest.setTimeout(100000); describe('KyveApi', () => { let kyveApi: KyveApi; let tendermint: Tendermint37Client; - let api: CosmosClient; let registry: Registry; beforeAll(async () => { registry = new Registry([...defaultRegistryTypes, ...wasmTypes]); - api = new CosmosClient(tendermint, registry); - kyveApi = new KyveApi('archway-1', 'https://arweave.net'); - await kyveApi.init(); + kyveApi = await KyveApi.create('archway-1'); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); }); @@ -80,7 +76,7 @@ describe('KyveApi', () => { }); it('ensure correct bundle ID on binary search', async () => { - await kyveApi.init(); // reset cached bundle Id + (kyveApi as any).currentBundleId = 0; // reset cached bundle Id const a = Date.now(); const firstBundle = await (kyveApi as any).getBundleId(120); // https://app.kyve.network/#/pools/2/bundles/0 const b = Date.now(); @@ -121,8 +117,14 @@ describe('KyveApi', () => { tendermintBlockInfo, tendermintBlockResult, registry, + wrapEvent, + ); + kyveLazyBlockContent = new LazyBlockContent( + bi, + br, + registry, + kyveApi.wrapEvent.bind(kyveApi), ); - kyveLazyBlockContent = new LazyBlockContent(bi, br, registry, kyveApi); }); it('wrapTransaction', () => { // note: kyve log is undefined diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index bae62dd13..7d1e16ad8 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -14,7 +14,10 @@ import { StorageReceipt } from '@kyvejs/protocol'; import { Gzip } from '@kyvejs/protocol/dist/src/reactors/compression/Gzip'; import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; -import { PoolResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; +import { + PoolResponse, + QueryPoolsResponse, +} from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; import { getLogger } from '@subql/node-core'; import { CosmosBlock, @@ -27,9 +30,8 @@ import { LazyBlockContent, wrapCosmosMsg } from '../cosmos'; import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms -const RADIX = 10; -const parseIntRadix = (value: string) => parseInt(value, RADIX); +const parseDecimal = (value: string) => parseInt(value, 10); const logger = getLogger('kyve'); @@ -38,6 +40,12 @@ interface UnZippedKyveBlockReponse { key: string; } +export type KyveConnectionConfig = { + storageUrl?: string; + kyveEndpoint?: string; + kyveChainId?: SupportedChains; +}; + export class KyveApi { private lcdClient: KyveLCDClientType; private respAdaptor = adaptor37.responses; @@ -47,20 +55,33 @@ export class KyveApi { private cachedBundle: any; // storage Data private storageUrl: string; - constructor( - private chainId: string, - storageUrl: string, - kyveChainId: SupportedChains = 'kyve-1', - ) { - this.storageUrl = storageUrl; - this.lcdClient = new KyveSDK(kyveChainId).createLCDClient(); + private constructor(private chainId: string) {} + + static async create( + chainId: string, // chainId for indexing chain + kyveConfig?: KyveConnectionConfig, + ): Promise { + const kyve = new KyveApi(chainId); + + kyve.lcdClient = new KyveSDK( + kyveConfig.kyveChainId, + kyveConfig.kyveEndpoint ? { rpc: kyveConfig.kyveEndpoint } : undefined, + ).createLCDClient(); + + kyve.storageUrl = kyveConfig.storageUrl; + kyve.currentBundleId = 0; + + await kyve.setPoolId(); + + return kyve; } - async init(): Promise { - this.currentBundleId = 0; - await this.setPoolId(); + + get getLcdClient(): KyveLCDClientType { + return this.lcdClient; } - private async getAllPools() { - return this.lcdClient.kyve.query.v1beta1.pools(); + + private async getAllPools(): Promise { + return (await this.lcdClient.kyve.query.v1beta1.pools()) as unknown as QueryPoolsResponse; } private async setPoolId(): Promise { @@ -90,11 +111,11 @@ export class KyveApi { private async unzipStorageData( compressionId: string, - storageData: any, + storageData: Buffer, ): Promise { const g = new Gzip(); - if (parseIntRadix(compressionId) === 0) { - throw new Error('No Compression'); + if (parseDecimal(compressionId) === 0) { + return storageData as any; } const buffer = await g.decompress(storageData); @@ -132,7 +153,7 @@ export class KyveApi { private async getLatestBundleId(): Promise { return ( - parseIntRadix( + parseDecimal( ( await this.lcdClient.kyve.query.v1beta1.finalizedBundles({ pool_id: this.poolId, @@ -157,8 +178,8 @@ export class KyveApi { const mid = Math.floor((low + high) / 2); const midBundle = await this.getBundleById(mid); - const fromKey = parseIntRadix(midBundle.from_key); - const toKey = parseIntRadix(midBundle.to_key); + const fromKey = parseDecimal(midBundle.from_key); + const toKey = parseDecimal(midBundle.to_key); if (height >= fromKey && height <= toKey) { startBundleId = mid; @@ -182,7 +203,7 @@ export class KyveApi { } private async validateCache(height: number, bundleDetails: BundleDetails) { - if (!this.cachedBundle || parseIntRadix(bundleDetails.to_key) > height) { + if (!this.cachedBundle || parseDecimal(bundleDetails.to_key) > height) { this.cachedBundle = await this.retrieveBundleData( bundleDetails.storage_id, BUNDLE_TIMEOUT, @@ -281,7 +302,12 @@ export class KyveApi { `txInfos doesn't match up with block (${blockInfo.block.header.height}) transactions expected ${blockInfo.block.txs.length}, received: ${blockResults.results.length}`, ); - return new LazyBlockContent(blockInfo, blockResults, registry, this); + return new LazyBlockContent( + blockInfo, + blockResults, + registry, + this.wrapEvent.bind(this), + ); } catch (e) { logger.error( e, diff --git a/packages/node/src/utils/kyve/kyveConnection.ts b/packages/node/src/utils/kyve/kyveConnection.ts index b0247b2a0..e0b4b6944 100644 --- a/packages/node/src/utils/kyve/kyveConnection.ts +++ b/packages/node/src/utils/kyve/kyveConnection.ts @@ -9,24 +9,27 @@ import { IApiConnectionSpecific, NetworkMetadataPayload, } from '@subql/node-core'; -import { FetchFunc } from '../../indexer/cosmosClient.connection'; import { BlockContent } from '../../indexer/types'; -import { KyveApi } from './kyve'; +import { KyveApi, KyveConnectionConfig } from './kyve'; const logger = getLogger('kyve-API'); +type KyveFetchFunc = ( + registry: Registry, + batch: number[], +) => Promise; + export class KyveConnection implements IApiConnectionSpecific { - readonly networkMeta: NetworkMetadataPayload; // this is not needed - unsafeApi: any; // this isnt needed - private registry: Registry; + unsafeApi: any; + readonly networkMeta: NetworkMetadataPayload; - constructor( - private fetchBlocksBatches: FetchFunc, + private constructor( + private fetchBlocksBatches: KyveFetchFunc, private chainId: string, - ) // todo do i need registry ? - { + private registry: Registry, + ) { this.networkMeta = { chain: this.chainId, specName: undefined, @@ -36,19 +39,18 @@ export class KyveConnection static async create( chainId: string, - kyveEndpoint: string, registry: Registry, + kyveConfig: KyveConnectionConfig, ): Promise { - const kyveApi = new KyveApi(chainId, kyveEndpoint); - await kyveApi.init(); + const kyveApi = await KyveApi.create(chainId, kyveConfig); const connection = new KyveConnection( kyveApi.fetchBlocksBatches.bind(kyveApi), chainId, + registry, ); - connection.setRegistry(registry); - logger.info(`connected to Kyve via ${kyveEndpoint}`); + logger.info(`connected to Kyve via ${kyveConfig.storageUrl}`); return connection; } @@ -68,20 +70,15 @@ export class KyveConnection ); } - private setRegistry(registry: Registry): void { - this.registry = registry; - } - - // No safeAPi safeApi(height: number): any { - return undefined; + throw new Error('SafeApi should not be used for kyve-connection'); } async apiConnect(): Promise { - return Promise.resolve(undefined); + // } async apiDisconnect(): Promise { - return Promise.resolve(undefined); + // } } diff --git a/packages/node/src/yargs.ts b/packages/node/src/yargs.ts index 4104e7610..7a0c742f7 100644 --- a/packages/node/src/yargs.ts +++ b/packages/node/src/yargs.ts @@ -23,9 +23,22 @@ export const yargsOptions = yargsBuilder({ return reindexInit(targetHeight); }, runOptions: { - kyve: { + kyveChainId: { demandOption: false, - describe: 'Use blocks from kyve instead of rpc', + describe: + 'When indexing from Kyve, please implement a supported kyve chain-id, it is defaulted to "kyve-1"', + type: 'string', + }, + kyveEndpoint: { + demandOption: false, + describe: + 'If indexing a network that Kyve supports adding a Kyve RPC endpoint will fetch blocks from Kyve', + type: 'string', + }, + storageUrl: { + demandOption: false, + describe: + 'When indexing from kyve, you can alternatively provide a different storageUrl to index data from, it is defaulted to arweave.', type: 'string', }, }, From db397bed38e9419f463d6c7b96e0a54eb845ecb8 Mon Sep 17 00:00:00 2001 From: bz888 Date: Thu, 4 Apr 2024 17:38:13 +0800 Subject: [PATCH 14/81] remove todo --- packages/node/src/utils/cosmos.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index 21538b08f..65183893d 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -254,7 +254,6 @@ export function wrapCosmosMsg( typeUrl: rawMessage.typeUrl, get decodedMsg() { delete this.decodedMsg; - // TODO, unsure how this will impact the decode return (this.decodedMsg = decodeMsg(rawMessage, registry)); }, }, From f9287745229bb87ccd66724d7bcfb33ea3ae97f6 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 5 Apr 2024 12:49:56 +0800 Subject: [PATCH 15/81] update logic for lazyBlock and refactored based on comments, added tests for new log injector --- packages/node/src/indexer/api.service.ts | 77 +++++----- .../src/indexer/cosmosClient.connection.ts | 1 - packages/node/src/init.ts | 1 + packages/node/src/utils/cosmos.ts | 13 +- packages/node/src/utils/kyve/kyve.spec.ts | 73 +++++++-- packages/node/src/utils/kyve/kyve.ts | 142 ++++++++++-------- .../node/src/utils/kyve/kyveConnection.ts | 34 +++-- packages/node/src/yargs.ts | 7 +- 8 files changed, 214 insertions(+), 134 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 569137ede..9d961c553 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -24,8 +24,6 @@ import { ApiService as BaseApiService, IBlock, NodeConfig, - IndexerEvent, - IApiConnectionSpecific, } from '@subql/node-core'; import { CosmWasmSafeClient } from '@subql/types-cosmos/interfaces'; import { @@ -89,48 +87,55 @@ export class ApiService await this.connectionPoolService.onApplicationShutdown(); } - private async createKyveConnection( - network: CosmosNetworkConfig, - createConnection: (chainId: string) => Promise, - ) { - const connection = await createConnection(network.chainId); - - this.eventEmitter.emit(IndexerEvent.ApiConnected, { - value: 1, - apiIndex: 0, - endpoint: this.nodeConfig.kyveEndpoint, - }); - } - async init(): Promise { const { network } = this.project; this.registry = await this.buildRegistry(); - if (this.nodeConfig.kyveChainId || this.nodeConfig.kyveEndpoint) { - await this.createKyveConnection(network, () => - KyveConnection.create(network.chainId, this.registry, { - storageUrl: this.nodeConfig.storageUrl ?? 'https://arweave.net', - kyveChainId: this.nodeConfig.kyveChainId ?? 'kyve-1', - kyveEndpoint: this.nodeConfig.kyveEndpoint, - }), + if (this.nodeConfig.kyveEndpoint) { + if (this.nodeConfig.workers > 0 || this.nodeConfig.unfinalizedBlocks) { + throw new Error( + `Unfinalized blocks and workers are not supported by kyve indexing`, + ); + } + + // still need to use cosmosClient to proxy rpcCalls + const cosmosClient = await CosmosClientConnection.create( + (network.endpoint as string[])[0], + this.fetchBlocksBatches, + this.registry, ); - } - await this.createConnections( - network, - (endpoint) => - CosmosClientConnection.create( - endpoint, - this.fetchBlocksBatches, - this.registry, - ), - (connection: CosmosClientConnection) => { - const api = connection.unsafeApi; - return api.getChainId(); - }, - ); + await this.createConnections( + network, + (endpoint) => + KyveConnection.create( + this.nodeConfig.kyveEndpoint, + network.chainId, + this.registry, + this.nodeConfig.storageUrl, + this.nodeConfig.kyveChainId, + cosmosClient, + ), + (connection: KyveConnection) => Promise.resolve(network.chainId), + ); + } else { + await this.createConnections( + network, + (endpoint) => + CosmosClientConnection.create( + endpoint, + this.fetchBlocksBatches, + this.registry, + ), + (connection: CosmosClientConnection) => { + const api = connection.unsafeApi; + return api.getChainId(); + }, + ); + } + // } return this; } diff --git a/packages/node/src/indexer/cosmosClient.connection.ts b/packages/node/src/indexer/cosmosClient.connection.ts index 0bb612994..cb0e1a224 100644 --- a/packages/node/src/indexer/cosmosClient.connection.ts +++ b/packages/node/src/indexer/cosmosClient.connection.ts @@ -30,7 +30,6 @@ const RETRY_DELAY = 2_500; const logger = getLogger('cosmos-client-connection'); type FetchFunc = ( - registry: Registry, batch: number[], api: CosmosClient, wrapEventsFunc: ( diff --git a/packages/node/src/init.ts b/packages/node/src/init.ts index 535a50073..45295bff8 100644 --- a/packages/node/src/init.ts +++ b/packages/node/src/init.ts @@ -63,6 +63,7 @@ export async function bootstrap(): Promise { logger.info(`Node started on port: ${port}`); } catch (e) { + console.trace(e); logger.error(e, 'Node failed to start'); process.exit(1); } diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index 65183893d..5a642aed6 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -203,7 +203,7 @@ async function getBlockByHeightByRpc( ]); } -export async function fetchCosmosBlocksArray( +export async function fetchCosmosBlocksArray( getBlockByHeight: ( height: number, ) => Promise<[BlockResponse, BlockResultsResponse]>, @@ -355,7 +355,6 @@ export function formatBlockUtil(block: B): IBlock { } export async function fetchBlocksBatches( - registry: Registry, blockArray: number[], api: CosmosClient, ): Promise[]> { @@ -372,7 +371,7 @@ export async function fetchBlocksBatches( ); return formatBlockUtil( - new LazyBlockContent(blockInfo, blockResults, registry, wrapEvent) + new LazyBlockContent(blockInfo, blockResults, api.registry) ); } catch (e) { logger.error( @@ -397,12 +396,6 @@ export class LazyBlockContent implements BlockContent { private _blockInfo: BlockResponse, private _results: BlockResultsResponse, private _registry: Registry, - private wrapEventsFunc: ( - block: CosmosBlock, - txs: CosmosTransaction[], - registry: Registry, - eventIdx: number, - ) => CosmosEvent[], ) {} get block() { @@ -434,7 +427,7 @@ export class LazyBlockContent implements BlockContent { get events() { if (!this._wrappedEvent) { - this._wrappedEvent = this.wrapEventsFunc( + this._wrappedEvent = wrapEvent( this.block, this.transactions, this._registry, diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index ef707f22a..4c60b5561 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -5,6 +5,11 @@ import path from 'path'; import { GeneratedType, Registry } from '@cosmjs/proto-signing'; import { defaultRegistryTypes } from '@cosmjs/stargate'; import { Tendermint37Client } from '@cosmjs/tendermint-rpc'; +import { + BlockResponse, + BlockResultsResponse, +} from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; +import axios from 'axios'; import { MsgClearAdmin, MsgExecuteContract, @@ -15,7 +20,7 @@ import { } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; import { isEqual } from 'lodash'; import { HttpClient } from '../../indexer/rpc-clients'; -import { LazyBlockContent, wrapEvent } from '../cosmos'; +import { LazyBlockContent } from '../cosmos'; import { KyveApi } from './kyve'; const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ @@ -41,7 +46,12 @@ describe('KyveApi', () => { beforeAll(async () => { registry = new Registry([...defaultRegistryTypes, ...wasmTypes]); - kyveApi = await KyveApi.create('archway-1'); + kyveApi = await KyveApi.create( + 'archway-1', + 'https://rpc-eu-1.kyve.network', + 'https://arweave.net', + 'kyve-1', + ); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); }); @@ -76,7 +86,7 @@ describe('KyveApi', () => { }); it('ensure correct bundle ID on binary search', async () => { - (kyveApi as any).currentBundleId = 0; // reset cached bundle Id + (kyveApi as any).currentBundleId = -1; // reset cached bundle Id const a = Date.now(); const firstBundle = await (kyveApi as any).getBundleId(120); // https://app.kyve.network/#/pools/2/bundles/0 const b = Date.now(); @@ -86,6 +96,37 @@ describe('KyveApi', () => { expect(firstBundle).toBe(0); expect(laterBundle).toBe(113773); }); + it('retreive and unzip storage data', async () => { + // const data = await (kyveApi as any).retrieveBundleData( + // 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', + // 100000 + // ) + console.log('ji test '); + const d = await axios.get( + 'https://arweave.net/YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', + { + headers: { + 'User-Agent': `SubQuery-Node 3.9.2`, + Connection: 'keep-alive', + 'Content-Encoding': 'gzip', + 'Content-Type': 'application/gzip', + }, + timeout: 60000, + }, + ); + console.log('!!?!'); + console.log('claimed data'); + // const unzipped = await (kyveApi as any).unzipStorageData('1', data) + // console.log(unzipped) + }); + it('Should increment bundleId when height exceeds cache', async () => { + (kyveApi as any).currentBundleId = 0; + (kyveApi as any).cachedBundle = 'value'; + + await (kyveApi as any).validateCache(160, { to_key: '150' } as any); + + expect((kyveApi as any).currentBundleId).toBe(1); + }); it('compare block info', async () => { const height = 3901476; const tendermintBlockInfo = await tendermint.block(height); @@ -99,10 +140,12 @@ describe('KyveApi', () => { describe('able to wrap kyveBlock', () => { let rpcLazyBlockContent: LazyBlockContent; let kyveLazyBlockContent: LazyBlockContent; + let tendermintBlockInfo: BlockResponse; + let tendermintBlockResult: BlockResultsResponse; beforeAll(async () => { const height = 3856726; - const [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ + [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ tendermint.block(height), tendermint.blockResults(height), ]); @@ -117,17 +160,23 @@ describe('KyveApi', () => { tendermintBlockInfo, tendermintBlockResult, registry, - wrapEvent, - ); - kyveLazyBlockContent = new LazyBlockContent( - bi, - br, - registry, - kyveApi.wrapEvent.bind(kyveApi), ); + kyveLazyBlockContent = new LazyBlockContent(bi, br, registry); + }); + it('compare kyve wrapped results with rpc results', () => { + const blockResults = bundle_3856726.value.block_results; + + const br = (kyveApi as any).decodeBlockResult(blockResults); + + const logs = (kyveApi as any).reconstructLogs(br); + expect(logs.length).toBe(2); + expect(logs[0].events.length).toBe(3); + expect(logs[1].events.length).toBe(5); + + const reconstructedKyveBlock = (kyveApi as any).injectLogs(br); + expect(reconstructedKyveBlock.results[0].log).toBeDefined(); }); it('wrapTransaction', () => { - // note: kyve log is undefined expect(kyveLazyBlockContent.transactions[0].tx.data.length).toBe( rpcLazyBlockContent.transactions[0].tx.data.length, ); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 7d1e16ad8..a4c204bfd 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -4,6 +4,7 @@ import assert from 'assert'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; import { Registry } from '@cosmjs/proto-signing'; +import { Log } from '@cosmjs/stargate/build/logs'; import { adaptor37 } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; import { BlockResponse, @@ -19,14 +20,9 @@ import { QueryPoolsResponse, } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; import { getLogger } from '@subql/node-core'; -import { - CosmosBlock, - CosmosEvent, - CosmosTransaction, -} from '@subql/types-cosmos'; import axios, { AxiosRequestConfig } from 'axios'; import { BlockContent } from '../../indexer/types'; -import { LazyBlockContent, wrapCosmosMsg } from '../cosmos'; +import { LazyBlockContent } from '../cosmos'; import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms @@ -35,42 +31,41 @@ const parseDecimal = (value: string) => parseInt(value, 10); const logger = getLogger('kyve'); +// eslint-disable-next-line @typescript-eslint/no-var-requires +const { version: packageVersion } = require('../../../package.json'); + interface UnZippedKyveBlockReponse { value: { block: any; block_results: any }; key: string; } -export type KyveConnectionConfig = { - storageUrl?: string; - kyveEndpoint?: string; - kyveChainId?: SupportedChains; -}; - export class KyveApi { private lcdClient: KyveLCDClientType; private respAdaptor = adaptor37.responses; private poolId: string; - private currentBundleId: number; + private currentBundleId = -1; private cachedBlocks: UnZippedKyveBlockReponse[]; - private cachedBundle: any; // storage Data - private storageUrl: string; - - private constructor(private chainId: string) {} + private cachedBundle: StorageReceipt; // storage Data + + private constructor( + private chainId: string, + private endpoint: string, + private readonly storageUrl: string, + private readonly kyveChainId: SupportedChains, + ) { + this.lcdClient = new KyveSDK(kyveChainId, { + rpc: this.endpoint, + }).createLCDClient(); + this.storageUrl = storageUrl; + } static async create( chainId: string, // chainId for indexing chain - kyveConfig?: KyveConnectionConfig, + endpoint: string, + storageUrl: string, + kyveChainId: SupportedChains, ): Promise { - const kyve = new KyveApi(chainId); - - kyve.lcdClient = new KyveSDK( - kyveConfig.kyveChainId, - kyveConfig.kyveEndpoint ? { rpc: kyveConfig.kyveEndpoint } : undefined, - ).createLCDClient(); - - kyve.storageUrl = kyveConfig.storageUrl; - kyve.currentBundleId = 0; - + const kyve = new KyveApi(chainId, endpoint, storageUrl, kyveChainId); await kyve.setPoolId(); return kyve; @@ -91,6 +86,7 @@ export class KyveApi { for (const p of pools.pools) { try { const config = JSON.parse(p.data.config); + if (config.network === this.chainId) { pool = p as unknown as PoolResponse; break; @@ -121,7 +117,11 @@ export class KyveApi { const buffer = await g.decompress(storageData); const parsedString = buffer.toString('utf-8'); - return JSON.parse(parsedString); + try { + return JSON.parse(parsedString); + } catch (e) { + throw new Error(`Failed to parse storageData. ${e}`); + } } private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { @@ -204,6 +204,8 @@ export class KyveApi { private async validateCache(height: number, bundleDetails: BundleDetails) { if (!this.cachedBundle || parseDecimal(bundleDetails.to_key) > height) { + this.currentBundleId++; + this.cachedBundle = await this.retrieveBundleData( bundleDetails.storage_id, BUNDLE_TIMEOUT, @@ -219,51 +221,67 @@ export class KyveApi { async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { - const bundleId = await this.getBundleId(height); - const bundleDetails = await this.getBundleById(bundleId); + const bundleId = + this.currentBundleId === -1 + ? await this.getBundleId(height) + : this.currentBundleId; + const bundleDetails = await this.getBundleById(bundleId); await this.validateCache(height, bundleDetails); const blockData = this.findBlockByHeight(height); return [ this.decodeBlock(blockData.value.block), - this.decodeBlockResult(blockData.value.block_results), + this.injectLogs(this.decodeBlockResult(blockData.value.block_results)), ]; } - wrapEvent( - block: CosmosBlock, - txs: CosmosTransaction[], - registry: Registry, - idxOffset: number, //use this offset to avoid clash with idx of begin block events - ): CosmosEvent[] { - const events: CosmosEvent[] = []; - for (const tx of txs) { + private injectLogs(kyveBlockResult: BlockResultsResponse) { + try { + kyveBlockResult.results.forEach((b) => { + // log is readonly hence needing to cast it + (b.log as any) = JSON.stringify(this.reconstructLogs(kyveBlockResult)); + }); + } catch (e) { + throw new Error(`Failed to inject kyveBlock`); + } + return kyveBlockResult; + } + + private reconstructLogs(blockResultResponse: BlockResultsResponse): Log[] { + const logs: Log[] = []; + + for (const tx of blockResultResponse.results) { + let currentLog: any = { + msg_index: -1, + events: [], + }; + let msgIndex = -1; - for (const event of tx.tx.events) { - if ( + for (const event of tx.events) { + const isMessageEvent = event.type === 'message' && - event.attributes.find((e) => e.key === 'action') - ) { + event.attributes.some((e) => e.key === 'action'); + + if (isMessageEvent) { + if (msgIndex >= 0) { + logs.push(currentLog); + } msgIndex += 1; + currentLog = { msg_index: msgIndex, events: [] }; } if (msgIndex >= 0) { - const msg = wrapCosmosMsg(block, tx, msgIndex, registry); - const cosmosEvent: CosmosEvent = { - idx: idxOffset++, - msg, - tx, - block, - log: undefined, - event, - }; - events.push(cosmosEvent); + currentLog.events.push(event); } } + + if (currentLog.events.length > 0) { + logs.push(currentLog); + } } - return events; + return logs; } private async fetchBlocksArray( @@ -280,10 +298,15 @@ export class KyveApi { ): Promise { const axiosConfig: AxiosRequestConfig = { method: 'get', - url: `/${storageId}`, + url: `${storageId}`, baseURL: this.storageUrl, responseType: 'arraybuffer', timeout, + headers: { + 'User-Agent': `SubQuery-Node ${packageVersion}`, + Connection: 'keep-alive', + 'Content-Encoding': 'gzip', + }, }; const { data: storageData } = await axios(axiosConfig); @@ -302,12 +325,7 @@ export class KyveApi { `txInfos doesn't match up with block (${blockInfo.block.header.height}) transactions expected ${blockInfo.block.txs.length}, received: ${blockResults.results.length}`, ); - return new LazyBlockContent( - blockInfo, - blockResults, - registry, - this.wrapEvent.bind(this), - ); + return new LazyBlockContent(blockInfo, blockResults, registry); } catch (e) { logger.error( e, diff --git a/packages/node/src/utils/kyve/kyveConnection.ts b/packages/node/src/utils/kyve/kyveConnection.ts index e0b4b6944..710a663fc 100644 --- a/packages/node/src/utils/kyve/kyveConnection.ts +++ b/packages/node/src/utils/kyve/kyveConnection.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0 import { Registry } from '@cosmjs/proto-signing'; +import { SupportedChains } from '@kyvejs/sdk/src/constants'; import { ApiConnectionError, ApiErrorType, @@ -9,8 +10,10 @@ import { IApiConnectionSpecific, NetworkMetadataPayload, } from '@subql/node-core'; +import { CosmosClient } from '../../indexer/api.service'; +import { CosmosClientConnection } from '../../indexer/cosmosClient.connection'; import { BlockContent } from '../../indexer/types'; -import { KyveApi, KyveConnectionConfig } from './kyve'; +import { KyveApi } from './kyve'; const logger = getLogger('kyve-API'); @@ -20,37 +23,48 @@ type KyveFetchFunc = ( ) => Promise; export class KyveConnection - implements IApiConnectionSpecific + implements IApiConnectionSpecific { - unsafeApi: any; + unsafeApi: CosmosClient; readonly networkMeta: NetworkMetadataPayload; private constructor( private fetchBlocksBatches: KyveFetchFunc, - private chainId: string, + chainId: string, private registry: Registry, + cosmosClient: CosmosClientConnection, ) { this.networkMeta = { - chain: this.chainId, + chain: chainId, specName: undefined, genesisHash: undefined, }; + this.unsafeApi = cosmosClient.unsafeApi; } static async create( + endpoint: string, // kyve LCD Endpoint chainId: string, registry: Registry, - kyveConfig: KyveConnectionConfig, + storageUrl: string, + kyveChainId: SupportedChains, + cosmosClient: CosmosClientConnection, ): Promise { - const kyveApi = await KyveApi.create(chainId, kyveConfig); + const kyveApi = await KyveApi.create( + chainId, + endpoint, + storageUrl, + kyveChainId, + ); const connection = new KyveConnection( kyveApi.fetchBlocksBatches.bind(kyveApi), chainId, registry, + cosmosClient, ); - logger.info(`connected to Kyve via ${kyveConfig.storageUrl}`); + logger.info(`connected to Kyve via ${endpoint}`); return connection; } @@ -75,10 +89,10 @@ export class KyveConnection } async apiConnect(): Promise { - // + return Promise.resolve(); } async apiDisconnect(): Promise { - // + return Promise.resolve(); } } diff --git a/packages/node/src/yargs.ts b/packages/node/src/yargs.ts index 7a0c742f7..97e7a3c65 100644 --- a/packages/node/src/yargs.ts +++ b/packages/node/src/yargs.ts @@ -25,14 +25,14 @@ export const yargsOptions = yargsBuilder({ runOptions: { kyveChainId: { demandOption: false, - describe: - 'When indexing from Kyve, please implement a supported kyve chain-id, it is defaulted to "kyve-1"', + describe: 'When indexing from Kyve, supported kyve chain-id', type: 'string', + default: 'kyve-1', }, kyveEndpoint: { demandOption: false, describe: - 'If indexing a network that Kyve supports adding a Kyve RPC endpoint will fetch blocks from Kyve', + 'If indexing a network that Kyve supports adding a Kyve LCD endpoint will fetch blocks from Kyve', type: 'string', }, storageUrl: { @@ -40,6 +40,7 @@ export const yargsOptions = yargsBuilder({ describe: 'When indexing from kyve, you can alternatively provide a different storageUrl to index data from, it is defaulted to arweave.', type: 'string', + default: 'https://arweave.net', }, }, }); From 27d6ad1b67b3a0d3631f86ee8960d1c2f0e3b124 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 5 Apr 2024 14:00:55 +0800 Subject: [PATCH 16/81] update logic and test --- packages/node/src/utils/kyve/kyve.spec.ts | 33 +++++++---------------- packages/node/src/utils/kyve/kyve.ts | 2 +- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 4c60b5561..0474d9e3b 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -56,6 +56,10 @@ describe('KyveApi', () => { tendermint = await Tendermint37Client.create(client); }); + afterEach(() => { + (kyveApi as any).currentBundleId = -1; // reset bundleId + }); + // TODO: all the test to fetch bundle from arweave is failing on timeout. it('getBundle by height', async () => { const [, blockResponse] = await kyveApi.getBlockByHeight(3856726); @@ -96,35 +100,18 @@ describe('KyveApi', () => { expect(firstBundle).toBe(0); expect(laterBundle).toBe(113773); }); - it('retreive and unzip storage data', async () => { - // const data = await (kyveApi as any).retrieveBundleData( - // 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', - // 100000 - // ) - console.log('ji test '); - const d = await axios.get( - 'https://arweave.net/YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', - { - headers: { - 'User-Agent': `SubQuery-Node 3.9.2`, - Connection: 'keep-alive', - 'Content-Encoding': 'gzip', - 'Content-Type': 'application/gzip', - }, - timeout: 60000, - }, + it('retrieve and unzip storage data', async () => { + const data = await (kyveApi as any).retrieveBundleData( + 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', + 100000, ); - console.log('!!?!'); - console.log('claimed data'); - // const unzipped = await (kyveApi as any).unzipStorageData('1', data) - // console.log(unzipped) + const unzipped = await (kyveApi as any).unzipStorageData('1', data); + expect(unzipped).toBeDefined(); }); it('Should increment bundleId when height exceeds cache', async () => { (kyveApi as any).currentBundleId = 0; (kyveApi as any).cachedBundle = 'value'; - await (kyveApi as any).validateCache(160, { to_key: '150' } as any); - expect((kyveApi as any).currentBundleId).toBe(1); }); it('compare block info', async () => { diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index a4c204bfd..21e03c9d2 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -203,7 +203,7 @@ export class KyveApi { } private async validateCache(height: number, bundleDetails: BundleDetails) { - if (!this.cachedBundle || parseDecimal(bundleDetails.to_key) > height) { + if (!this.cachedBundle || height > parseDecimal(bundleDetails.to_key)) { this.currentBundleId++; this.cachedBundle = await this.retrieveBundleData( From b7f6757d29bf2e9c8466b87e623c0627d74d4e61 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 5 Apr 2024 14:37:14 +0800 Subject: [PATCH 17/81] update logic on getBlockByHeight --- packages/node/src/utils/kyve/kyve.spec.ts | 13 +++++---- packages/node/src/utils/kyve/kyve.ts | 33 ++++++++++++++--------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 0474d9e3b..3c23541d6 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -9,7 +9,6 @@ import { BlockResponse, BlockResultsResponse, } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; -import axios from 'axios'; import { MsgClearAdmin, MsgExecuteContract, @@ -60,11 +59,6 @@ describe('KyveApi', () => { (kyveApi as any).currentBundleId = -1; // reset bundleId }); - // TODO: all the test to fetch bundle from arweave is failing on timeout. - it('getBundle by height', async () => { - const [, blockResponse] = await kyveApi.getBlockByHeight(3856726); - expect(blockResponse).toEqual(bundle_3856726); - }); it('ensure bundleDetails', async () => { const bundleDetails = await (kyveApi as any).getBundleById(0); expect(bundleDetails).toEqual({ @@ -111,7 +105,12 @@ describe('KyveApi', () => { it('Should increment bundleId when height exceeds cache', async () => { (kyveApi as any).currentBundleId = 0; (kyveApi as any).cachedBundle = 'value'; - await (kyveApi as any).validateCache(160, { to_key: '150' } as any); + (kyveApi as any).cachedBundleDetails = { + to_key: '150', + storage_id: 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', + compression_id: '1', + } as any; + await (kyveApi as any).updateCurrentBundleAndDetails(160); expect((kyveApi as any).currentBundleId).toBe(1); }); it('compare block info', async () => { diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 21e03c9d2..e9f3f67da 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -44,8 +44,9 @@ export class KyveApi { private respAdaptor = adaptor37.responses; private poolId: string; private currentBundleId = -1; + private cachedBundleDetails: BundleDetails; private cachedBlocks: UnZippedKyveBlockReponse[]; - private cachedBundle: StorageReceipt; // storage Data + private cachedBundle: StorageReceipt; private constructor( private chainId: string, @@ -202,17 +203,28 @@ export class KyveApi { ); } - private async validateCache(height: number, bundleDetails: BundleDetails) { - if (!this.cachedBundle || height > parseDecimal(bundleDetails.to_key)) { - this.currentBundleId++; + async updateCurrentBundleAndDetails(height: number): Promise { + if ( + this.currentBundleId === -1 || + parseDecimal(this.cachedBundleDetails.to_key) < height + ) { + this.currentBundleId = + this.currentBundleId === -1 + ? await this.getBundleId(height) + : this.currentBundleId + 1; + this.cachedBundleDetails = await this.getBundleById(this.currentBundleId); + } + } + async initializeOrUpdateCachedBundle(): Promise { + if (!this.cachedBundle) { this.cachedBundle = await this.retrieveBundleData( - bundleDetails.storage_id, + this.cachedBundleDetails.storage_id, BUNDLE_TIMEOUT, ); this.cachedBlocks = await this.unzipStorageData( - bundleDetails.compression_id, + this.cachedBundleDetails.compression_id, this.cachedBundle.storageData, ); } @@ -221,13 +233,8 @@ export class KyveApi { async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { - const bundleId = - this.currentBundleId === -1 - ? await this.getBundleId(height) - : this.currentBundleId; - - const bundleDetails = await this.getBundleById(bundleId); - await this.validateCache(height, bundleDetails); + await this.updateCurrentBundleAndDetails(height); + await this.initializeOrUpdateCachedBundle(); const blockData = this.findBlockByHeight(height); From ea4fce9929fe8bed35cfd1b8f9b5cc3bfc9d5722 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 5 Apr 2024 14:41:36 +0800 Subject: [PATCH 18/81] update test cache --- packages/node/src/utils/kyve/kyve.spec.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 3c23541d6..565fce92b 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -56,7 +56,11 @@ describe('KyveApi', () => { }); afterEach(() => { - (kyveApi as any).currentBundleId = -1; // reset bundleId + // reset cache + (kyveApi as any).currentBundleId = -1; + (kyveApi as any).cachedBundleDetails = undefined; + (kyveApi as any).cachedBundle = undefined; + (kyveApi as any).cachedBlocks = undefined; }); it('ensure bundleDetails', async () => { From 79fd593c94b8f9ac86b1e726f57baa814e803cc5 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 5 Apr 2024 14:44:13 +0800 Subject: [PATCH 19/81] update changelog --- packages/node/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/node/CHANGELOG.md b/packages/node/CHANGELOG.md index 17fcdcc8c..ae70e9370 100644 --- a/packages/node/CHANGELOG.md +++ b/packages/node/CHANGELOG.md @@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Added +- Support for KYVE integration with supporting flags (#235) + - `--kyveEndpoint` + - `--kyveChainId` + - `--storageUrl` ## [3.10.0] - 2024-04-10 ### Changed From aa0090c5b11582a6e13067bfb95f85beadb8f176 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 5 Apr 2024 14:56:39 +0800 Subject: [PATCH 20/81] fixed kyve test --- packages/node/src/utils/kyve/kyve.spec.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 565fce92b..a132d0df7 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -103,7 +103,10 @@ describe('KyveApi', () => { 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', 100000, ); - const unzipped = await (kyveApi as any).unzipStorageData('1', data); + const unzipped = await (kyveApi as any).unzipStorageData( + '1', + data.storageData, + ); expect(unzipped).toBeDefined(); }); it('Should increment bundleId when height exceeds cache', async () => { From b3453160504a0d312d758d4d7d42f1af7868dec2 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 5 Apr 2024 14:59:05 +0800 Subject: [PATCH 21/81] update yargs --- packages/node/src/yargs.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node/src/yargs.ts b/packages/node/src/yargs.ts index 97e7a3c65..13ef20130 100644 --- a/packages/node/src/yargs.ts +++ b/packages/node/src/yargs.ts @@ -23,19 +23,19 @@ export const yargsOptions = yargsBuilder({ return reindexInit(targetHeight); }, runOptions: { - kyveChainId: { + 'kyve-chain-id': { demandOption: false, describe: 'When indexing from Kyve, supported kyve chain-id', type: 'string', default: 'kyve-1', }, - kyveEndpoint: { + 'kyve-endpoint': { demandOption: false, describe: 'If indexing a network that Kyve supports adding a Kyve LCD endpoint will fetch blocks from Kyve', type: 'string', }, - storageUrl: { + 'storage-url': { demandOption: false, describe: 'When indexing from kyve, you can alternatively provide a different storageUrl to index data from, it is defaulted to arweave.', From 0440ed974128525d1dbcda635877e9583ba49802 Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 8 Apr 2024 07:24:36 +0800 Subject: [PATCH 22/81] tidy ups --- packages/node/src/indexer/api.service.ts | 13 +++++++------ packages/node/src/utils/kyve/kyve.ts | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 9d961c553..c4dfc1c7d 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -61,6 +61,13 @@ export class ApiService super(connectionPoolService, eventEmitter); this.nodeConfig = new CosmosNodeConfig(nodeConfig); } + // create a temp file + // download the block content + + // the first worker that would load the bundle + // file lock to control permission on doing it + + // clean up old bundles private async buildRegistry(): Promise { const chaintypes = await this.getChainType(this.project.network); @@ -93,12 +100,6 @@ export class ApiService this.registry = await this.buildRegistry(); if (this.nodeConfig.kyveEndpoint) { - if (this.nodeConfig.workers > 0 || this.nodeConfig.unfinalizedBlocks) { - throw new Error( - `Unfinalized blocks and workers are not supported by kyve indexing`, - ); - } - // still need to use cosmosClient to proxy rpcCalls const cosmosClient = await CosmosClientConnection.create( (network.endpoint as string[])[0], diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index e9f3f67da..2cb9a47af 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -54,7 +54,7 @@ export class KyveApi { private readonly storageUrl: string, private readonly kyveChainId: SupportedChains, ) { - this.lcdClient = new KyveSDK(kyveChainId, { + this.lcdClient = new KyveSDK(this.kyveChainId, { rpc: this.endpoint, }).createLCDClient(); this.storageUrl = storageUrl; From 18acfa9d8eb59de25a955862ad9e368b66028983 Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 8 Apr 2024 22:31:44 +0800 Subject: [PATCH 23/81] refactor with worker and file cache logic, addeds tests --- packages/node/src/indexer/api.service.ts | 3 + packages/node/src/utils/kyve/kyve.spec.ts | 86 ++++++++++++ packages/node/src/utils/kyve/kyve.ts | 132 +++++++++++++++--- .../node/src/utils/kyve/kyveConnection.ts | 2 + 4 files changed, 200 insertions(+), 23 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index c4dfc1c7d..735e99e0b 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -17,6 +17,7 @@ import { } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; +import { makeTempDir } from '@subql/common'; import { CosmosProjectNetConfig } from '@subql/common-cosmos'; import { getLogger, @@ -100,6 +101,7 @@ export class ApiService this.registry = await this.buildRegistry(); if (this.nodeConfig.kyveEndpoint) { + const tmpDir = await makeTempDir(); // still need to use cosmosClient to proxy rpcCalls const cosmosClient = await CosmosClientConnection.create( (network.endpoint as string[])[0], @@ -117,6 +119,7 @@ export class ApiService this.nodeConfig.storageUrl, this.nodeConfig.kyveChainId, cosmosClient, + tmpDir, ), (connection: KyveConnection) => Promise.resolve(network.chainId), ); diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index a132d0df7..1c479cd28 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -9,6 +9,7 @@ import { BlockResponse, BlockResultsResponse, } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; +import { makeTempDir } from '@subql/common'; import { MsgClearAdmin, MsgExecuteContract, @@ -43,13 +44,20 @@ describe('KyveApi', () => { let tendermint: Tendermint37Client; let registry: Registry; + let tmpPath: string; + let retrieveBundleDataSpy: jest.SpyInstance; + let unzipStorageDataSpy: jest.SpyInstance; + beforeAll(async () => { + tmpPath = await makeTempDir(); + registry = new Registry([...defaultRegistryTypes, ...wasmTypes]); kyveApi = await KyveApi.create( 'archway-1', 'https://rpc-eu-1.kyve.network', 'https://arweave.net', 'kyve-1', + tmpPath, ); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); @@ -61,6 +69,9 @@ describe('KyveApi', () => { (kyveApi as any).cachedBundleDetails = undefined; (kyveApi as any).cachedBundle = undefined; (kyveApi as any).cachedBlocks = undefined; + + retrieveBundleDataSpy.mockRestore(); + unzipStorageDataSpy.mockRestore(); }); it('ensure bundleDetails', async () => { @@ -130,6 +141,81 @@ describe('KyveApi', () => { expect((kyveApi as any).poolId).toBe('2'); expect((kyveApi as any).chainId).toBe('archway-1'); }); + it('able to download and write to file', async () => { + (kyveApi as any).cachedBundleDetails = { + id: '1', + to_key: '150', + storage_id: 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', + compression_id: '1', + } as any; + + retrieveBundleDataSpy = jest + .spyOn(kyveApi as any, 'retrieveBundleData') + .mockImplementation(() => + Promise.resolve({ + storageData: Buffer.from(JSON.stringify(bundle_3856726)), + }), + ); + + unzipStorageDataSpy = jest + .spyOn(kyveApi as any, 'unzipStorageData') + .mockImplementation(() => + Promise.resolve(Buffer.from(JSON.stringify(bundle_3856726))), + ); + + const writerSpy = jest.spyOn(kyveApi as any, 'writeToFile'); + const height = 160; + + await kyveApi.updateCurrentBundleAndDetails(height); + + await expect( + Promise.all([ + kyveApi.updateCurrentBundleAndDetails(height), + kyveApi.updateCurrentBundleAndDetails(height), + ]), + ).resolves.not.toThrow(); + + await expect( + (kyveApi as any).readFromFile( + path.join(tmpPath, `bundle_${(kyveApi as any).cachedBundleDetails.id}`), + ), + ).resolves.toEqual(bundle_3856726); + + expect(writerSpy).toHaveBeenCalledTimes(1); + expect((kyveApi as any).cachedBundleDetails.to_index).toBe('300'); + }); + it('race condition on file cache', async () => { + (kyveApi as any).cachedBundleDetails = { + id: '1', + to_key: '150', + storage_id: 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', + compression_id: '1', + } as any; + const height = 160; + + retrieveBundleDataSpy = jest + .spyOn(kyveApi as any, 'retrieveBundleData') + .mockImplementation(() => + Promise.resolve({ + storageData: Buffer.from(JSON.stringify(bundle_3856726)), + }), + ); + + unzipStorageDataSpy = jest + .spyOn(kyveApi as any, 'unzipStorageData') + .mockImplementation(() => + Promise.resolve(Buffer.from(JSON.stringify(bundle_3856726))), + ); + + await Promise.all([ + kyveApi.updateCurrentBundleAndDetails(height), + kyveApi.updateCurrentBundleAndDetails(height), + kyveApi.updateCurrentBundleAndDetails(height), + kyveApi.updateCurrentBundleAndDetails(height), + ]); + + // read from folder and ensure that there is content + }); describe('able to wrap kyveBlock', () => { let rpcLazyBlockContent: LazyBlockContent; let kyveLazyBlockContent: LazyBlockContent; diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 2cb9a47af..20742924b 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -2,6 +2,8 @@ // SPDX-License-Identifier: GPL-3.0 import assert from 'assert'; +import fs from 'fs'; +import path from 'path'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; import { Registry } from '@cosmjs/proto-signing'; import { Log } from '@cosmjs/stargate/build/logs'; @@ -26,6 +28,7 @@ import { LazyBlockContent } from '../cosmos'; import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms +const POLL_TIMER = 1000; // ms const parseDecimal = (value: string) => parseInt(value, 10); @@ -40,19 +43,18 @@ interface UnZippedKyveBlockReponse { } export class KyveApi { - private lcdClient: KyveLCDClientType; + private readonly lcdClient: KyveLCDClientType; private respAdaptor = adaptor37.responses; private poolId: string; private currentBundleId = -1; private cachedBundleDetails: BundleDetails; - private cachedBlocks: UnZippedKyveBlockReponse[]; - private cachedBundle: StorageReceipt; private constructor( private chainId: string, private endpoint: string, private readonly storageUrl: string, private readonly kyveChainId: SupportedChains, + private readonly tmpCacheDir: string, ) { this.lcdClient = new KyveSDK(this.kyveChainId, { rpc: this.endpoint, @@ -65,8 +67,15 @@ export class KyveApi { endpoint: string, storageUrl: string, kyveChainId: SupportedChains, + tmpCacheDir: string, ): Promise { - const kyve = new KyveApi(chainId, endpoint, storageUrl, kyveChainId); + const kyve = new KyveApi( + chainId, + endpoint, + storageUrl, + kyveChainId, + tmpCacheDir, + ); await kyve.setPoolId(); return kyve; @@ -109,20 +118,13 @@ export class KyveApi { private async unzipStorageData( compressionId: string, storageData: Buffer, - ): Promise { + ): Promise { const g = new Gzip(); if (parseDecimal(compressionId) === 0) { return storageData as any; } - const buffer = await g.decompress(storageData); - const parsedString = buffer.toString('utf-8'); - - try { - return JSON.parse(parsedString); - } catch (e) { - throw new Error(`Failed to parse storageData. ${e}`); - } + return g.decompress(storageData); } private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { @@ -197,13 +199,21 @@ export class KyveApi { throw new Error(`No suitable bundle found for height ${height}}`); } - private findBlockByHeight(height: number): UnZippedKyveBlockReponse { - return this.cachedBlocks.find( + private async findBlockByHeight( + height: number, + ): Promise { + const bundleFilePath = path.join( + this.tmpCacheDir, + `bundle_${this.cachedBundleDetails.id}`, + ); + + return (await this.readFromFile(bundleFilePath)).find( (bk: UnZippedKyveBlockReponse) => bk.key === height.toString(), ); } async updateCurrentBundleAndDetails(height: number): Promise { + // this is on init, and then when height is greater than current cache if ( this.currentBundleId === -1 || parseDecimal(this.cachedBundleDetails.to_key) < height @@ -213,30 +223,106 @@ export class KyveApi { ? await this.getBundleId(height) : this.currentBundleId + 1; this.cachedBundleDetails = await this.getBundleById(this.currentBundleId); + + if (parseDecimal(this.cachedBundleDetails.to_key) < height) { + await this.clearFileCache(); + } + + const lockFilePath = path.join( + this.tmpCacheDir, + `bundle_${this.cachedBundleDetails.id}.lock`, + ); + try { + await this.downloadAndWriteToFile(lockFilePath); + } catch (e: any) { + if (e?.code !== 'EACCES') { + throw e; + } + + await this.pollUntilUnlocked(lockFilePath); + } } } - async initializeOrUpdateCachedBundle(): Promise { - if (!this.cachedBundle) { - this.cachedBundle = await this.retrieveBundleData( + async isLocked(lockFilePath: string): Promise { + try { + await fs.promises.access(lockFilePath); + return true; + } catch { + return false; + } + } + + private async lockFile(lockFilePath: string): Promise { + await fs.promises.writeFile(lockFilePath, 'locked'); + } + + private async unlockFile(lockFilePath: string): Promise { + await fs.promises.unlink(lockFilePath); + } + + // Poll until the file is unlocked + async pollUntilUnlocked(lockFilePath: string): Promise { + while (await this.isLocked(lockFilePath)) { + await new Promise((resolve) => setTimeout(resolve, POLL_TIMER)); + } + } + + async downloadAndWriteToFile(lockFilePath: string): Promise { + const bundleFilePath = path.join( + this.tmpCacheDir, + `bundle_${this.cachedBundleDetails.id}`, + ); + + if (await this.isLocked(lockFilePath)) { + // no op for other workers. + await this.pollUntilUnlocked(lockFilePath); + } else { + await this.lockFile(lockFilePath); + + const zippedBundleData = await this.retrieveBundleData( this.cachedBundleDetails.storage_id, BUNDLE_TIMEOUT, ); - - this.cachedBlocks = await this.unzipStorageData( + // TODO: unsure if i need to use the zipper + const unzippedBundleData = await this.unzipStorageData( this.cachedBundleDetails.compression_id, - this.cachedBundle.storageData, + zippedBundleData.storageData, ); + + await this.writeToFile(bundleFilePath, unzippedBundleData); + + await this.unlockFile(lockFilePath); // to lock it so other won't start reading until it is done writing } } + async writeToFile(bundleFilePath: string, data: Buffer): Promise { + await fs.promises.writeFile(bundleFilePath, data, { flag: 'w' }); + await fs.promises.chmod(bundleFilePath, 0o444); + } + + async readFromFile( + bundleFilePath: string, + ): Promise { + try { + return JSON.parse(await fs.promises.readFile(bundleFilePath, 'utf-8')); + } catch (e) { + throw new Error(`Failed to parse storageData. ${e}`); + } + } + + async clearFileCache(): Promise { + await fs.promises.unlink( + path.join(this.tmpCacheDir, `bundle_${this.cachedBundleDetails.id}`), + ); + } + async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { await this.updateCurrentBundleAndDetails(height); - await this.initializeOrUpdateCachedBundle(); - const blockData = this.findBlockByHeight(height); + const blockData = await this.findBlockByHeight(height); return [ this.decodeBlock(blockData.value.block), diff --git a/packages/node/src/utils/kyve/kyveConnection.ts b/packages/node/src/utils/kyve/kyveConnection.ts index 710a663fc..51bee5c78 100644 --- a/packages/node/src/utils/kyve/kyveConnection.ts +++ b/packages/node/src/utils/kyve/kyveConnection.ts @@ -49,12 +49,14 @@ export class KyveConnection storageUrl: string, kyveChainId: SupportedChains, cosmosClient: CosmosClientConnection, + tmpCacheDir: string, ): Promise { const kyveApi = await KyveApi.create( chainId, endpoint, storageUrl, kyveChainId, + tmpCacheDir, ); const connection = new KyveConnection( From 5bf216ceca7d322061fe9ae8d0330b5f03b70a7e Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 9 Apr 2024 19:35:03 +0800 Subject: [PATCH 24/81] added more test, refactored polling logic and added write stream --- packages/node/src/utils/kyve/kyve.spec.ts | 141 +- packages/node/src/utils/kyve/kyve.ts | 184 +- .../node/test/kyve_block/block_3856726.json | 3822 +++++++++++++++++ packages/node/test/kyve_block/bundle.json | 3820 ---------------- 4 files changed, 3980 insertions(+), 3987 deletions(-) create mode 100644 packages/node/test/kyve_block/block_3856726.json delete mode 100644 packages/node/test/kyve_block/bundle.json diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 1c479cd28..c4fc42773 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -1,7 +1,11 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 +import fs from 'fs'; import path from 'path'; +import { Readable } from 'stream'; +import { promisify } from 'util'; +import { gunzipSync, gzipSync } from 'zlib'; import { GeneratedType, Registry } from '@cosmjs/proto-signing'; import { defaultRegistryTypes } from '@cosmjs/stargate'; import { Tendermint37Client } from '@cosmjs/tendermint-rpc'; @@ -19,6 +23,7 @@ import { MsgUpdateAdmin, } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; import { isEqual } from 'lodash'; +import rimraf from 'rimraf'; import { HttpClient } from '../../indexer/rpc-clients'; import { LazyBlockContent } from '../cosmos'; import { KyveApi } from './kyve'; @@ -34,9 +39,9 @@ const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ const kyveBundlePath = path.join( __dirname, - '../../../test/kyve_block/bundle.json', + '../../../test/kyve_block/block_3856726.json', ); -const bundle_3856726 = require(kyveBundlePath); +const block_3856726 = require(kyveBundlePath); jest.setTimeout(100000); describe('KyveApi', () => { @@ -46,7 +51,14 @@ describe('KyveApi', () => { let tmpPath: string; let retrieveBundleDataSpy: jest.SpyInstance; - let unzipStorageDataSpy: jest.SpyInstance; + + const zipped = gzipSync(Buffer.from(JSON.stringify(block_3856726))); + const mockStream = new Readable({ + read() { + this.push(zipped); + this.push(null); + }, + }); beforeAll(async () => { tmpPath = await makeTempDir(); @@ -71,7 +83,9 @@ describe('KyveApi', () => { (kyveApi as any).cachedBlocks = undefined; retrieveBundleDataSpy.mockRestore(); - unzipStorageDataSpy.mockRestore(); + }); + afterAll(async () => { + await promisify(rimraf)(tmpPath); }); it('ensure bundleDetails', async () => { @@ -141,80 +155,75 @@ describe('KyveApi', () => { expect((kyveApi as any).poolId).toBe('2'); expect((kyveApi as any).chainId).toBe('archway-1'); }); - it('able to download and write to file', async () => { - (kyveApi as any).cachedBundleDetails = { - id: '1', - to_key: '150', - storage_id: 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', - compression_id: '1', - } as any; + it('able to update and clear file cache', async () => { + const checkFileExist = async (filePath: string) => { + try { + await fs.promises.access(filePath); + return true; + } catch (e) { + return false; + } + }; + + // create two mock bundles + await fs.promises.writeFile(path.join(tmpPath, 'bundle_130263'), 'mock'); // should be removed + await fs.promises.writeFile(path.join(tmpPath, 'bundle_130264'), 'mock'); retrieveBundleDataSpy = jest .spyOn(kyveApi as any, 'retrieveBundleData') - .mockImplementation(() => - Promise.resolve({ - storageData: Buffer.from(JSON.stringify(bundle_3856726)), - }), - ); - - unzipStorageDataSpy = jest - .spyOn(kyveApi as any, 'unzipStorageData') - .mockImplementation(() => - Promise.resolve(Buffer.from(JSON.stringify(bundle_3856726))), - ); + .mockImplementation(() => { + return { data: mockStream }; + }); - const writerSpy = jest.spyOn(kyveApi as any, 'writeToFile'); - const height = 160; + const clearFileSpy = jest.spyOn(kyveApi as any, 'clearFileCache'); - await kyveApi.updateCurrentBundleAndDetails(height); + jest.spyOn(kyveApi as any, 'readFromFile').mockImplementation(() => { + return Promise.resolve(JSON.stringify(block_3856726)); + }); - await expect( - Promise.all([ - kyveApi.updateCurrentBundleAndDetails(height), - kyveApi.updateCurrentBundleAndDetails(height), - ]), - ).resolves.not.toThrow(); + await kyveApi.getBlockByHeight(3856726); + expect((kyveApi as any).cachedBundleDetails).not.toBe('0'); await expect( - (kyveApi as any).readFromFile( - path.join(tmpPath, `bundle_${(kyveApi as any).cachedBundleDetails.id}`), - ), - ).resolves.toEqual(bundle_3856726); - - expect(writerSpy).toHaveBeenCalledTimes(1); - expect((kyveApi as any).cachedBundleDetails.to_index).toBe('300'); + checkFileExist(path.join(tmpPath, 'bundle_130263')), + ).resolves.toBe(false); + expect(clearFileSpy).toHaveBeenCalledTimes(1); }); - it('race condition on file cache', async () => { - (kyveApi as any).cachedBundleDetails = { - id: '1', - to_key: '150', - storage_id: 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', - compression_id: '1', - } as any; - const height = 160; + it('able to download and write to file', async () => { + (kyveApi as any).cachedBundleDetails = await (kyveApi as any).getBundleById( + 1, + ); retrieveBundleDataSpy = jest .spyOn(kyveApi as any, 'retrieveBundleData') - .mockImplementation(() => - Promise.resolve({ - storageData: Buffer.from(JSON.stringify(bundle_3856726)), - }), - ); + .mockImplementation(() => { + return { data: mockStream }; + }); - unzipStorageDataSpy = jest - .spyOn(kyveApi as any, 'unzipStorageData') - .mockImplementation(() => - Promise.resolve(Buffer.from(JSON.stringify(bundle_3856726))), - ); + const pollSpy = jest.spyOn(kyveApi, 'pollUntilReadable'); - await Promise.all([ - kyveApi.updateCurrentBundleAndDetails(height), - kyveApi.updateCurrentBundleAndDetails(height), - kyveApi.updateCurrentBundleAndDetails(height), - kyveApi.updateCurrentBundleAndDetails(height), - ]); + await expect( + Promise.all([ + kyveApi.getFileCacheData(), + kyveApi.getFileCacheData(), + kyveApi.getFileCacheData(), + kyveApi.getFileCacheData(), + ]), + ).resolves.not.toThrow(); + + expect(pollSpy).toHaveBeenCalled(); + + const MAX_COMPRESSION_BYTE_SIZE = 2 * 10 ** 9; + + const r = await kyveApi.readFromFile( + path.join(tmpPath, `bundle_${(kyveApi as any).cachedBundleDetails.id}`), + ); + const unzipped = gunzipSync(zipped, { + maxOutputLength: MAX_COMPRESSION_BYTE_SIZE, + }); - // read from folder and ensure that there is content + // TODO for some reason it does not equal + expect(r).toEqual(JSON.stringify(block_3856726)); }); describe('able to wrap kyveBlock', () => { let rpcLazyBlockContent: LazyBlockContent; @@ -229,8 +238,8 @@ describe('KyveApi', () => { tendermint.blockResults(height), ]); - const blockInfo = bundle_3856726.value.block; - const blockResults = bundle_3856726.value.block_results; + const blockInfo = block_3856726[0].value.block; + const blockResults = block_3856726[0].value.block_results; const bi = (kyveApi as any).decodeBlock(blockInfo); const br = (kyveApi as any).decodeBlockResult(blockResults); @@ -243,7 +252,7 @@ describe('KyveApi', () => { kyveLazyBlockContent = new LazyBlockContent(bi, br, registry); }); it('compare kyve wrapped results with rpc results', () => { - const blockResults = bundle_3856726.value.block_results; + const blockResults = block_3856726[0].value.block_results; const br = (kyveApi as any).decodeBlockResult(blockResults); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 20742924b..6ef70e072 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -4,6 +4,7 @@ import assert from 'assert'; import fs from 'fs'; import path from 'path'; +import * as zlib from 'zlib'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; import { Registry } from '@cosmjs/proto-signing'; import { Log } from '@cosmjs/stargate/build/logs'; @@ -12,23 +13,21 @@ import { BlockResponse, BlockResultsResponse, } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; -// Currently these types are not exported -import { StorageReceipt } from '@kyvejs/protocol'; -import { Gzip } from '@kyvejs/protocol/dist/src/reactors/compression/Gzip'; import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; -import { SupportedChains } from '@kyvejs/sdk/src/constants'; +import { SupportedChains } from '@kyvejs/sdk/src/constants'; // Currently these types are not exported import { PoolResponse, QueryPoolsResponse, } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; -import { getLogger } from '@subql/node-core'; -import axios, { AxiosRequestConfig } from 'axios'; +import { delay, getLogger } from '@subql/node-core'; +import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; import { BlockContent } from '../../indexer/types'; import { LazyBlockContent } from '../cosmos'; import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms -const POLL_TIMER = 1000; // ms +const POLL_TIMER = 3; // sec +const MAX_COMPRESSION_BYTE_SIZE = 2 * 10 ** 9; const parseDecimal = (value: string) => parseInt(value, 10); @@ -115,18 +114,6 @@ export class KyveApi { this.poolId = pool.id; } - private async unzipStorageData( - compressionId: string, - storageData: Buffer, - ): Promise { - const g = new Gzip(); - if (parseDecimal(compressionId) === 0) { - return storageData as any; - } - - return g.decompress(storageData); - } - private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { return this.respAdaptor.decodeBlock({ id: 1, @@ -199,20 +186,18 @@ export class KyveApi { throw new Error(`No suitable bundle found for height ${height}}`); } - private async findBlockByHeight( + private findBlockByHeight( height: number, - ): Promise { - const bundleFilePath = path.join( - this.tmpCacheDir, - `bundle_${this.cachedBundleDetails.id}`, - ); - - return (await this.readFromFile(bundleFilePath)).find( + fileCacheData: UnZippedKyveBlockReponse[], + ): UnZippedKyveBlockReponse { + return fileCacheData.find( (bk: UnZippedKyveBlockReponse) => bk.key === height.toString(), ); } - async updateCurrentBundleAndDetails(height: number): Promise { + async updateCurrentBundleAndDetails( + height: number, + ): Promise { // this is on init, and then when height is greater than current cache if ( this.currentBundleId === -1 || @@ -223,106 +208,108 @@ export class KyveApi { ? await this.getBundleId(height) : this.currentBundleId + 1; this.cachedBundleDetails = await this.getBundleById(this.currentBundleId); - - if (parseDecimal(this.cachedBundleDetails.to_key) < height) { + try { + await fs.promises.access( + path.join( + this.tmpCacheDir, + `bundle_${parseDecimal(this.cachedBundleDetails.id) - 2}`, + ), + ); await this.clearFileCache(); + } catch (e) { + /* empty */ } - const lockFilePath = path.join( - this.tmpCacheDir, - `bundle_${this.cachedBundleDetails.id}.lock`, - ); + return this.jsonParseWrapper(await this.getFileCacheData()); + } + } + + async pollUntilReadable(bundleFilePath: string): Promise { + // eslint-disable-next-line no-constant-condition + while (true) { try { - await this.downloadAndWriteToFile(lockFilePath); - } catch (e: any) { - if (e?.code !== 'EACCES') { + return await this.readFromFile(bundleFilePath); + } catch (e) { + if (e.code === 'EACCES') { + await delay(POLL_TIMER); + } else { throw e; } - - await this.pollUntilUnlocked(lockFilePath); } } } - async isLocked(lockFilePath: string): Promise { - try { - await fs.promises.access(lockFilePath); - return true; - } catch { - return false; - } - } - - private async lockFile(lockFilePath: string): Promise { - await fs.promises.writeFile(lockFilePath, 'locked'); - } + async downloadAndProcessBundle(bundleFilePath: string): Promise { + const writeStream = fs.createWriteStream(bundleFilePath, { + flags: 'wx+', + }); - private async unlockFile(lockFilePath: string): Promise { - await fs.promises.unlink(lockFilePath); - } + const zippedBundleData = await this.retrieveBundleData(); - // Poll until the file is unlocked - async pollUntilUnlocked(lockFilePath: string): Promise { - while (await this.isLocked(lockFilePath)) { - await new Promise((resolve) => setTimeout(resolve, POLL_TIMER)); - } + const gunzip = zlib.createUnzip({ + maxOutputLength: MAX_COMPRESSION_BYTE_SIZE /* avoid zip bombs */, + }); + zippedBundleData.data + .pipe(gunzip) + .pipe(writeStream) + .on('error', (err) => { + // TODO i am unsure if this is working with async + if (err.code === 'EEXIST') { + return this.pollUntilReadable(bundleFilePath); + } else { + throw err; + } + }) + .on('finish', () => { + return fs.promises.chmod(bundleFilePath, 0o444); + }); } - async downloadAndWriteToFile(lockFilePath: string): Promise { + async getFileCacheData(): Promise { const bundleFilePath = path.join( this.tmpCacheDir, `bundle_${this.cachedBundleDetails.id}`, ); - if (await this.isLocked(lockFilePath)) { - // no op for other workers. - await this.pollUntilUnlocked(lockFilePath); - } else { - await this.lockFile(lockFilePath); - - const zippedBundleData = await this.retrieveBundleData( - this.cachedBundleDetails.storage_id, - BUNDLE_TIMEOUT, - ); - // TODO: unsure if i need to use the zipper - const unzippedBundleData = await this.unzipStorageData( - this.cachedBundleDetails.compression_id, - zippedBundleData.storageData, - ); - - await this.writeToFile(bundleFilePath, unzippedBundleData); - - await this.unlockFile(lockFilePath); // to lock it so other won't start reading until it is done writing + try { + await this.downloadAndProcessBundle(bundleFilePath); + return await this.readFromFile(bundleFilePath); + } catch (e: any) { + if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { + return this.pollUntilReadable(bundleFilePath); + } else { + throw e; + } } } - async writeToFile(bundleFilePath: string, data: Buffer): Promise { - await fs.promises.writeFile(bundleFilePath, data, { flag: 'w' }); - await fs.promises.chmod(bundleFilePath, 0o444); - } - - async readFromFile( - bundleFilePath: string, - ): Promise { + private jsonParseWrapper(data: string) { try { - return JSON.parse(await fs.promises.readFile(bundleFilePath, 'utf-8')); + return JSON.parse(data); } catch (e) { throw new Error(`Failed to parse storageData. ${e}`); } } + async readFromFile(bundleFilePath: string): Promise { + return fs.promises.readFile(bundleFilePath, 'utf-8'); + } + async clearFileCache(): Promise { await fs.promises.unlink( - path.join(this.tmpCacheDir, `bundle_${this.cachedBundleDetails.id}`), + path.join( + this.tmpCacheDir, + `bundle_${parseDecimal(this.cachedBundleDetails.id) - 2}`, + ), ); } async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { - await this.updateCurrentBundleAndDetails(height); + const blocks = await this.updateCurrentBundleAndDetails(height); - const blockData = await this.findBlockByHeight(height); + const blockData = this.findBlockByHeight(height, blocks); return [ this.decodeBlock(blockData.value.block), @@ -385,25 +372,20 @@ export class KyveApi { ); } - private async retrieveBundleData( - storageId: string, - timeout: number, - ): Promise { + private async retrieveBundleData(): Promise { const axiosConfig: AxiosRequestConfig = { method: 'get', - url: `${storageId}`, + url: this.cachedBundleDetails.storage_id, baseURL: this.storageUrl, - responseType: 'arraybuffer', - timeout, + responseType: 'stream', + timeout: BUNDLE_TIMEOUT, headers: { 'User-Agent': `SubQuery-Node ${packageVersion}`, Connection: 'keep-alive', 'Content-Encoding': 'gzip', }, }; - const { data: storageData } = await axios(axiosConfig); - - return { storageId, storageData }; + return axios(axiosConfig); } async fetchBlocksBatches( diff --git a/packages/node/test/kyve_block/block_3856726.json b/packages/node/test/kyve_block/block_3856726.json new file mode 100644 index 000000000..9ca2441b5 --- /dev/null +++ b/packages/node/test/kyve_block/block_3856726.json @@ -0,0 +1,3822 @@ +[ + { + "key": "3856726", + "value": { + "block": { + "block_id": { + "hash": "51223D03D35E04476553C309FA4094E8EE09570178B4B77EB5D663F2BF72AB9E", + "parts": { + "total": 1, + "hash": "2D95CC59E4000651933F9E1D3C63BBC06480C9B6BDD201CB8B1FB08E5354AE7D" + } + }, + "block": { + "header": { + "version": { + "block": "11" + }, + "chain_id": "archway-1", + "height": "3856726", + "time": "2024-03-25T06:14:27.24295008Z", + "last_block_id": { + "hash": "C9C081761B20353325F5C2D8A53068F0DD59BD739D562F1017D047825928DF0D", + "parts": { + "total": 1, + "hash": "B645EAA4F54247468C1BA020A71AFCEFB72EAF900E1F3D219EB3FBA5756E4F16" + } + }, + "last_commit_hash": "935D03A37FF6C9C7BF1C89F6DB1A65AC70FA4A0F7CCFC248ED25251E4151423A", + "data_hash": "CE02B6109F04A6C01EB71819F9D8EF1CE28C3D8B1E37B8EFBFF2A1134BF409C0", + "validators_hash": "BE08D7C9A03E52687DB305B8CEF14F96D353FD6DC66F694C0D21FB2BF4C9C4DB", + "next_validators_hash": "BE08D7C9A03E52687DB305B8CEF14F96D353FD6DC66F694C0D21FB2BF4C9C4DB", + "consensus_hash": "22E3FA2D1695AE7DB62E55677BF0C914B1EC88D64CD8D280CF2E29B2E06D0965", + "app_hash": "4F36440223B8AA53C357A9203054C4CC54F669E59714A5F587AD308C5BD4141C", + "last_results_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "evidence_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "proposer_address": "F183805F63AD6C429B7157D90D7199F2075280AA" + }, + "data": { + "txs": [ + "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" + ] + }, + "evidence": { + "evidence": [] + }, + "last_commit": { + "height": "3856725", + "round": 0, + "block_id": { + "hash": "C9C081761B20353325F5C2D8A53068F0DD59BD739D562F1017D047825928DF0D", + "parts": { + "total": 1, + "hash": "B645EAA4F54247468C1BA020A71AFCEFB72EAF900E1F3D219EB3FBA5756E4F16" + } + }, + "signatures": [ + { + "block_id_flag": 2, + "validator_address": "454BA446172211B1CB7A08E14161FB3BA1493F73", + "timestamp": "2024-03-25T06:14:27.198711863Z", + "signature": "2e8XvUA4Tbn1wEbARGH8NB1UmMK6MS5vMlZjNBV1x4K1+SOGkqSfMdm/ulWngwiOygqBwLgsvmq/rhikwa2rDw==" + }, + { + "block_id_flag": 2, + "validator_address": "5E026F83F8DDC51308008A80518530E9C03C7771", + "timestamp": "2024-03-25T06:14:27.302921022Z", + "signature": "lq2SyHxljxPnLImJIS2/fPAKqyyP4pmhdx3Zs3mAt6gjK6mZUCkTQ1GVF3GAAzDmQplkbnIT5/Vehi31pja5Ag==" + }, + { + "block_id_flag": 2, + "validator_address": "C64F7CF03BBB07B80E1B557A185032114C1F0201", + "timestamp": "2024-03-25T06:14:27.268900037Z", + "signature": "lY9GJMAD7/zGk0S3Kc7VhE80xggXs68AXiYhiJnG5aB+IhpdEorKdGxXWrw/Tl7V/NNGwfM1DM+naq6e3rBeBg==" + }, + { + "block_id_flag": 2, + "validator_address": "9396A4ECDC186B5F92600579AEC5E04D1059642D", + "timestamp": "2024-03-25T06:14:27.292183475Z", + "signature": "ndgHemJ5qlwxgpfQ/6Y2PqFRNfOkS58jJC1up4gQ5ZYUggDBIVxYdNSqWscmvgpBZkz6IrIfUukO/JnZqcpJDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "192D17EFD1F6012E52A8833717D8621178168264", + "timestamp": "2024-03-25T06:14:27.21504644Z", + "signature": "n2jli5HiR7rDMEI36JqQvUem3RNarjPr1N0tqTQReYslCn8m9r2KRvj13WpaWx1nyc9bjF4/tEBhTmn3DUuRAg==" + }, + { + "block_id_flag": 2, + "validator_address": "56AE16561016ECD1B64540DCE711C588F06E2DBA", + "timestamp": "2024-03-25T06:14:27.204804746Z", + "signature": "SgF01ZGHIwwNjmyGYhSnzf6+xgTJRAozD2c0C76zCHnU7b3lo/7Xg29fJh4AZZw4c4ol8CstNBDh2CCcMSWwAg==" + }, + { + "block_id_flag": 2, + "validator_address": "3ABC887FAAB038EBB82506305FD928270AD2867C", + "timestamp": "2024-03-25T06:14:27.359862997Z", + "signature": "60Jc13MrHdG1zk2OFXEx39n0VfXvRD4rSvsu6gqNJ9FqNM+TcnZGN6nhLQFJ9ijFhqZhJwODI31B+zWJzv+yAg==" + }, + { + "block_id_flag": 2, + "validator_address": "7CF3A6E06DA02BF700E33372951EA2E95AF6A7C6", + "timestamp": "2024-03-25T06:14:27.243732794Z", + "signature": "uYOWyHr8KmR7rsrvgzKo7LJOvP0bPnzA0s3yVePxt6JlzAK+bvOuV1HJ6GBm7cg7BBhJQUzB5YUZbUdGbqwGCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "E89799B6440988A1AAEE14ADA7050FCFBCBE31B5", + "timestamp": "2024-03-25T06:14:27.28412331Z", + "signature": "oz0OU8f0jpbkMPye9psiy+qnE+Hpa9fkh+IlFN8u80Mgi3pB1ABAn4SAt08qGQu3eu/Gnuv21tWnDnmUpGo+AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "E840B5676A5DA43F7ECA8385B461FA6BF0BE2CCB", + "timestamp": "2024-03-25T06:14:27.229527079Z", + "signature": "OY/V9y9gwWgKLgWPW6P4W73BPNAdcGR8KB+XnkM72My81/8NmzCh0F2OBysNRxYZ5qoV0TheXqc2WdVp2/SiDw==" + }, + { + "block_id_flag": 2, + "validator_address": "90FAA31CA9BE4E4BB8E4C9732EB69575F4C5B626", + "timestamp": "2024-03-25T06:14:27.251424274Z", + "signature": "25v4oL8wp+MbgxYl7V9LsCOvoohPeMejbim173bPKvmz9M8pKieyb5LoBO/9I0nHYvmLXuwLYTjj+iksIRy9Bw==" + }, + { + "block_id_flag": 2, + "validator_address": "CB8D061C7D78BAE099C50D6857B97AD4A9218776", + "timestamp": "2024-03-25T06:14:27.24295008Z", + "signature": "vUBPYARoWvUjAEqgp+UwXQSSmIGaW5Gajhi/E7PMOivzpY3trjjknomq3hzR9Jw4B0OQplviiJnRCn9voF/yAA==" + }, + { + "block_id_flag": 2, + "validator_address": "4630574528AEF5F2CE3BEA1BE9E092927E311F0E", + "timestamp": "2024-03-25T06:14:27.18719406Z", + "signature": "HwRudquc1x2MWz8e8a1B8EBhGYQIBMAFM24svk+SfjL/DMESJ2bEQwZvylYdNtRcuHsw6x17EfIHNuVNOAI3DA==" + }, + { + "block_id_flag": 2, + "validator_address": "B2FF86CCBBA2DB501E828E0E9D15EC14D50E0214", + "timestamp": "2024-03-25T06:14:27.191671125Z", + "signature": "y1shsVEvnmu7wPAcycLcpyqwsm2ZWyhpw/biuxFycx0/fhh+BlEX9QUIsJz1LDo52tPRIrbVNpmmTQ+9t4mBBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "CFBD265B3AB49045D2AEE7D001199ABD30BD1E5C", + "timestamp": "2024-03-25T06:14:27.209181671Z", + "signature": "IGfa6KghvryZkbonMVj/pXMQ6A+tsBDVN9OC1+KNBRl35eDe552hRjK07r1To4tMHM5+Fnz59a85ft7hconBCA==" + }, + { + "block_id_flag": 2, + "validator_address": "2348415EAAEAE89FE5A9412F2F45CA9AA5E73BBA", + "timestamp": "2024-03-25T06:14:27.348597083Z", + "signature": "MDv8yml9BxpRdKo/lTnhHfz/mCo9yeIEBbt5KjARvvTXlka5cwGwMW/hdCpNXMPqHqEv/I72mVQo/84tqyROCw==" + }, + { + "block_id_flag": 2, + "validator_address": "E4983569DBE9E32DC1C9C69CBE4DCF1CB82899AA", + "timestamp": "2024-03-25T06:14:27.242449608Z", + "signature": "43gXDvJMGoNR39pQdtx/w1moo3iGxEJM6CLxobXOx76WmtV0lT8izEqHXYOpPJFzd1alGpvmDWzFp7YAk5EuCw==" + }, + { + "block_id_flag": 2, + "validator_address": "F183805F63AD6C429B7157D90D7199F2075280AA", + "timestamp": "2024-03-25T06:14:27.205952311Z", + "signature": "ZotOXk+V0oh5eJFv0E/9l3oMnmLfdsrIu7+C1/Ufhl6W06g+Qx+FlGG6OcoJA4KKym/E7gLmkegZUKCz2B+DCA==" + }, + { + "block_id_flag": 2, + "validator_address": "5F647EE2AA22982E897765117160DA27BD8DD1AE", + "timestamp": "2024-03-25T06:14:27.21051342Z", + "signature": "SQuChlSd/54IYo9N4KAsUeoaXX21lD9Gvbq4tbSqa0QP8awWaav6S8pd0d5UN3Q5DaoJdgmP8JPNOWAowkNZDA==" + }, + { + "block_id_flag": 2, + "validator_address": "C6216B74B71AD3DD522E00D28BF1E7D7B9145869", + "timestamp": "2024-03-25T06:14:27.260030577Z", + "signature": "2ZBx8rLaNazZ93iQhmpAkYABtx424OfrXrDssBhZO3Cs+bO9StVeQOU06WXI0AQqtHD24Aw+Q5EqVAOBAWPNAg==" + }, + { + "block_id_flag": 2, + "validator_address": "31323915F9B0CBC60B4F371E454B5FB19B0AD26D", + "timestamp": "2024-03-25T06:14:27.296428597Z", + "signature": "gR96bGxmM/Xu5MBNPftimPjjgQDGagvG9tK4PA0UKARwf0wb3t4WspRcdv7sf8x05LWbx7CBb3DFoY5jcYA9AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "90F0753D72B15384CD536B1FAE023BD7FF7D250E", + "timestamp": "2024-03-25T06:14:27.294846688Z", + "signature": "urgxmnMfREsnkRtkhs6JaLTnY35UlkabmVDFnmB3qGfOfDeVurLUcBWIe2pAdJAsu5NGqYiKhWwRjPlNxbSHCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "9417D3AA3F23E9D96CDCBA2045A07B401C1E11DC", + "timestamp": "2024-03-25T06:14:27.21561313Z", + "signature": "DQWOigfi6ey6I1U9VGIb5gjEDY/QKXtRqGdxxUVnAPlI0Az+QpHXQ3FzhMj6ChteqVWg/OzIpU8YencUPT0/AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "38303246077ABA69E2782CB2C71C89DE9E2B7BCC", + "timestamp": "2024-03-25T06:14:27.273058159Z", + "signature": "ETdEehLafzgsITa1hBtEjKUcIg5SVPcrGUAmpW64Dju2AcfFoX7u0Hh8M3YW1JHb0ad0cZNC93q2Wm6NWtStBw==" + }, + { + "block_id_flag": 2, + "validator_address": "1D143C66358013DFA42A05A3BD9D00397AFDD6D4", + "timestamp": "2024-03-25T06:14:27.26998412Z", + "signature": "Xbhtj+DbTXVOLXc/eCszWFHCun34INCAn1OC9IxSM+pj261HVnUauh001rnFxzBjD52mxl7Wi2i4KoFd+TXxCA==" + }, + { + "block_id_flag": 2, + "validator_address": "8F41A1631BC7D5ED4915B673297D2F60A22C6E34", + "timestamp": "2024-03-25T06:14:27.208788012Z", + "signature": "vJts89t3tXLBb6LB/CF5UO1/l+gQP4teCQIOVj9Q3trUHB3SE4u1T9IPeQL5gblXTiwARrwkbccCuI0NUztlCw==" + }, + { + "block_id_flag": 2, + "validator_address": "8B714B0E76353D945D98D4974C8BD0B0748EC196", + "timestamp": "2024-03-25T06:14:27.233740258Z", + "signature": "hkqqwoCiTCNDURwo/9Pj4KqQ4cWKSnFnlqktW9wsohfmNdEZWjBCuFPfO7Etr2pfh0Cv5DVe7yTc5Sm4Nok8DQ==" + }, + { + "block_id_flag": 2, + "validator_address": "94B06CE54895A6138DB5D3E406E5914ED41445D9", + "timestamp": "2024-03-25T06:14:27.249889348Z", + "signature": "Fn/3ESz0Z8c79L37hKlyeSI3RR8ztarlrCmK8HLnU9CD7jaO1O9MJziqE56vATpHGAkDZEKPOSCbwJGu+cdgCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "ADADEE9B97C69600FEA8911323F3F5CB28906EE5", + "timestamp": "2024-03-25T06:14:27.399513013Z", + "signature": "Xb+eLvN/0KMqjCcYlq20t/gdR2tRf4f6p9w3IlcCseoR6F4p3RyHAV2RZ2TszcjUP8VYIAdCgukukIxofZhFCg==" + }, + { + "block_id_flag": 2, + "validator_address": "FD1E562DD7FA1296ACA834EF29AA0685A8AD8F33", + "timestamp": "2024-03-25T06:14:27.201830902Z", + "signature": "OMhImUqKrB6sbsBfDRcr5+F/+L4oNH8KuP+nBLmwp8RSXvW65oxMEyR/O9KqMtUl5Ib12TwI0BIHxNUWHDwaBA==" + }, + { + "block_id_flag": 2, + "validator_address": "A0212325DA0D8E777AA60AC5DA61DE409072726A", + "timestamp": "2024-03-25T06:14:27.208975888Z", + "signature": "nFEzQvXWCQzfQO1g7CAp5Qr8dgy2eOfF3WeWgcolIxq/2HSbLDO3uB+iIWMEkSTSkh9Zk/H1yCkeNfzMaFIuAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "CF65D933DAAD0646727C76795AAB0DE423B8C0E5", + "timestamp": "2024-03-25T06:14:27.216374782Z", + "signature": "GQZAf4We2Q3mKY1F8AVEirKOU/VXo/Ia1JJfkx0VreBDXqhAeJ0h/q64G7oXdw02Ed11Kc3CoqK7CtXuVAJBBg==" + }, + { + "block_id_flag": 2, + "validator_address": "80FF2FDD961F707F3C005A7FD41D55A74F076AA0", + "timestamp": "2024-03-25T06:14:27.224969374Z", + "signature": "tXcyjOQTYwoyhvsDhfAamhPjpLDytPKFsUIbVYeZO/hwmgnrZS8G6IH50gSS4BfhcMPQ6Bp0oRF0R8bBwldyAg==" + }, + { + "block_id_flag": 2, + "validator_address": "FF592BF088B8ADABFA6080AA820F7903F0F02046", + "timestamp": "2024-03-25T06:14:27.306082208Z", + "signature": "mqIIRczB6lyk6j5CqUK+VIun34fVFA/50fV6qcHZkJcCaYxZC+CKu88/KVPXfsCOHEEBxnvCC0d/AGpTPVbWAg==" + }, + { + "block_id_flag": 2, + "validator_address": "C5047A5B0C008A531993140151F3E54C1308A86F", + "timestamp": "2024-03-25T06:14:27.211417554Z", + "signature": "0qJEczrpIYdF8sdNT3p0gYivAFT/NeUvbml7mOkyDA/bsHGeXVDX+n5aLrkx/fYyqhs+rCB7bv23j7mI+Mn1Dw==" + }, + { + "block_id_flag": 2, + "validator_address": "43EAC69067530360F849375487ADA1F26FC026FE", + "timestamp": "2024-03-25T06:14:27.221068884Z", + "signature": "doK0ZlUgFFtnPJLgEXTp8W10EGXBBZC+u3YNYe1SD33W9LG4uTXfj0t0db4XsD7KIaZ7QWmdBP33ew0mStwKBg==" + }, + { + "block_id_flag": 2, + "validator_address": "5894E2D8B68C01CBC835985BADBF0AE378A5A6B6", + "timestamp": "2024-03-25T06:14:27.262841804Z", + "signature": "aQDifQtR7PY8mmujd353OZGJRJozbbPg9BpZP/WmjXQDLI/vuDDTMUJUfw0/JE9cDra42hnPQ5pf/8aarGWCCw==" + }, + { + "block_id_flag": 2, + "validator_address": "94A81ED9CF1EFE9672501231F0255F0C54A4F411", + "timestamp": "2024-03-25T06:14:27.213546159Z", + "signature": "SUpF6JTYtVLUX3QDVS5qNlSiJg8Nco3+3tO+XZ9ehfUFHqQ7hqchj4OFBHNbtF6KOZbolGz04ZSZrEaV6PTyDw==" + }, + { + "block_id_flag": 2, + "validator_address": "D78997B5A01D2D4E80C5189D930A14055002B478", + "timestamp": "2024-03-25T06:14:27.209686721Z", + "signature": "AiEAtstORITGefKUuruXaVLMV2PddgE+MvNgoefPNnaeTVRPRsgcMYCfk6TsLGDCkih4uTpGJIKyly/h1NIGCg==" + }, + { + "block_id_flag": 2, + "validator_address": "69C38FB90624F19356482DAA89E64D9957A37C00", + "timestamp": "2024-03-25T06:14:27.197381186Z", + "signature": "0zJHwlFfrnEX88Yhjwr7Mp/2UCaL66KY9K1H5DXwGjgBb6O7ozW5Ku36+RmT8/QFM+pQmQHUHf32De5nrpzIBw==" + }, + { + "block_id_flag": 2, + "validator_address": "2D63B9079FCAF8CEE74B072665A04599064BCB09", + "timestamp": "2024-03-25T06:14:27.187860932Z", + "signature": "FTIy7zamXLA6S/NzmMDHv7sy5/FGcIpChtLmNgzFhUz59P7uV2OT1RRVD56nWabrqCMOV6Qio1DEIdiptFoBDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "1AF66CF8C90E5D334FB095B4983210FDC2E2815F", + "timestamp": "2024-03-25T06:14:27.2934702Z", + "signature": "BmKsz5Lt6sxLRyv8UQDsYKuyTRJeuyG9NjAMzXgw5T1Da3Vx6EpRqhm5lY4ZpBzVLagXGD072Ix4q8Z56wV/DA==" + }, + { + "block_id_flag": 2, + "validator_address": "159424CD4756CBEF88083C1A11B6033423537A3A", + "timestamp": "2024-03-25T06:14:27.395386931Z", + "signature": "LP+S1UnorS51jwWhLUbepP/sgezYL1CJInFhR2c4oTc+k5iabeFofw04ZW/zQMNebDHXNF6oyWubaD2KnGc4CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "C406A6BFB29F36979ADA959B917DD4A2A780E519", + "timestamp": "2024-03-25T06:14:27.299496138Z", + "signature": "7HTkVqMSkgQc3PqfW7twXSI9sIrkgwfyn16KML7y6gB677rk2Wn3YvVL2rn7JfC2Cnbj5PS17o53y7+76wY6CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "92C0FD982DEC037B295494DC7ACF25FBB8E3EE5C", + "timestamp": "2024-03-25T06:14:21.339631074Z", + "signature": "9vtjqiTYXLoP6728kPDuJnt5Dq5cwauRcXs942pBJFw3go0TP2hWojpO5ljf9XqaUDdffIHqSsyclALtIqi5Bg==" + }, + { + "block_id_flag": 2, + "validator_address": "5883CB9214B4FE1A0CE68774D714425DC6024D52", + "timestamp": "2024-03-25T06:14:27.241979083Z", + "signature": "ILVsPy44TCgUW+VCQLazvEma7Knr/G9TgZF5UBHqRCkMu1loWS4WhfaLUeXYxWJ/oTzSt0B0eD1hoSYtJP3xAw==" + }, + { + "block_id_flag": 2, + "validator_address": "6C6412282FB32525FD92617157F154579434F9FC", + "timestamp": "2024-03-25T06:14:27.204271239Z", + "signature": "snrhUC6Qa3dhiQeIaI41CYAS41k91X544LpEnk24LHzEwSR0u9Qbrfum3ocvxfldTuC6N4S2URuGGIUfjU+0Cw==" + }, + { + "block_id_flag": 2, + "validator_address": "EEB553125D331715F799680FE763B33D4D8EC063", + "timestamp": "2024-03-25T06:14:27.233977273Z", + "signature": "gctjdRc+zF9OEV3xa6X/cjIaOoOVyOwWwumCbbomNmlv4VRyi6ctBJHVHtbrnampkDdT4EF1jwRriAznffzfDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "DB2D66F06C70A06818910685E8A51C73E6EF3324", + "timestamp": "2024-03-25T06:14:27.226749145Z", + "signature": "BIOK4yc3z8qjpeFyCAQ9deVWFd+N/JWBtyJCM3WoP6oeaCdImZlz1GMZpFdu/q910OlJ5ovLeVEPgKm2ygYeCA==" + }, + { + "block_id_flag": 2, + "validator_address": "07F4F6BEAC490B1508E93E38D9E5B3DC50716200", + "timestamp": "2024-03-25T06:14:27.325335199Z", + "signature": "PngsVhXlpeFwn/0SxHolgxNkKH5lXWkJKskaYJ6XlexUPImbJNT0dbHoWGqeMmaaHONyhvTL6rJZgZ+/SJtvAA==" + }, + { + "block_id_flag": 2, + "validator_address": "32F529A962B3F9D7896BD858D9970E3C1392570E", + "timestamp": "2024-03-25T06:14:27.435809271Z", + "signature": "P3b/VPqrxBgxf1uBMd+3oNssgAWvzJTYzSHTL+msiTEGNvXWJWO/iuzds59daZO5ZktKHLeebX/8hSO0LHPUCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "223BD658ADC0BE9E1A318EAEE26A927E9B782DFB", + "timestamp": "2024-03-25T06:14:27.298543778Z", + "signature": "22Ci/5gtqsUekp6U1XIPDU/6a4f9XJNuwPu5lNuU2GLcAeW5ztZqMHphb4kT0AHGdn04g41UFlKGaRMUmybbAA==" + }, + { + "block_id_flag": 2, + "validator_address": "B155936FBF30A4A21C2FD9B2A3CC1C2CACA9DDE7", + "timestamp": "2024-03-25T06:14:27.314051454Z", + "signature": "6DoBNRasJfqp5eTsWkX99hSTtq8aFYg7h1jydaYpB5DQAL/J5Tie0w1jd8gq981rZBOVUgfNuPkpl7OonwgsBw==" + }, + { + "block_id_flag": 2, + "validator_address": "D0810844A5202004AE1249CE17610A4AA5A1684E", + "timestamp": "2024-03-25T06:14:27.504915992Z", + "signature": "yB9nGNImbiz1x/fc/wMEnmbT5vahaPEWolorzE35PhOW+JveeTH5wXVfc8V2+PKIflFPn2ftbR/j7Jvns96GCw==" + }, + { + "block_id_flag": 2, + "validator_address": "0C170D04155D212B97B3D33AD24D0076053E70C2", + "timestamp": "2024-03-25T06:14:27.282067495Z", + "signature": "5S/h/C2XHP70XYO7WXAzOOHZCz0eyO+RLNO59c7VVfZcPloEomvwrVlyG+UOL1cHV0BxTqHOmy82+V0TE3tZAw==" + }, + { + "block_id_flag": 2, + "validator_address": "2859D4F84CABF0136BEAF3EFA339F5BF6F6CD39C", + "timestamp": "2024-03-25T06:14:27.229881613Z", + "signature": "GljjGBNXjaJdU3yObE7h58jJwbCoAoNLMtjvpMYG/UHtrk3vBvxiILksgS3nKxXnLYv+8UDqNaM9BYRs3cKlCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "195623E1DDC7F85D8E5015D79B9D0DA47A7F59C2", + "timestamp": "2024-03-25T06:14:27.238487848Z", + "signature": "UFjUdS/aJgk2DPWC/BJKgMmqIuGGQMrNwdAdLFKcRjHfjNmBS2JanaSt43Hrlrpha0USzAOUYecVp8Qnif+8Dw==" + }, + { + "block_id_flag": 2, + "validator_address": "7B0411064960AD679FC4A64A7066B401DF3C7F52", + "timestamp": "2024-03-25T06:14:27.294517354Z", + "signature": "xuSuad88AM2c9Jp3n3Q/tERfFoZrxBPv0I59ZJl1rLvqPE3nZBOuCBMwZPUCEa9136QsNfpXEemt/4jlliN5Cw==" + }, + { + "block_id_flag": 2, + "validator_address": "8066E3C72BE72F9CD84439FFB59D79B2C316C01D", + "timestamp": "2024-03-25T06:14:27.297025738Z", + "signature": "SsE4E3QYw+1rk9uhObCu3YUlHQSoREfMeVX456rSeQLhU+Lppat69YtxnG4FWGeBBzgMZ+jg+s+GyWhVOIjDBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "8CB1BE337D1427136EB8EDDD9232735E2405C50C", + "timestamp": "2024-03-25T06:14:27.248658018Z", + "signature": "SOO5yhm/Zs/qgTMYbId1yn44P4Bo/88BtNvJBEmziJeOwrpwV0So5q1FDQ2pK+ddAsc9ampt2pIA3gdlNimgDw==" + }, + { + "block_id_flag": 2, + "validator_address": "83CC77F0F60F418B9DE2A24642645777D2FBCC02", + "timestamp": "2024-03-25T06:14:27.254563507Z", + "signature": "aEt+2hSYgJibHGrvCK47cq4NOFSYyQR2lBn2qK7V9KJSRN0ccB5Bp/iM/OyhlJ7PrLOWanQghCqzotcQQb0KAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "D83516A8B94EA1DB899B7C80C76C05D0BE204004", + "timestamp": "2024-03-25T06:14:27.250738609Z", + "signature": "20E5FZHX7sCgykdz7wpaMpt/xCCUPy/3joMlb3vqagUT1OqVgFj5IonKpFPz8WDcZCDv2CEAjc2qzSb0zNAYCw==" + }, + { + "block_id_flag": 2, + "validator_address": "DBDE432B755C38F3136A75D2D3F530B5A74FBDF2", + "timestamp": "2024-03-25T06:14:27.226292884Z", + "signature": "OampF/a5bMIBndboMuM+rsJBoa6rDS1AKYQLf4QV3elgVSxYBPaWh32NGzKI0FvKtfNCo82GiWNyKKvBTXfiCA==" + }, + { + "block_id_flag": 2, + "validator_address": "8F9C9F4EC28C7E06F3D348394270FCA69DBA116B", + "timestamp": "2024-03-25T06:14:27.294859322Z", + "signature": "Aid0oQvPLKP2Ab78Nj2jnw/2TVc7ojnh8oi2q/dETrip9eEH8XSeQJ9+bKnFU2oKnmcK1FYkKwGzi5m2EfpEBg==" + }, + { + "block_id_flag": 2, + "validator_address": "F9F61FD65FB010A8C9365032D83CCAB9FEF69BFA", + "timestamp": "2024-03-25T06:14:27.20862173Z", + "signature": "Raa83ztno5967q1aeVw+SKas6WPNJz0xHOb3z4fAxrAZemNR5rkrEcBK5Dah6l8nQ70m0Y1OYRUEV1GE93e5Aw==" + }, + { + "block_id_flag": 2, + "validator_address": "02425C209B7A5BFDA29FEEC5876E12AEC64D4C81", + "timestamp": "2024-03-25T06:14:27.198883431Z", + "signature": "aFf3eD567PWOwcSWeKXFD156lM9AngvM6w738tUQGj9sI3sLLj+qHFDe2f54ZDx3ybBt01bpvk0Td1isEDhQBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "37CBD9EAD6B6632851646323C2D9127E79B1C37C", + "timestamp": "2024-03-25T06:14:27.250703418Z", + "signature": "aslqoF8TjiCalfO48S98TW5mdfUZ1IP3MK6JWupdwxaVwcEhDcr4wffSK5nqXSHdPhdFmSJsY16jN+4YfyCeAA==" + }, + { + "block_id_flag": 2, + "validator_address": "1DA762F8A91B63B90817D5D3A20D0A3E8CB240C9", + "timestamp": "2024-03-25T06:14:27.20908433Z", + "signature": "9kdJRK8+r0RRZ+q5eQQJPaP+17PKYyImLyHd5XOJqWU4JKS93eqQT6JHKJnTBGo0WAubVV90PI9DvgiWNtrpCw==" + }, + { + "block_id_flag": 2, + "validator_address": "012ED7FDCAFD53E87DBC4F98DCC93B73E30FFA2D", + "timestamp": "2024-03-25T06:14:27.270230258Z", + "signature": "gqwtVHmUbqy5DRDGg6eJjFS4nQgWmmM6e6t4Yx421IF/8/oWZeeMcjjFzlMxX4NonrEB8VBGHvY9hKL20/r2AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "E27C9D446FA6A9CFCE43802136CF958E7F939226", + "timestamp": "2024-03-25T06:14:27.216205479Z", + "signature": "PC05d40CuIxreCOcSWZ4mLm34hTYPWMMpBdcSHxOsQ/IU3MLP3PTikl8j2ugL3umg8OCxnxT2ef80z9df388BQ==" + }, + { + "block_id_flag": 2, + "validator_address": "0B854339BDCC14B85FB8711E41C2942377476F70", + "timestamp": "2024-03-25T06:14:27.209033257Z", + "signature": "l95YxnFCwAt1QuqXomDAkzc1Mo6R9j62BHT0tCSpj98rm6PCjsfIRvEP/+j+gQEqB4jJvqq2U6ZYosm3950NDg==" + }, + { + "block_id_flag": 2, + "validator_address": "ECEE73D95A77E41A4AC3148D75BE7AEB02CC147D", + "timestamp": "2024-03-25T06:14:27.300665187Z", + "signature": "X4XT2w9MkSXRn5NDElBwstWc9nhGGh5NJzO68WUXbZGH87DJlR+V2NdEtYz1/2gfaHw2DH1CLbVN9O9xL0zZDw==" + }, + { + "block_id_flag": 2, + "validator_address": "E3DE542C5573C78253BF5DA6F20E2119C0F1BA48", + "timestamp": "2024-03-25T06:14:27.240320031Z", + "signature": "HeMVDGr5kMtKJe0QRFy/CR3CcfY/xzYb1zawQtvfMb2G7gc06jJ4fd+4OM2JjUrZzG8W7wNx9EWYBzg3wHtwCg==" + }, + { + "block_id_flag": 2, + "validator_address": "1A0DD1BA9B3EF21F6414210D0AA35EE0F9A12BE0", + "timestamp": "2024-03-25T06:14:27.248713782Z", + "signature": "Q9bKIijvXNhhpTJw8GYCn4L6v91/pU6Zc1DjhEofzSkQCzn514glSpn6xs+WQxZw6br6Dn35k42jkdQ8fdT3Ag==" + }, + { + "block_id_flag": 2, + "validator_address": "3E01DF5EF729ABFB3CB4E8CBAE5062D685009FB7", + "timestamp": "2024-03-25T06:14:27.216058329Z", + "signature": "qUlOsW7hLc4RkBFDR2vSqGtpqRsaY2S4c0kr5qgR0rdCVwfOrkVjhBDrtM23nBiRmvzffpsYEUZm687WXmrgBg==" + }, + { + "block_id_flag": 2, + "validator_address": "10AC1B41D924B67539EA8D755FB0158D57B0F555", + "timestamp": "2024-03-25T06:14:27.260938966Z", + "signature": "QG/5BZ+4eq7sJkbrSeiQf41c+yZqbKanwFkIYGD/wiiNMYEhq1b3iZwS5bJKKRLb4zGprDKQ9vaohyN0eSdJDw==" + }, + { + "block_id_flag": 2, + "validator_address": "F5EFDE8E7BF30A548B847ACD250407CF0CC0539E", + "timestamp": "2024-03-25T06:14:27.211301742Z", + "signature": "1fdvlOuPcdAzrMFJxUgUGbRqX8OP1pb+PvxBUFGqaIFtxn+juxFXF15fvHiGjzG+MSF8w9SDzWjHBM323+0ZDA==" + }, + { + "block_id_flag": 2, + "validator_address": "E42A113076FE41D20780BC6F2FA1C700B2756193", + "timestamp": "2024-03-25T06:14:27.304878958Z", + "signature": "LiS/Ncw9LZpOZ7eSxl3mrflu4EFoK+92+81btwv8OH1112OLCcuoUP8FkukKyD2A3eP9asEmnFoGYecMxU/YAw==" + }, + { + "block_id_flag": 2, + "validator_address": "A468764E5AC834870F79453F1CA26060DEBFA629", + "timestamp": "2024-03-25T06:14:27.232074527Z", + "signature": "owk9vcDs3qppskTOF5ukfV40YvWd3uKT2O5OpB+RkvUhsN49HeUCBN+twoNN2yE99F2M0SEitXRdKD/0rqQZCw==" + }, + { + "block_id_flag": 2, + "validator_address": "7991CF87E4FF6C6D46376939E6E7214FA7473AE0", + "timestamp": "2024-03-25T06:14:27.24642099Z", + "signature": "5ekIibouYY03U0xtyEJH3b2DY5rBsQmmujd4q+P/Hz7Hu6fjqsDVe5r/w5Y+SyJW4Dpeu3IUBlHRLtMdWrU6CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "132A20818488C9362C9E37E529B879CBCD6FBDF3", + "timestamp": "2024-03-25T06:14:27.252922227Z", + "signature": "6XS3kXciqm/vyY5bILQ8+OIqNitOvmjcoTFECvuSwxQXonh3oLl9qDYMetl6TZzBfmWxOTwrvETU0YKanRP1Bg==" + }, + { + "block_id_flag": 2, + "validator_address": "4C10504F2614BE17668FB7EE4CCDC9BDBDC5E94D", + "timestamp": "2024-03-25T06:14:27.198949987Z", + "signature": "x0mukdGORqepq+INtUB8sifZ0EtHqhzXFZIgA1OMHyMEx3vg+m8qHdrxjfbN7QQcdkJGblG2UO9EMjQO5Tl6Bw==" + }, + { + "block_id_flag": 2, + "validator_address": "152DBAD504AF9B1C103D3D4BBBB472C45758F301", + "timestamp": "2024-03-25T06:14:27.301151981Z", + "signature": "JJ3DoJqBz2YjqdYElJT39L+viwFYy+svDpzgRBCflUGYDy41YyejvI7EoN21M3AbRylYVQrR3kF32aTvccTxDA==" + }, + { + "block_id_flag": 2, + "validator_address": "2191940572E2B2E4F477DA155AE95FA3697AF3D3", + "timestamp": "2024-03-25T06:14:27.222339495Z", + "signature": "RCpNsDllj2GCQ/wkgPlXPMB4a1b52U/kdFlasvR84uaZKhbf5vZKlQTlNMRk1UQ8OEduRfWuUUuVAnc8te+ICA==" + }, + { + "block_id_flag": 2, + "validator_address": "AF28D38FEA9D6F1A8559AE134EDA0F1FE1509768", + "timestamp": "2024-03-25T06:14:27.2892123Z", + "signature": "YvuPNZ2Pop9TeQjP231tgShezvdoIYj617baGJbRBfNxnuxzU2ZuouJOO2AtTgOr3yxxLmuntl7j21OYUugCBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "8D0008FE0C7A6EE7BDD1D59CAFFF96AE369C303F", + "timestamp": "2024-03-25T06:14:27.318615916Z", + "signature": "TMQnpCOmCG/XciqY1H1X+DRZn9d9a9ODBOgZAmGY1z98z3Le6ftIOtV4nBLNYbOw7JscKCy8HMTGOfUQTB32Ag==" + }, + { + "block_id_flag": 2, + "validator_address": "88102131B351CE7719EED9CADB15330217A9D038", + "timestamp": "2024-03-25T06:14:27.239020415Z", + "signature": "94mJSDK5AcChfp2Rs6w/LCl2Oa37J+S1wuqJD9MNDsSv8nx3ysxh7QkBqQrJmlO6z6zHQUw/H5frCFsAXqy9BA==" + }, + { + "block_id_flag": 2, + "validator_address": "9C3BFE7B68E53DFF9D3CF7B70E3B8115AFD42411", + "timestamp": "2024-03-25T06:14:27.402701022Z", + "signature": "8Pk9YesjiQUC9bTxL83CeDtofxEm6YesuPWfN3luxaBFY9crRetMZq6dVizo/lJz/teN2uLlVaKK4wmlivapDA==" + }, + { + "block_id_flag": 2, + "validator_address": "39BB490F1B1554AF3FB524CC89D1533EC5A02E2D", + "timestamp": "2024-03-25T06:14:27.203968116Z", + "signature": "tNL9c9RvIDEZr3sxrFzxxuzVnGZLFGNFabqtyEhDGzYp6fRtXHtcLOWkZoZVTBZsQ9TXRGADsNhxJbcTElenCA==" + }, + { + "block_id_flag": 2, + "validator_address": "750CA8CEE4ABA1CA93D1E0A524F26DA8A64EF7F7", + "timestamp": "2024-03-25T06:14:27.23364418Z", + "signature": "R318nz6/+S8PoN/2C/wHiT4zQdyqe5PlPP0C0ArZJ3DnK1NfM4O073tWOcQ/CTh24690+xhWRjOx32QfduEFBA==" + }, + { + "block_id_flag": 2, + "validator_address": "DBAC8BF532C03354ED8BCA5FB7992EA14C1B62C1", + "timestamp": "2024-03-25T06:14:27.263448028Z", + "signature": "1NFURpxVZOD3gXu9E7Bg77suvhIeJg6D5i+fVUTReoQnE38aJJwfCqrKPpnzkDOycHZlkONg/VkfMK0Cr5oVBg==" + }, + { + "block_id_flag": 2, + "validator_address": "E7F7CE3DC63D23B2AC7A233A432F8C7ED74B23B7", + "timestamp": "2024-03-25T06:14:27.192866526Z", + "signature": "n385e1IR/y0OfFgT/8284XFo+DP7hLA+LvNse0IhMnpZQpfn0z9Zwv5a6S16pcKGLtGcSS8bmTMgmifHOBb1Dg==" + }, + { + "block_id_flag": 2, + "validator_address": "23D911027C3A30470D63EBC2EDA4D71C91412543", + "timestamp": "2024-03-25T06:14:27.318050596Z", + "signature": "4ReDzyty2bN7bgbm5gqa+oHxL4oaxDzCOjqUIsbutxk+ydUQVoncqEbjVwn7xT69k6R5ZiHjzVrslJdGO72sCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "4B71B41D7DC82C7F44FADB7D527011678B14693D", + "timestamp": "2024-03-25T06:14:21.339631074Z", + "signature": "IGYRX6oOdKREREx+EmWDVYy4w7qsg3oaganYXH26V0S4hJLDb+ZbCDwIb1YNaolm2ASnA8ebbSf3eVwc7IkRAg==" + }, + { + "block_id_flag": 2, + "validator_address": "3A0C2AED56A4E76E52616CD336FBC311B3799322", + "timestamp": "2024-03-25T06:14:27.250498816Z", + "signature": "E2g6oC0ASeqUU8lUNRjGTkq6Nh7OjzjHgJAk2w9j44Xfl/iY0h1XClsASLOYBU5mi0jcwHtNGDiSebYszwhDCg==" + }, + { + "block_id_flag": 2, + "validator_address": "C071D8A87D78969620BC2D1AB55DCE5B683851ED", + "timestamp": "2024-03-25T06:14:27.217216828Z", + "signature": "/UaOablXzYlqttOw+DpJleRa2RbkOlFL+810RkWnMCN/kOKfaLXs283LOVVXcpfq3FL55m9/Se6WVysZZWoHBw==" + }, + { + "block_id_flag": 2, + "validator_address": "180049B647B4CE71C46D70E1AAAB869B2114D0A5", + "timestamp": "2024-03-25T06:14:27.276196465Z", + "signature": "0aUNZyRMWarl5PmjBpFFoZC0NQDIc9DWiVujKc/12VRpK7q2B8pmTRazKSKIPpCHyhccGuT8ZCnmzNXugG9fAw==" + }, + { + "block_id_flag": 2, + "validator_address": "C875B64A69611343F68BD7F1B81C16F971876720", + "timestamp": "2024-03-25T06:14:27.201976056Z", + "signature": "zt1C0dJQ2VM5LbntMfBNlo4FG45DoAJSydKY+siyF55pqdsxG3QW8lZY+QS/xNIDvB1zLce2d2pKNnqXiYmvDA==" + }, + { + "block_id_flag": 2, + "validator_address": "B6411041F5AA0C6E38612CC8E75BB70E74D0704E", + "timestamp": "2024-03-25T06:14:27.232543158Z", + "signature": "Q7HCCILuaWqAyYvcCLZAJ1Y0/K9DjXK3vi2ULYnBPLAUIMzK+6Vpqlf5qKwzyAyOJmFvg/iyGQp9SUgmTUunCA==" + }, + { + "block_id_flag": 2, + "validator_address": "ABE6553C7FCAB8753E1E2E0FCE046473F93CD6C3", + "timestamp": "2024-03-25T06:14:27.243673233Z", + "signature": "7jeKeynSTUFmxYOOWPXATSiL0Cw8aNY7zqyNqULCWANXBjrMIOOAFQi4MsUUxycX5fY+1bgWV/MWZvbq5UqOAw==" + } + ] + } + } + }, + "block_results": { + "height": "3856726", + "txs_results": [ + { + "code": 0, + "data": "Ei0KKy9pYmMuY29yZS5jbGllbnQudjEuTXNnVXBkYXRlQ2xpZW50UmVzcG9uc2USNQovL2liYy5jb3JlLmNoYW5uZWwudjEuTXNnQWNrbm93bGVkZ2VtZW50UmVzcG9uc2USAggC", + "info": "", + "gas_wanted": "484467", + "gas_used": "403673", + "events": [ + { + "type": "use_feegrant", + "attributes": [ + { + "key": "grantee", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" + }, + { + "key": "granter", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "update_feegrant", + "attributes": [ + { + "key": "grantee", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" + }, + { + "key": "granter", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "436020300000000000aarch" + }, + { + "key": "spender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "436020300000000000aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "436020300000000000aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "436020300000000000aarch" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4/16618" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "BumjcrR0vVFIKuVEKGTGEiunbHUhBwxCvRP/Xx1ZSstpmRuWGYXspOe1yhyOtjG3hGpDu21Tj4Pho2sPDwqAwA==" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/ibc.core.client.v1.MsgUpdateClient" + }, + { + "key": "sender", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" + } + ] + }, + { + "type": "update_client", + "attributes": [ + { + "key": "client_id", + "value": "07-tendermint-70" + }, + { + "key": "client_type", + "value": "07-tendermint" + }, + { + "key": "consensus_height", + "value": "2-15581441" + }, + { + "key": "consensus_heights", + "value": "2-15581441" + }, + { + "key": "header", + "value": "0a262f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e48656164657212c5a4010afd3e0a92030a02080b120a616b6173686e65742d32188182b707220b08c0ac84b00610c79bc8022a480a20922d44f2f302a137e504e1e13c5db35bcaee72048cad6c938c973a3a88cba31e122408041220e3a4c96bfb381a352849de7f701d75a65756fd247e2b66bca84c0486bade38b93220ff89aeb30b95970271355e66c5cf6f5a3759b8f98140b304e229da94be82aa2d3a20b00698a377c95210ab27810302fd90a4b3c92e7965e6e6ed0787d3f2740e2d1f4220e8d022f1af4597974007b2d1bb08b67c53b16a751b6c7c7f110adee60a6b433c4a2017bed346ba6ba721b8eda75e77e94874c944bf1a5c2a09b047ecbe62fa4d293e5220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20360989c22a580cf79524f65c84c33c84a19b148131ed545a8abbecc4f4cdd883622092ae11933d53f4bcf0f988bf0ded0a23182ef48b2b9737d9aeeb1522e044ae6b6a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572148fca7539afd32000bf2c928fc69737483c49b75b12e53b088182b7071a480a202aba4963d64d21e23de083b5628fa44af519509483a780126e8f683be0fcc4d9122408011220b8756df795d8a350b875893cc8d125dd48ea6a89a8547fcf44b81a25b5a3a6bd226808021214b1852d17fa66b5382a8f770725cc5b228b3577501a0c08c5ac84b00610cde3c89a032240859df3a1a0bded57a0c491cb2ff75fa76a9a7483d74105c558cbcfc6f7892f57791a8f3bc1f142e916a23ee75a3bc03f314b8b9a0d7bad967a3e351f21f844042268080212142abc4854b1a1c5aa8403c4ea853a81aca901cc761a0c08c5ac84b00610fb96c2a4032240cb64bc7eb090214ae00aedbe9752e66f7997fce1933142b8a7949ec747dcdd89e8e8d0019bb720344def6d4dff02ed0f176059489101dcb4a1792600d7a40a0322680802121425b40fd5ae2ac26b4382b746f6cddb8c73ce60251a0c08c5ac84b00610d1fcf8a6032240dab2c9cce83842bdce9d53819555f416f29077b0bad03d7f656c1ac3dc4ad3bc6c357d556eb9da5223f9edd47753804eb6f04a6a84e8745257edaedefbe5bb05220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212140549633adf0dd5e91ec75458cbeec35ae4331ad11a0c08c5ac84b006109189e1a3032240fb4af079d53daad6894e66eff8f5d8be255e30b59407ebdf106c66f004cdd5943b0cf8d22d088047d58be23dc5e39cf29615659aaa0f5f2f29009dd6ed7b7408220f08011a0b088092b8c398feffffff01226808021214fe1d612fc9c346e51fa20ed491ebd81162c0e1101a0c08c5ac84b0061095cacaa903224012903fa5ab2717225df16e12c51e01335c54fa5f6baf5e81d2bd273c9553e201799687f10f844067ff94683c05a51520766b2ac1993b6102025a3e632dcdb604220f08011a0b088092b8c398feffffff0122680802121439d8e563c1af1285095ff5bee373e235d63d0cae1a0c08c5ac84b00610df94e7a4032240d321a1c03391bcb663c0d1483015cacd1d82a30158a88b5a7e16e09dbaa0f28a994ad1ba549846994927a8eaa26cbfd3485a1c223c9f2cc356d404ce48f65d0922680802121459835dcbb6ce79f1d12b86702e8690e5f5c514e51a0c08c5ac84b006108cb3a29c032240502a742634bb3dfaf9698a12b679b9c5a376529d28c0bd96543a9f97b39e64ba67b45e025ebe7f69f295ad2c571f5b09f29f01ffc973877f8db84ba8b45f830a2268080212147bd85b0a30cfae183af900b65bc0ec0a28063c991a0c08c5ac84b00610beabdfa00322404cee5b1f3333a536b6a2ee8a88dab1bb8f9bb96a7adef3017d91bef73e4ee68b7cdcfb17a9a81c22072590e0751b3f1d38dc3c85b266ab7b27f015b180d2ef012268080212140218a7a051c04fec85b4f92bfb00a8c4da1a9bd51a0c08c5ac84b006109d9fb1a4032240e065dbd8ba81c1edc4b734364cd4508e1e13bf635f55b0cd960ab638eca7d0c4ee9bc71add507465589417cba9743b7a36eda7b762bf39e80fe450b25aedcf01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214fe849f301b09dacebd2dce15d3ca34d6ba4ca4731a0c08c5ac84b00610cfe9fca9032240de372dbf43b1d6eb45f0d7c7b883e7c6f12d135aa048d6d6591606bd612b97dee6d39c5d212f71d5e53e27b583dd7380368f40f1231f24f1ef749d7a3dfa44092268080212142d9790447341f3371ad11b4b706332313cce33c31a0c08c5ac84b00610f49eba8d032240c4d9b5c20c4c6f1eeadcd03276fe835d71d0f671da5922755156995b91c9e5b484c3e9e3f00f60fcf0832c54a73792d14b6744f7a70ec2c64689008f88d47e0c226808021214dfe3e4385652c2f176ebe59c3dbe4198fd30da901a0c08c5ac84b00610f1f88fa4032240905089e3124740c3af81f36139a014193d6409a7302f1968113156df7f8a84dde0b2da23a6d407c4c0b73db858a0d6a501128545fe81b76239ffcdf61af55709220f08011a0b088092b8c398feffffff012268080212148fca7539afd32000bf2c928fc69737483c49b75b1a0c08c5ac84b006108dddf6a403224072b6a0e54c29d81467082fdd2509e2956f769fb6abe7c8bf84264504f36d3b7318cf74461e70725aa1cef8b219a9c97d535728a8add54fd835e1d6a083a5fe07226808021214eab91d7b40213e14e850a90d7c28e662466dd7c61a0c08c5ac84b00610c9d3db850322402e6bff1624a5953964863100c0d131ed93497c893d3bc967bef501846941e89259b549de34ea6d0cf83b1e72f483397ea5bb88e4f06b1f096f76f6d1c18ac8082268080212142bded3e9a310eeedfb7d4db1778a9413e29d97b11a0c08c5ac84b00610adb8d1a60322407e25144dfcc7af4f7fbbecba576e504a739f7148904c38e697fe5147e5a6d52d701b04b32e133662e2eb89a777a4e84eadd465edf732bec01a3b3f42a4ac040c2268080212141856685db8ac33cb29b9b1d35c034f16511d48501a0c08c5ac84b00610c0c6d2aa032240d7aba48b01d06f8a6a9d99a414e9c09703fbec6a1d1fb933ce4feb17034b1a6786e27b379399403ae69a30f0673a2e7c4fa8f6753a15726529d81dedd0f35704226808021214fac8f77451006668f58b8937a73ae86aee68e2531a0c08c5ac84b00610b784c99a032240a70c848545d669d2e8ea4e9c9bc57ac15fd5b008d8cad2241c5f32e14f44279232874ec8689e121e57b48a79e8d3ce952f4ac3612f486f4939843d7d1557b404226808021214f8bf2150619f6d553ec0ee4427e09ae4cf085aef1a0c08c5ac84b00610cca5aeaa0322408b2fd4a1d57abede09f226812790555a95d3ed43c1ded2c82bb6b424563ff7b554538fa4338e2d9ca7e9432fd1425d70f6f16ed5f802b011a926c1cd384c3c08226808021214ebaaecf31ec18dc4234e01c82b749ae2cd7a95771a0c08c5ac84b0061083abb0b20322408e624290f7816ef1552e51cbe6f94cab4c113276b8ad50bd2280408f9e3e35b4e400677f8db92024ce9fe0d777bb605be7a777fd3fbd76223daf5b83b524da09226808021214c3c730090bf75fc5bfdfbb4bd26589cf1c7b74871a0c08c5ac84b00610c9a6b7850322402fffe20e969254879e78defaefe87a43efa3578bc3ec3727f31667995bc5ee239fdb7a3334a29d92bc3f247c06059fcd8c05b522c71772905f9b7bcb552c7103220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214706fab402d748242cd0a22b49012a6c039feec651a0c08c5ac84b00610f6b49aa90322405a598006423467706d4806c454bdc8e101bc58ad24286bec38964c29447767f93e0b3fe8beca13a9ee57935c05cd01b536282a8e23c1fb7e96723795dd4a5007226808021214b4fd96d19a44fe4b6b05370f200d89251fb68b401a0c08c5ac84b00610f8fc81a50322402c23e85d098e4c8efb6c3dd40a0b52dcf5e47e1a226a5dbaa0482032253732b0eb59de81a8c2e3b8443697f94c71cc6e2e577367ca4b711b6bd08c332f6af100220f08011a0b088092b8c398feffffff012268080212149c29fe719923138d4a27bde5704563e45afc705d1a0c08c5ac84b00610ca9fecaa03224039125eabe6237dbcf691370a9ececacc1b38e5204ca9654ada8325631bbae9741f6c79fd4694cb0bdc461f26b97ca82b7970a5a21f83bc1497787f719cd12c0c220f08011a0b088092b8c398feffffff012268080212144451050fc63430d28fedd2a37f3ba16353c7e60a1a0c08c5ac84b00610809893a70322409fcb186b8cf687398b6a3776f57dd70f7146a4b0be0ed1523ff577be61ea10460fb1eed891a7ad5f02802b9ce018d6cda0f432199e661f75ea27b161bc547f0d226808021214a6e68f4720f047480f3bee8502304baf0faaa7a71a0c08c5ac84b00610ece1e5820322408870aeba3646534181cd016e7631af3d0c486e8822f67ef10856609557fb6532afbd775284f59a50af6b2869b7ca5cb5da0b26f36e41b7f4a3361371750a70052268080212144249abbc6cccb87ef36b481b3016ec33912901891a0c08c5ac84b00610a5faafb3032240a834a3efb9619ac1db9685bbc521baeb9813d1dad7682fcf006cd58c2ef45c8eacc9b9385751913a3e98951db1b1398dbc91f66cbf17a80814b15a0e2824e409226808021214c3266367ddf27040547dc92d5ebb1623caf2903d1a0c08c5ac84b00610dad3ceaa032240188e056696305f22a67d9904a067f0be7f87f1124ade527ef5d3060591379dba30fe57fc4aadf802104e6a2ca50f6a223f867c0fde5de2a7bb24ec21ccb3840422680802121483ee1db3ddc3112b91ee8d6e652cd5eef38c46e01a0c08c5ac84b00610e9db958b03224058a25bdb113d463cd40e59db67510699410caeb3bbef857db839aade920089259d4e941056c92e580295efec5ba048c8ac9a55d50d10de70276527cef1c3d50a2268080212145e56a5d935a9529b8999e1291c64b0ba3f9fd6631a0c08c5ac84b00610f7ac85ab032240da8b69eb538c660dbefb1efd4ecaf28d57867597666b1b2f6540c75b9d536c1484d28c6540f5c485b4ecc20b47f16631ebefd3375d7060fb1c74cba4f4d4e100226808021214fed8e547546670aa5256f64ea16d8bf1a340a5a31a0c08c5ac84b00610c4828da60322406d123b9e2f8162ce671174e124cb77b5f6ac23b7c540b1fe3c09f1dd38a700f2b43d2653c036fd3332e74484e917862a18880fc49c9a4590173c91bc89126a0f22680802121438fbd1eaedfbb5791314bc0661e3b9d145074d901a0c08c5ac84b0061093c98085032240af406ed28fcdbf4f6e1ad92519b72d170dc22bfc82771efd350780df40526811fddeabe3793007ef978b631bdf00ab7161833ca036d143da4e638edc39d80e0922680802121484b7580e977f1fd0448c4cbab82a7d3719367d571a0c08c5ac84b00610eb8d86b40322402f1a1d6f8af2949868ad0bd77365c4f6c24350b676882e523936a47faeac781fbe6d53222f6dd042a78423b7e7d2d3cd90ddb5fb6ffe141f8bae6ad2a70c930d226808021214c24fc0f3780141b5124c8a3bec39de645fb385e41a0c08c5ac84b00610a3e9fba7032240ef1ff6b813753376af4b67e184ee3fed97431a0e5c5696a99cc3a09e336ff714f00140f954960f5962b04e686902f9e420951ff44eaab73e079465fadb905b082268080212146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af81a0c08c5ac84b00610bcb9d4a20322403cba7354f25c17e980c55459ce5de1ac71f210e134d460642e422162e1dd8b692a86ac491ab562268b34e9a4859672d5cf7997903a5cb2ba94814982741b8203220f08011a0b088092b8c398feffffff01226808021214da250934d695a5a2457708f417f688ff8d9cc3261a0c08c5ac84b00610c0d7daac032240f9b9069ec79d2db8c9da98076d1512498c409f57d9d9df96ab7e3e1f8dab47d09cabdf75057f0f18c5953abfde4d16313cfb970d8156eb42dae960580e0f580a220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d21a0c08c5ac84b00610b0c5cea70322407154c18b984e0f75389b45f95d954e69348f63409bf051fb9cbb64649213602e294f9dfadbba3d46281473bb9a9ad01ad499a7539eee51d3bf1b165dbc24110e22680802121462683a7647539e61d001866edb1fb7152e1f79631a0c08c5ac84b00610a3ced5ad0322405d568927456830e6d1bac28dc454175f69993c2ae140fda1739ee1a12498fd8eeff23c636de597d703d1a3fc728c7139426b1634627ce9f0783458e7ba96ac0f226808021214b15aeec05b39196f3a972f5ab8b7c822e3336c3a1a0c08c5ac84b00610dae48ab00322404fd1cab90aa77443f1c7f16cfe829f6f53ffbbd1f2a0b7be4c1d1009b4a1fc433dc9cf40bc91ee6a054d92dc8805a977989d86f34f0d906bf8cf277550e7d50c226808021214f8933325d7838f9f70bf3ad2d8054ed2826cece51a0c08c5ac84b006109aeaa2a803224011a410d587d561a90d5ecd9d794c8c2b83ffcd4edadb5a0dffa5e9dc3b483193e9b760fc5d6ae85f05b1fc3302386a7ee7b06e89b719f1922e18b1c53ed9540a220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214a5af3f1e0814ef41b0613da1a8bafa20513723201a0c08c5ac84b0061085d3cfa703224022bc591f0043a4f15107ffcea4a3100aed1b27bea45541b59773ac2f4d9b1dc73db3158a5a128b7abd9741002207f58bba56027f2c769f97f6d6875a51d98a0b220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214fad3de3292c242997bf4000af8ffd4551272eb621a0c08c5ac84b00610d5f595fe022240a018672598c67c9ea1d14862e4f2c1fe84abc56724b5f855bd7582f8bce34081e11a8ce09d4d2bf08aacb28b39bb2d39dc541662aecd2e3df6ee228f286ffc00226808021214812dc4bd67175c2c4a74a13a4c6990fe41037a5b1a0c08c5ac84b00610d9a692b5032240384f5d91dd77fea058585a881b16c7ce31c19effb85304af002904b86987666f83e853263f3c46fdbdc2c8897a8ba2b6c9d8e0bdc945121385620da79c213b04220f08011a0b088092b8c398feffffff0122680802121430412ba7032186c3a2b1a6b440272e1d4780ab981a0c08c5ac84b00610e0b1e68d03224028370eb4cfb5dcd9aed66fc6db8dbe789a4025fb07aaf1f5b5f4a34463ca49ba2d18effada1b6751e8997709b7c6aff34b4c736c03264652b597558185d061002268080212148d5e2c42b5d2f9d8203f2a7e9173b5358952576a1a0c08c5ac84b00610c1d3bc9f0322400601d8877836d4e7508255146c1398b7627f3935235c9d13a00f2203e83cce64a90484dad6d6d4fb14f43232a7118e92f5cab96b7f5b3074d2ec9a7aad85050b220f08011a0b088092b8c398feffffff01226808021214330b0dee27003d8e8b24be39f82159f375127d321a0c08c5ac84b006109a81c0a603224042ee5c09a22b86a32cba7a5cff74b7e0dbc9cfbbb37faf41921c16af5592e32fd11bde5b1a86237bbfa786456e927de4940a2489e23b4bc5a4f34f82f17b330422680802121458b9f2517dbf8c55573fcfa9853fff27066d86ed1a0c08c5ac84b00610bb908ea20322403d32ba4d917430f76f20a50172bd47221c6359e3ecf4da5a098ba6dc99d1e558f3023e640b2d5cad9cce5857177745241ee9d459927cc5b2a4d79420eb639e0e220f08011a0b088092b8c398feffffff0122680802121458aff9ec275a66e7ad086d31e30fc59e02b94b921a0c08c5ac84b00610948887b20322400e70a330ba99a86d5419e4ed893ebed6aa62067c8cef32f17d4b200c1358f48d0d27106e1f3720146da4f423262a216d3f0f1b70b71c73c53b35f341c07fbd02220f08011a0b088092b8c398feffffff01226808021214ee2a8b5958586c495b1e7bf7ecfc284d83136c151a0c08c5ac84b00610f092ab8703224059e2e0d4331ec786e542c950b6da7dd0e757ba790a3beeba849bb9be2e979d06901b4fbd5dbd3be985cf85374f7367cbbb0376acd7640c867ff9f99854747f092268080212146d8f5894ab17dc6821a7d82c31a05d81b71c17391a0c08c5ac84b00610bfabfaa0032240f2c30fe5b8a0a4d64171ebf508ebbdc63a48110066a2dfb7f0d3c23d17b6738af902d6f8c337bc28c595ded70d2b2ca8049e68714974720400b8c2e2ff4f55092268080212143096bed304a51710ccde2dcdeb5c364c7559e7351a0c08c5ac84b0061086a690ab03224095d1ad85bea361349e57ec4fd4e10dbc1648e679c06d7ecc3b907fb33e342228e664ca182e9110b50175d6d6a21a2dc291437c1d24adfc5427d149d94617e30c226808021214c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f1a0c08c5ac84b00610f4dde9fe0222402233bd14a55b315bacbb57de5091a6948628851a1e630c9188967419b58745852dd0a73d8ceff4d7db35939c992b15a2993eaa435da4e6e2c9c8a3cba01e2109226808021214784cd03b935c7c3e75419b1f35b283e03faa7c0c1a0c08c5ac84b006108f81899c0322400ea212a580087311d4e13d4862d2957b448b31ec5ea34db1092076448f1701b5b23fe8e265aba9148e46205beb663d0c64d97252429338a8388e90b5a2fab70b220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212145245f51eeb87311e0544086e64df6e737afa01521a0c08c5ac84b00610f7f1faa50322401e147cd0d6d40d9fc280001c792b1b027179bda63ae43019256b1796ee8a40c06cd462887b2a1fd68935c3ee2981dc1a98cabc61ae71491d26abd3968886f004226808021214e7dc29639166155dc9ef5d562e44cefec2d169ca1a0c08c5ac84b00610dde093ab032240bac3c333026946c6cef7b263f9ee2a8834a45b7a366b09d1a126b211683a518586d71cf2752c4fa2e52cb6f0d77489db550be12e20caaf82dd789a47144b1803220f08011a0b088092b8c398feffffff0122680802121483a05569feb3c027db1f5e85c48073d6994040ee1a0c08c5ac84b00610c29ee5b30322403523860032e460064bc7a274826dbf67e4577967644266114696cd1ca01bcde0f1a029c53caee332e7ae620a202c1ed4dc7e44c5c5509598efe3ec1dc200e40f226808021214618ca0614c7ea885243f3580790708979be7bd451a0c08c5ac84b00610afa485a5032240973420c1533fb165fe2cc2b345eca839ef3cd3e98b6df638601fb0a64619f31c66dea36915962583f4f78d7742ea386b2702f15624bd4000c6da55782928b902226808021214f8426ee2307c31165cce1cc4da9762ae74f84ec11a0c08c5ac84b00610f7fed0b303224099a1ea5beea3f8f9afb8766f797fb65f71a4bad207ea275077fd4e37c54c31c4de63fc52536dbe4d69986f72da593bc081069e3f42f976a5014435fd96092804226808021214f063a67840c7d6411bd0c4b9603a1c6c7440d3f91a0c08c5ac84b0061082f3b58303224049f91e2c1a96f7675715b2347b9e2fe04c0c7f6b1f5fa66c3e77667caf8d327765f57f6c74bb08395a9e32b05faba764f4289eb44c107efafbc8f8e2c2b83504226808021214c7ed8e58ed8bbc7c0e9911bfaa38c725c00383641a0c08c5ac84b00610bac6e299032240b3c8e95e5b76ab342e1059bae1eec41f572492383c16592a9b09c74d80dfd800555489cb7e0f4697673dadc52237e49ecb69731e2a0368a6a6b239d6156cd406226808021214bdc269f2f62e3b02d6eb049bd2a11a425cfe3f291a0c08c5ac84b00610f182d9a70322402cc04249565c79527bf8a2784351eed93d111aaa111aea25a689ec924adbd55021afd1799fcd2fc9e560536204da4a25f095e651f527695bcc19c1d5106af40d220f08011a0b088092b8c398feffffff012268080212140808a48a93fba44a17029c17b16ad5cb1ccccfce1a0c08c5ac84b00610bd81ad8b032240912941700df39f699fc34b21faed36ce15627db84dde35cf78ca722cbbce6d874ea36d3575cbe8f747cae1dbb9b4d4136f876c5f719bb98cbbae40d0f82acd0b22680802121465a73fb6a5b297299393c8cc9a342242b13697441a0c08c5ac84b00610acdd889e032240752a924c7393e9ffab930c86f04f1655fe1e741ee7f82012bba78fe3e3d4f95457a28eff334a17e51f7b4d53499c852ef6950224f79b133a2c18303808778a03220f08011a0b088092b8c398feffffff0122680802121472f92fd75727431194c7129be2411a9093e6d57c1a0c08c5ac84b00610d6f0aec60322403ae6ed72d3224c9d276162630709ef68412e77a29c4c234ccdde0afcf97d74c7c22ba7d5f2743bea49a766008b3f8211289b76178f636e0bb4e8320d28b0130422680802121411c30fd0a3bda953d88a2157a69b2cab52b41f051a0c08c5ac84b00610cafeed860322402f5d7772ce53445c16156edddf5f2e2590fd089d3d4d8be0761a686b4c658b46ad4f856180ff59bb0098ab01a47e366ec6f42b5a6db83ebf824aa0cd712ad80b22680802121409d7dd253fe3ea53eb16a5c4492166688b3c65801a0c08c5ac84b0061080d8e5ac03224069ddedc5a33917d6a39d334acc752e318bc84c968b473ff769d895f1f6e1d0649d91a2ff141bcca83a7f62a157595d9d569c25029ada94cfaf9efe053e8bc304226808021214f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a1a0c08c5ac84b00610e5a0eea3032240324a9848b8a67cb786a7783b490d6698f4a0e793defcef6e572d5e4b03d6e9d1ce04fe78555eedc6376e7007382bfc3a41c29124a3760170d300688f81591b05220f08011a0b088092b8c398feffffff0112db320a3f0a14b1852d17fa66b5382a8f770725cc5b228b35775012220a20ec06936d55936aca5c041b091c7a311b1f3065bd2b65b60be25ed09104feb8f318f4d3aa060a3f0a142abc4854b1a1c5aa8403c4ea853a81aca901cc7612220a201addaecd87a7fdaf28bb67bc3533bc705bdfb52007365b7d67685f1d65030dde18a8eea8030a3f0a1425b40fd5ae2ac26b4382b746f6cddb8c73ce602512220a203183f39d70ce25f0a8ea02a762e43dd6fa8ec4037e1bd210acfb49570cd0666f18be80f7020a3f0a148dab929d392163909bfc1b2c8be1d4ff5b058f8612220a20e75d7c6c4a161f130000560c02ad4bfb70709ec2b625d3157a19c50a2987cf8e1896b3ed020a3f0a14408b9882eaa1e636bd48998340babe0153050cc312220a20b0d65ae97827e39346b7e0c6390d116301139a6e2d9a189c4edf26782621a38e18f18ad2020a3f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f3010a3f0a140549633adf0dd5e91ec75458cbeec35ae4331ad112220a20cdb58d6d7fa134d2dac24605a3d616d48fe41f8ed872f8e4c98e9037666db16918daf7ea010a3f0a14fd46533e10d45d8fbfda2588c70f927d2e44bc7912220a20e7de761f86056b4946d8d50100da0515061465b0b26cfafd5ddf97f71b41a86e18e7b9e8010a3f0a14fe1d612fc9c346e51fa20ed491ebd81162c0e11012220a20b017d03e09d1d7283fc27775ad243788236939851a5a326ea084fa62a80bbae618c2fac9010a3f0a1483337fa8c2a5bf1283a58384c0ccee0811919e0a12220a20147ee0dd6069170d26c95238e5a979a0ad370b68178926e806b17775cb5d38e018beb8c7010a3f0a1439d8e563c1af1285095ff5bee373e235d63d0cae12220a20e383ebbe5ff6bd0539f2e8618dbd95dd5da15a4147575da0215cf14f3f386b8c18f1a6c1010a3f0a1459835dcbb6ce79f1d12b86702e8690e5f5c514e512220a20e2e8b19d9012cbd9b00e9bdbd3195ea5107d730d5beb9eb771efaf4e0b3a1dee18bb93bd010a3f0a147bd85b0a30cfae183af900b65bc0ec0a28063c9912220a20c68b2e6e48b7049594cf7e6f24a4f2323d7356233a614e7cf7fd5101cc9be97f18edacb6010a3f0a140218a7a051c04fec85b4f92bfb00a8c4da1a9bd512220a203d94dcb94e8d15630e1934ae4fa0bb644f962bfc81b9d9be368882c1017f983e1885afad010a3f0a143596e89e65d41be8200b436c2986e97e9dd1ecce12220a2003512e3640974bc65e350e91c68b130e769ee58eef0f68eff9fd0763a08d441a18c6bb9d010a3f0a14923b8fcd3097ba253408cf32f8a77da355bbc86312220a204137811e4eaf4874c7d64915b28c174eeb7a1be95d314c7b7822f6f93ec5470518f18198010a3f0a14fe849f301b09dacebd2dce15d3ca34d6ba4ca47312220a20a6322cef180e269ebc624714d13c4955dbba0f408cd8e10d997dc7024494f80418f49c95010a3f0a142d9790447341f3371ad11b4b706332313cce33c312220a20d927b9a6b67b352b9c5747c6595766c1ad25c7708d04264aa17e3c580fd98b2718929894010a3f0a14dfe3e4385652c2f176ebe59c3dbe4198fd30da9012220a2072e20f388f16bae585240348109645b102e2f29ab77cbbce7817b5d123bd0df018f2fb92010a3f0a14536c4cc1cf97c4df693b3e7e6604bf0b14f4257e12220a2003c83e556021016aaaffc2f6aa48fdf788d033c3da0924cd21ccdf6dd5cf32d518f7868c010a3f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018e6ad8b010a3f0a14eab91d7b40213e14e850a90d7c28e662466dd7c612220a20d683dd49bf1096490b5ef089100917f040751afd2f698f161e1f80bc2db9511a18e58384010a3e0a142bded3e9a310eeedfb7d4db1778a9413e29d97b112220a20d854ff20e923fd27aeaea258d784afcb9d87c9fe3927d9ad5ae0b1669d1c2d751892bd780a3e0a141856685db8ac33cb29b9b1d35c034f16511d485012220a20e8527069a1e7bfbe25eaafafad88a1ed0f32db8e4e0a1669972c796f6cad6a4e1889a16b0a3e0a14fac8f77451006668f58b8937a73ae86aee68e25312220a20e408946e01267bc86fb50deacc86dafdaedb3a805a9c45eba47810700fadd18618cbd6610a3e0a14f8bf2150619f6d553ec0ee4427e09ae4cf085aef12220a20c7c5ffac225b15476f87b43d652e06304a965e7491d18fb0d9a0a6a208dbf8e818fffa5f0a3e0a14ebaaecf31ec18dc4234e01c82b749ae2cd7a957712220a20755b3e61036e77ae0f9d8b69df1a9cfc0e47c1fcc6bfdb15a675d47def8061fb18bdef5e0a3e0a14c3c730090bf75fc5bfdfbb4bd26589cf1c7b748712220a20f9bbb0bd1d1e5502d4c4c35da60e4f4a738e18ee28455c77888aac7fc3114a7a18a9ec530a3e0a14b4058eebe8da7015a6c0c29f3c53451563478fb712220a20f45743b9d87fdab24ccd8d07f917679c2d29d0f1e1d71113a5d4d93961fc4ea118f0b5500a3e0a14795ad41bb274e23b8d82b32b4f878c30ff76f3ee12220a202687ca37348621f6f0d7bb0d8181b6d7036887940813b7061ca7999a48bd1f8c1895a54c0a3e0a14fabfce1baa453eaf8255bedc5ee8eff464aa37b512220a208ba26509d1dbd124081bef7bde188ede90cb2ade0f6aefe1fe71193800ba962a18b381410a3e0a14706fab402d748242cd0a22b49012a6c039feec6512220a20243bafe50ae8db47bb23976a2aa10d8e60fbf66a6b3400239bfbf6709aad11d518e3d83d0a3e0a14b4fd96d19a44fe4b6b05370f200d89251fb68b4012220a20e738929a9dd600112b677dfee30227dc396c0683beb26cf7ad1c4d439ee972e31899da390a3e0a14aa6786a7b42270295639f5980e8c3648286caea212220a2096a759920df5363c9aee820cd5220ae927c60b510ec497653d3dbf6ec63c8a9f18a5bd390a3e0a149c29fe719923138d4a27bde5704563e45afc705d12220a207017fbc65e3fb62fbebc1b894125a9cd147a8f5cf87bd37590d70a64c7f6401218818e380a3e0a14a21ccd762306bb2651b2a24cfa15ae537c8c633f12220a207ac3ae3da8ea25e443879b5c1b321c3fb05a5c8f793925eec64aa650629e362418ee8b380a3e0a144451050fc63430d28fedd2a37f3ba16353c7e60a12220a204b534106cdefad4f0da9ee1eec2d7c2985ce1c0cfbd47d9461382afd729dc2bb18cd88360a3e0a14a6e68f4720f047480f3bee8502304baf0faaa7a712220a20b217c1303ec5ae61af90f6a8a72caa57b6e59c416f12e8d256dd904b429998ca18e3ce350a3e0a144249abbc6cccb87ef36b481b3016ec339129018912220a203b9674d593af41c481890f6e1fc3aa279cbe5d58eac58671f35734c59f3743c118d1e1330a3e0a14c3266367ddf27040547dc92d5ebb1623caf2903d12220a203aa92f59e180f35d9419add9a3ce6ad0a608541b811424aa85df565d2032c3af189aa3320a3e0a1483ee1db3ddc3112b91ee8d6e652cd5eef38c46e012220a20d6af075513a9e2d25972bc4893c4807336f3a00d98ebd3749980b1afedef30dc18e3b62e0a3e0a145e56a5d935a9529b8999e1291c64b0ba3f9fd66312220a2008983fbb9c4eeb900ad180158ca77242a29063669ae1a4a32641572ddfda83c91888a32d0a3e0a14fed8e547546670aa5256f64ea16d8bf1a340a5a312220a20f89aeac801b13028472b4733dde75e161b1bfc186b587c469097c0a66b431aba18fb872d0a3e0a1438fbd1eaedfbb5791314bc0661e3b9d145074d9012220a208db395073ffa6278e1c05481ad6a52d50468a90d94efa80b42348f3c62eb0e05189ba52c0a3e0a1484b7580e977f1fd0448c4cbab82a7d3719367d5712220a20eea097ce993a3c7a4e47141404bf14c149be585520e763c22f5cb34909cfbad418dcd4290a3e0a14c24fc0f3780141b5124c8a3bec39de645fb385e412220a20047bbb54c5e59a5b740162e0fa02d35efdde81994b5317100fd79214de3529001891e2270a3e0a146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af812220a20ed9d6aa7a16df68792b42371f386b5308c347f3e8e2f9301a857dfc3f1e72e4718b4d2270a3e0a14373328b487c327e51cb513e60a8a1c5fdaff5b3012220a20647bc426173aa99f2a5bcac2145078d050c7eb72d3b361a4aedf21ac0e5ebb9618aff9250a3e0a14da250934d695a5a2457708f417f688ff8d9cc32612220a20a5bc8d67cf595fe8d576257a97d3832df9fc480216a7df493366f92f8736a0ed18f696240a3e0a144198498bc2c20053e5aaaa4ce9cb7e3b93b8e85e12220a20f69e8798c93227eefb3ccf7efc20c3bd96cae139281f2e699f5b4de17878756c18bd99230a3e0a14e28bf9e8ff9ef17268d26a50f7cd998bee4db3f012220a20ea21311aa1f222afdaf21a2c5cfac248ac8fbe816354e466ac4fafb4f60a513218c8b1220a3e0a14fb2ef7e3b80bf63f9ddc9e2431addbcdc6e7644a12220a203f282143c907b1ef86202f71ffd761693a40748b26961ef5c94930b7cde0812118f1af210a3e0a1479efa8b65cb1f1aa69373ad3d01f442dcfcf938112220a20c85bd96888a6971f1bb95ca0f354f681584c883d7746a7fb312239bc1322d48318f1ac200a3e0a1480524f180664c5a1ac66bdd30bcedb36bbac096a12220a20b00c9552aa825e3e8d0bb9e230fb8e558eb54a0c6fc2b6dde7ea466199e954e018bca8200a3e0a14b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d212220a2030534ef00c64b39ab07df356961b4b6420733389a599242ee26e94de6c76dd7a18daa2200a3e0a1462683a7647539e61d001866edb1fb7152e1f796312220a205040fe5690b8fb12333f1d1b85180a52a9deffa01cf759b6d0efa4e420cdf33018bb9a200a3e0a14b15aeec05b39196f3a972f5ab8b7c822e3336c3a12220a203b9adeab28a2e7165d38299fe0eeb6fb0b6aba7cc201fd5d4955b1fcb56cf9e4189981200a3e0a14f8933325d7838f9f70bf3ad2d8054ed2826cece512220a200a3812c57d816fb4a3ec3686c3b306938d6c72bfce34a23154acd414fa37c5f7189deb1f0a3e0a140d97b64748720fe5d1ddf647ef06eba901caee8612220a20d395877c653467006556d1476ac4b68c9902364ab7fb6507a1a7758f56863cda18f8bf1f0a3e0a145b205289e6d60f7bf3fb4a15db5343da30a2509e12220a200b37c2a9a04bc6a04a68cee15624ced60f603b0939fa9c3ae3c7ddebe96140b5188dab1f0a3e0a14a5af3f1e0814ef41b0613da1a8bafa205137232012220a208ae4723213b340fb244a0d54f6d316aec71776d0fe2cc36d32436f752a1fd44018eca31f0a3e0a149dc49bd022e7e81dbcead966fff4f9af77052f2a12220a207a12ce70a7e988b9ec8ffe03d3ed4758875105bbf15ae78d5d2f46ae67464afd18efcf1e0a3e0a14fd1df5c5f5ea867fb21aa05c00926fabd2639e1612220a20dbb0e5b2016dd75f871ff64f4c8d472fc0da4289690f515f5f173aba8892ab3518d1ec1d0a3e0a14f7a35051ba1ce4f9d5b43157c522275dd90a454212220a2035e4cd35fd12e58f067b8852369bded41708336daca6c176bcbc7cdd8161057818ebab1d0a3e0a14fad3de3292c242997bf4000af8ffd4551272eb6212220a207024974db2eac3a6d3b1106acb52b39e21506c7e26c9f5a61fa86a45e86ce832188eba1c0a3e0a14812dc4bd67175c2c4a74a13a4c6990fe41037a5b12220a20458370b1f37e8de7fa4bae977b90a569285ffe1d37c0460e5b138ad2ecdd738518d6a21b0a3e0a143ded012b42f48947bbb2bd8eef7c0d69d217dce012220a20c2a41771f5e9612ed358c08e997f94be52a4486b6567816e9f50e9f686899b7e18eec5190a3e0a1430412ba7032186c3a2b1a6b440272e1d4780ab9812220a2032307c624e438a213e57ac577044cf328cbb305cc604693611092f77dfe13adf18ce99190a3e0a148d5e2c42b5d2f9d8203f2a7e9173b5358952576a12220a206afd4890886c667d79ee871ae1c1b2b83fdcc26c6fb1cda40695e2091157b152189087190a3e0a143c70fac7857389b869696e8f3e1f48be0be0242912220a20dfdd72d0732e60bf39286432b6b41fb10c0d8905d70897bf2291989e1eeac26518cbda170a3e0a14330b0dee27003d8e8b24be39f82159f375127d3212220a203db48acea4cb759b208b418b3e826ab9c75a77ca3fc7eeb647b84b1ea422308a18bbdc160a3e0a1458b9f2517dbf8c55573fcfa9853fff27066d86ed12220a20d0fa86b1e1eca13d135c07d3dc25814367bff1fafe25e8d8872897d6a0bde59018d79d140a3e0a146f23af09898a93352392cd0977bd5be5c74ef70912220a205ae5773928fed10cbf6f4d5f80d6533501b66736864a3b50e96c58021389b20818a3bc120a3e0a1458aff9ec275a66e7ad086d31e30fc59e02b94b9212220a20640499f5afeeb7ab49c601221c44fb762f3c02d05d5032bde7bab27823a5827718a7a4120a3e0a14e357f35a66a72eb8162f5a66ea221b9025ff56bc12220a20ac38b9ef0c5f7314dec03f8ad4d2fedd35f9d49bc5bb9de48832b55c00d6571518c3f3110a3e0a14ee2a8b5958586c495b1e7bf7ecfc284d83136c1512220a2099a8eeb2d17d0dff6b915cf6c65ffd563606dfd60640a35b8e082d40f67dca3318a683110a3e0a146d8f5894ab17dc6821a7d82c31a05d81b71c173912220a2065348bed02c217dacb610d4c8b7ae45d00389078b18df73e644174a0752c3c8418ceac100a3e0a143096bed304a51710ccde2dcdeb5c364c7559e73512220a20d77807b7263fd82cd116f733f78d7415eb08ac78be46a5e31d20b5285565bfee18ecf70e0a3e0a14c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f12220a20d61e7cdcfae95db114e7dce184ca3b11d59fc64b9163bc02bc8728631b4b5f5718c9e40e0a3e0a14784cd03b935c7c3e75419b1f35b283e03faa7c0c12220a205364bf153a2c5eb3e916bf62c327bbe782ee6b275863c9a11f8af39f7bef4eed18a2e00c0a3e0a142640a32bf68b7f9723e001c2e4b4e32e00b9467912220a209e5d22a072e232bf5c277dffa170ebc80db49d5496c0b638b6af2c01ea993c0c18b1dd0c0a3e0a14caab75b9c6d41e924cd1b526f5e2d123db756bc412220a2091da6ce3e1debed393e42c02a9641e42e965fe5b4095699c3db096049b29b4ea18d9c10c0a3e0a145245f51eeb87311e0544086e64df6e737afa015212220a203df173fba4427fd0acd8bc0f6c83f8f13a7944e5ad20c5f365c7390e5382313918acc00b0a3e0a14e7dc29639166155dc9ef5d562e44cefec2d169ca12220a203f0eb2d5e935320f269d5ab878104d36be1a2bc38d5ef1b2fe66760814a93c9818affd0a0a3e0a1457f61959ff8a08562bb0aba4921c5ef1b307dc6312220a20f5d18e7d52e05100d55e2f5fd0aa9fa8ba710f0801d7f605985b9732063b1c58188fee0a0a3e0a1483a05569feb3c027db1f5e85c48073d6994040ee12220a2087e931b901b4fb3d4733e821ad082d39d13930a1705baf4f5876a941e12f22dd18e3b30a0a3e0a14618ca0614c7ea885243f3580790708979be7bd4512220a200ec759549c85f6a5a4dbc79f7b112de4592dff74e9562d71c45a8fd3161dc9f318fbfc090a3e0a14f8426ee2307c31165cce1cc4da9762ae74f84ec112220a202cb896fc05f2f31a15a470963122fad880de8d26bff2a259291fb18af4d5914418dcf7090a3e0a14f063a67840c7d6411bd0c4b9603a1c6c7440d3f912220a20f9b393d098812877c926b72ffb2acea890ef4e8d321595c8b3f6d2b6ad92dff118a5ac090a3e0a14c7ed8e58ed8bbc7c0e9911bfaa38c725c003836412220a2060d20c0dd3ac3a21ffdbb7a4f0e6e704ff5fc0a6d11b10d1ee194b1a1fedbf7518e788090a3e0a14bdc269f2f62e3b02d6eb049bd2a11a425cfe3f2912220a203cb375c0722fd44d8da62db992e0bb34036e931ab217862892eca2cbcfbb2e9218eff9080a3e0a14c1976fefd48939e2327cbf83f367841028b95e0e12220a208aaa1c11dc4b43e95603cb10d9d24b6215e0232c5d87bb80539d440d6792e22618bb88080a3e0a140808a48a93fba44a17029c17b16ad5cb1ccccfce12220a20cdee5cd83bf3e85634a60f171c51cabba3fe76257605782eeb11d3a9d735c31a1899fd070a3e0a1465a73fb6a5b297299393c8cc9a342242b136974412220a207887710424a3375409f13d31bfed217c1524fb0db7c4f64db96671a5bdcebbc418e48d070a3e0a140c714e67a83273e3c3e35b17ca8ee140551a536012220a203452cde83ab0a21e43c9b749851e03b2ed0421aea710281711ca57d448af7bc218fc90060a3e0a1472f92fd75727431194c7129be2411a9093e6d57c12220a208ed5b1abd4aa4593dcb9c790927ac89f866e54c73d593554e13ef1efd86ab66918c0eb050a3e0a1411c30fd0a3bda953d88a2157a69b2cab52b41f0512220a2079e66631b3171534f3bce2430e6f9a87d83b94d0fcc4d21068dfcd3e2002df3e18d788040a3e0a1409d7dd253fe3ea53eb16a5c4492166688b3c658012220a20a24599a1f46bad5422ffb0d05e83a4394b602ffa007fe3393c985569ee7aa07f18acff030a3e0a14f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a12220a205556636b3bbc09f22e546840fa79d6628e36b4e4ff8d6978d9b274a5a92d932b18abfe020a3d0a1413a56fa6f11adaa2b09d97e57b36277319f22df012220a20315f78bea93b18884bab79e68711a9c05c67953b78788979e80c7fb1fc4caad618ab73123f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018e6ad8b0118d988be3e1a07080210c080b70722db320a3f0a14b1852d17fa66b5382a8f770725cc5b228b35775012220a20ec06936d55936aca5c041b091c7a311b1f3065bd2b65b60be25ed09104feb8f318edd3aa060a3f0a142abc4854b1a1c5aa8403c4ea853a81aca901cc7612220a201addaecd87a7fdaf28bb67bc3533bc705bdfb52007365b7d67685f1d65030dde1894eea8030a3f0a1425b40fd5ae2ac26b4382b746f6cddb8c73ce602512220a203183f39d70ce25f0a8ea02a762e43dd6fa8ec4037e1bd210acfb49570cd0666f189d80f7020a3f0a148dab929d392163909bfc1b2c8be1d4ff5b058f8612220a20e75d7c6c4a161f130000560c02ad4bfb70709ec2b625d3157a19c50a2987cf8e1891b3ed020a3f0a14408b9882eaa1e636bd48998340babe0153050cc312220a20b0d65ae97827e39346b7e0c6390d116301139a6e2d9a189c4edf26782621a38e18dc8ad2020a3f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f3010a3f0a140549633adf0dd5e91ec75458cbeec35ae4331ad112220a20cdb58d6d7fa134d2dac24605a3d616d48fe41f8ed872f8e4c98e9037666db16918daf7ea010a3f0a14fd46533e10d45d8fbfda2588c70f927d2e44bc7912220a20e7de761f86056b4946d8d50100da0515061465b0b26cfafd5ddf97f71b41a86e18dab9e8010a3f0a14fe1d612fc9c346e51fa20ed491ebd81162c0e11012220a20b017d03e09d1d7283fc27775ad243788236939851a5a326ea084fa62a80bbae618c2fac9010a3f0a1483337fa8c2a5bf1283a58384c0ccee0811919e0a12220a20147ee0dd6069170d26c95238e5a979a0ad370b68178926e806b17775cb5d38e018beb8c7010a3f0a1439d8e563c1af1285095ff5bee373e235d63d0cae12220a20e383ebbe5ff6bd0539f2e8618dbd95dd5da15a4147575da0215cf14f3f386b8c18f1a6c1010a3f0a1459835dcbb6ce79f1d12b86702e8690e5f5c514e512220a20e2e8b19d9012cbd9b00e9bdbd3195ea5107d730d5beb9eb771efaf4e0b3a1dee18b593bd010a3f0a147bd85b0a30cfae183af900b65bc0ec0a28063c9912220a20c68b2e6e48b7049594cf7e6f24a4f2323d7356233a614e7cf7fd5101cc9be97f18edacb6010a3f0a140218a7a051c04fec85b4f92bfb00a8c4da1a9bd512220a203d94dcb94e8d15630e1934ae4fa0bb644f962bfc81b9d9be368882c1017f983e1885afad010a3f0a143596e89e65d41be8200b436c2986e97e9dd1ecce12220a2003512e3640974bc65e350e91c68b130e769ee58eef0f68eff9fd0763a08d441a18c6bb9d010a3f0a14923b8fcd3097ba253408cf32f8a77da355bbc86312220a204137811e4eaf4874c7d64915b28c174eeb7a1be95d314c7b7822f6f93ec5470518f18198010a3f0a14fe849f301b09dacebd2dce15d3ca34d6ba4ca47312220a20a6322cef180e269ebc624714d13c4955dbba0f408cd8e10d997dc7024494f80418f49c95010a3f0a142d9790447341f3371ad11b4b706332313cce33c312220a20d927b9a6b67b352b9c5747c6595766c1ad25c7708d04264aa17e3c580fd98b2718f29794010a3f0a14dfe3e4385652c2f176ebe59c3dbe4198fd30da9012220a2072e20f388f16bae585240348109645b102e2f29ab77cbbce7817b5d123bd0df018f2fb92010a3f0a14536c4cc1cf97c4df693b3e7e6604bf0b14f4257e12220a2003c83e556021016aaaffc2f6aa48fdf788d033c3da0924cd21ccdf6dd5cf32d518f7868c010a3f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018ddad8b010a3f0a14eab91d7b40213e14e850a90d7c28e662466dd7c612220a20d683dd49bf1096490b5ef089100917f040751afd2f698f161e1f80bc2db9511a18e58384010a3e0a142bded3e9a310eeedfb7d4db1778a9413e29d97b112220a20d854ff20e923fd27aeaea258d784afcb9d87c9fe3927d9ad5ae0b1669d1c2d751892bd780a3e0a141856685db8ac33cb29b9b1d35c034f16511d485012220a20e8527069a1e7bfbe25eaafafad88a1ed0f32db8e4e0a1669972c796f6cad6a4e1889a16b0a3e0a14fac8f77451006668f58b8937a73ae86aee68e25312220a20e408946e01267bc86fb50deacc86dafdaedb3a805a9c45eba47810700fadd18618cbd6610a3e0a14f8bf2150619f6d553ec0ee4427e09ae4cf085aef12220a20c7c5ffac225b15476f87b43d652e06304a965e7491d18fb0d9a0a6a208dbf8e818fefa5f0a3e0a14ebaaecf31ec18dc4234e01c82b749ae2cd7a957712220a20755b3e61036e77ae0f9d8b69df1a9cfc0e47c1fcc6bfdb15a675d47def8061fb18bdef5e0a3e0a14c3c730090bf75fc5bfdfbb4bd26589cf1c7b748712220a20f9bbb0bd1d1e5502d4c4c35da60e4f4a738e18ee28455c77888aac7fc3114a7a18a7ec530a3e0a14b4058eebe8da7015a6c0c29f3c53451563478fb712220a20f45743b9d87fdab24ccd8d07f917679c2d29d0f1e1d71113a5d4d93961fc4ea118f0b5500a3e0a14795ad41bb274e23b8d82b32b4f878c30ff76f3ee12220a202687ca37348621f6f0d7bb0d8181b6d7036887940813b7061ca7999a48bd1f8c1895a54c0a3e0a14fabfce1baa453eaf8255bedc5ee8eff464aa37b512220a208ba26509d1dbd124081bef7bde188ede90cb2ade0f6aefe1fe71193800ba962a18b381410a3e0a14706fab402d748242cd0a22b49012a6c039feec6512220a20243bafe50ae8db47bb23976a2aa10d8e60fbf66a6b3400239bfbf6709aad11d518e3d83d0a3e0a14b4fd96d19a44fe4b6b05370f200d89251fb68b4012220a20e738929a9dd600112b677dfee30227dc396c0683beb26cf7ad1c4d439ee972e31898da390a3e0a14aa6786a7b42270295639f5980e8c3648286caea212220a2096a759920df5363c9aee820cd5220ae927c60b510ec497653d3dbf6ec63c8a9f18a5bd390a3e0a149c29fe719923138d4a27bde5704563e45afc705d12220a207017fbc65e3fb62fbebc1b894125a9cd147a8f5cf87bd37590d70a64c7f6401218808e380a3e0a14a21ccd762306bb2651b2a24cfa15ae537c8c633f12220a207ac3ae3da8ea25e443879b5c1b321c3fb05a5c8f793925eec64aa650629e362418ee8b380a3e0a144451050fc63430d28fedd2a37f3ba16353c7e60a12220a204b534106cdefad4f0da9ee1eec2d7c2985ce1c0cfbd47d9461382afd729dc2bb18cd88360a3e0a14a6e68f4720f047480f3bee8502304baf0faaa7a712220a20b217c1303ec5ae61af90f6a8a72caa57b6e59c416f12e8d256dd904b429998ca18e3ce350a3e0a144249abbc6cccb87ef36b481b3016ec339129018912220a203b9674d593af41c481890f6e1fc3aa279cbe5d58eac58671f35734c59f3743c118d1e1330a3e0a14c3266367ddf27040547dc92d5ebb1623caf2903d12220a203aa92f59e180f35d9419add9a3ce6ad0a608541b811424aa85df565d2032c3af189aa3320a3e0a1483ee1db3ddc3112b91ee8d6e652cd5eef38c46e012220a20d6af075513a9e2d25972bc4893c4807336f3a00d98ebd3749980b1afedef30dc18e3b62e0a3e0a145e56a5d935a9529b8999e1291c64b0ba3f9fd66312220a2008983fbb9c4eeb900ad180158ca77242a29063669ae1a4a32641572ddfda83c91888a32d0a3e0a14fed8e547546670aa5256f64ea16d8bf1a340a5a312220a20f89aeac801b13028472b4733dde75e161b1bfc186b587c469097c0a66b431aba18fb872d0a3e0a1438fbd1eaedfbb5791314bc0661e3b9d145074d9012220a208db395073ffa6278e1c05481ad6a52d50468a90d94efa80b42348f3c62eb0e05189ba52c0a3e0a1484b7580e977f1fd0448c4cbab82a7d3719367d5712220a20eea097ce993a3c7a4e47141404bf14c149be585520e763c22f5cb34909cfbad418dcd4290a3e0a14c24fc0f3780141b5124c8a3bec39de645fb385e412220a20047bbb54c5e59a5b740162e0fa02d35efdde81994b5317100fd79214de3529001891e2270a3e0a146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af812220a20ed9d6aa7a16df68792b42371f386b5308c347f3e8e2f9301a857dfc3f1e72e4718b4d2270a3e0a14373328b487c327e51cb513e60a8a1c5fdaff5b3012220a20647bc426173aa99f2a5bcac2145078d050c7eb72d3b361a4aedf21ac0e5ebb9618aff9250a3e0a14da250934d695a5a2457708f417f688ff8d9cc32612220a20a5bc8d67cf595fe8d576257a97d3832df9fc480216a7df493366f92f8736a0ed18f696240a3e0a144198498bc2c20053e5aaaa4ce9cb7e3b93b8e85e12220a20f69e8798c93227eefb3ccf7efc20c3bd96cae139281f2e699f5b4de17878756c18bd99230a3e0a14e28bf9e8ff9ef17268d26a50f7cd998bee4db3f012220a20ea21311aa1f222afdaf21a2c5cfac248ac8fbe816354e466ac4fafb4f60a513218c8b1220a3e0a14fb2ef7e3b80bf63f9ddc9e2431addbcdc6e7644a12220a203f282143c907b1ef86202f71ffd761693a40748b26961ef5c94930b7cde0812118f1af210a3e0a1479efa8b65cb1f1aa69373ad3d01f442dcfcf938112220a20c85bd96888a6971f1bb95ca0f354f681584c883d7746a7fb312239bc1322d48318f1ac200a3e0a1480524f180664c5a1ac66bdd30bcedb36bbac096a12220a20b00c9552aa825e3e8d0bb9e230fb8e558eb54a0c6fc2b6dde7ea466199e954e018aba8200a3e0a14b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d212220a2030534ef00c64b39ab07df356961b4b6420733389a599242ee26e94de6c76dd7a18daa2200a3e0a1462683a7647539e61d001866edb1fb7152e1f796312220a205040fe5690b8fb12333f1d1b85180a52a9deffa01cf759b6d0efa4e420cdf33018bb9a200a3e0a14b15aeec05b39196f3a972f5ab8b7c822e3336c3a12220a203b9adeab28a2e7165d38299fe0eeb6fb0b6aba7cc201fd5d4955b1fcb56cf9e4189981200a3e0a14f8933325d7838f9f70bf3ad2d8054ed2826cece512220a200a3812c57d816fb4a3ec3686c3b306938d6c72bfce34a23154acd414fa37c5f7189deb1f0a3e0a140d97b64748720fe5d1ddf647ef06eba901caee8612220a20d395877c653467006556d1476ac4b68c9902364ab7fb6507a1a7758f56863cda18f8bf1f0a3e0a145b205289e6d60f7bf3fb4a15db5343da30a2509e12220a200b37c2a9a04bc6a04a68cee15624ced60f603b0939fa9c3ae3c7ddebe96140b5188dab1f0a3e0a14a5af3f1e0814ef41b0613da1a8bafa205137232012220a208ae4723213b340fb244a0d54f6d316aec71776d0fe2cc36d32436f752a1fd44018eca31f0a3e0a149dc49bd022e7e81dbcead966fff4f9af77052f2a12220a207a12ce70a7e988b9ec8ffe03d3ed4758875105bbf15ae78d5d2f46ae67464afd18efcf1e0a3e0a14fd1df5c5f5ea867fb21aa05c00926fabd2639e1612220a20dbb0e5b2016dd75f871ff64f4c8d472fc0da4289690f515f5f173aba8892ab3518d0ec1d0a3e0a14f7a35051ba1ce4f9d5b43157c522275dd90a454212220a2035e4cd35fd12e58f067b8852369bded41708336daca6c176bcbc7cdd8161057818ebab1d0a3e0a14fad3de3292c242997bf4000af8ffd4551272eb6212220a207024974db2eac3a6d3b1106acb52b39e21506c7e26c9f5a61fa86a45e86ce832188eba1c0a3e0a14812dc4bd67175c2c4a74a13a4c6990fe41037a5b12220a20458370b1f37e8de7fa4bae977b90a569285ffe1d37c0460e5b138ad2ecdd738518d6a21b0a3e0a143ded012b42f48947bbb2bd8eef7c0d69d217dce012220a20c2a41771f5e9612ed358c08e997f94be52a4486b6567816e9f50e9f686899b7e18eec5190a3e0a1430412ba7032186c3a2b1a6b440272e1d4780ab9812220a2032307c624e438a213e57ac577044cf328cbb305cc604693611092f77dfe13adf18ce99190a3e0a148d5e2c42b5d2f9d8203f2a7e9173b5358952576a12220a206afd4890886c667d79ee871ae1c1b2b83fdcc26c6fb1cda40695e2091157b152189087190a3e0a143c70fac7857389b869696e8f3e1f48be0be0242912220a20dfdd72d0732e60bf39286432b6b41fb10c0d8905d70897bf2291989e1eeac26518cbda170a3e0a14330b0dee27003d8e8b24be39f82159f375127d3212220a203db48acea4cb759b208b418b3e826ab9c75a77ca3fc7eeb647b84b1ea422308a18bbdc160a3e0a1458b9f2517dbf8c55573fcfa9853fff27066d86ed12220a20d0fa86b1e1eca13d135c07d3dc25814367bff1fafe25e8d8872897d6a0bde59018d79d140a3e0a146f23af09898a93352392cd0977bd5be5c74ef70912220a205ae5773928fed10cbf6f4d5f80d6533501b66736864a3b50e96c58021389b20818a3bc120a3e0a1458aff9ec275a66e7ad086d31e30fc59e02b94b9212220a20640499f5afeeb7ab49c601221c44fb762f3c02d05d5032bde7bab27823a5827718a7a4120a3e0a14e357f35a66a72eb8162f5a66ea221b9025ff56bc12220a20ac38b9ef0c5f7314dec03f8ad4d2fedd35f9d49bc5bb9de48832b55c00d6571518c3f3110a3e0a14ee2a8b5958586c495b1e7bf7ecfc284d83136c1512220a2099a8eeb2d17d0dff6b915cf6c65ffd563606dfd60640a35b8e082d40f67dca3318a683110a3e0a146d8f5894ab17dc6821a7d82c31a05d81b71c173912220a2065348bed02c217dacb610d4c8b7ae45d00389078b18df73e644174a0752c3c8418ceac100a3e0a143096bed304a51710ccde2dcdeb5c364c7559e73512220a20d77807b7263fd82cd116f733f78d7415eb08ac78be46a5e31d20b5285565bfee18ecf70e0a3e0a14c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f12220a20d61e7cdcfae95db114e7dce184ca3b11d59fc64b9163bc02bc8728631b4b5f5718c9e40e0a3e0a14784cd03b935c7c3e75419b1f35b283e03faa7c0c12220a205364bf153a2c5eb3e916bf62c327bbe782ee6b275863c9a11f8af39f7bef4eed18a2e00c0a3e0a142640a32bf68b7f9723e001c2e4b4e32e00b9467912220a209e5d22a072e232bf5c277dffa170ebc80db49d5496c0b638b6af2c01ea993c0c18b1dd0c0a3e0a14caab75b9c6d41e924cd1b526f5e2d123db756bc412220a2091da6ce3e1debed393e42c02a9641e42e965fe5b4095699c3db096049b29b4ea18d9c10c0a3e0a145245f51eeb87311e0544086e64df6e737afa015212220a203df173fba4427fd0acd8bc0f6c83f8f13a7944e5ad20c5f365c7390e5382313918acc00b0a3e0a14e7dc29639166155dc9ef5d562e44cefec2d169ca12220a203f0eb2d5e935320f269d5ab878104d36be1a2bc38d5ef1b2fe66760814a93c9818affd0a0a3e0a1457f61959ff8a08562bb0aba4921c5ef1b307dc6312220a20f5d18e7d52e05100d55e2f5fd0aa9fa8ba710f0801d7f605985b9732063b1c58188fee0a0a3e0a1483a05569feb3c027db1f5e85c48073d6994040ee12220a2087e931b901b4fb3d4733e821ad082d39d13930a1705baf4f5876a941e12f22dd18e3b30a0a3e0a14618ca0614c7ea885243f3580790708979be7bd4512220a200ec759549c85f6a5a4dbc79f7b112de4592dff74e9562d71c45a8fd3161dc9f318fbfc090a3e0a14f8426ee2307c31165cce1cc4da9762ae74f84ec112220a202cb896fc05f2f31a15a470963122fad880de8d26bff2a259291fb18af4d5914418dcf7090a3e0a14f063a67840c7d6411bd0c4b9603a1c6c7440d3f912220a20f9b393d098812877c926b72ffb2acea890ef4e8d321595c8b3f6d2b6ad92dff118a5ac090a3e0a14c7ed8e58ed8bbc7c0e9911bfaa38c725c003836412220a2060d20c0dd3ac3a21ffdbb7a4f0e6e704ff5fc0a6d11b10d1ee194b1a1fedbf7518e788090a3e0a14bdc269f2f62e3b02d6eb049bd2a11a425cfe3f2912220a203cb375c0722fd44d8da62db992e0bb34036e931ab217862892eca2cbcfbb2e9218eff9080a3e0a14c1976fefd48939e2327cbf83f367841028b95e0e12220a208aaa1c11dc4b43e95603cb10d9d24b6215e0232c5d87bb80539d440d6792e22618bb88080a3e0a140808a48a93fba44a17029c17b16ad5cb1ccccfce12220a20cdee5cd83bf3e85634a60f171c51cabba3fe76257605782eeb11d3a9d735c31a1899fd070a3e0a1465a73fb6a5b297299393c8cc9a342242b136974412220a207887710424a3375409f13d31bfed217c1524fb0db7c4f64db96671a5bdcebbc418da8d070a3e0a140c714e67a83273e3c3e35b17ca8ee140551a536012220a203452cde83ab0a21e43c9b749851e03b2ed0421aea710281711ca57d448af7bc218fc90060a3e0a1472f92fd75727431194c7129be2411a9093e6d57c12220a208ed5b1abd4aa4593dcb9c790927ac89f866e54c73d593554e13ef1efd86ab66918bceb050a3e0a1411c30fd0a3bda953d88a2157a69b2cab52b41f0512220a2079e66631b3171534f3bce2430e6f9a87d83b94d0fcc4d21068dfcd3e2002df3e18d788040a3e0a1409d7dd253fe3ea53eb16a5c4492166688b3c658012220a20a24599a1f46bad5422ffb0d05e83a4394b602ffa007fe3393c985569ee7aa07f18acff030a3e0a14f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a12220a205556636b3bbc09f22e546840fa79d6628e36b4e4ff8d6978d9b274a5a92d932b18abfe020a3d0a1413a56fa6f11adaa2b09d97e57b36277319f22df012220a20315f78bea93b18884bab79e68711a9c05c67953b78788979e80c7fb1fc4caad618ab73123f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f30118a287be3e" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "ibc_client" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/ibc.core.channel.v1.MsgAcknowledgement" + }, + { + "key": "sender", + "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" + } + ] + }, + { + "type": "acknowledge_packet", + "attributes": [ + { + "key": "connection_id", + "value": "connection-75" + }, + { + "key": "packet_channel_ordering", + "value": "ORDER_UNORDERED" + }, + { + "key": "packet_connection", + "value": "connection-75" + }, + { + "key": "packet_dst_channel", + "value": "channel-126" + }, + { + "key": "packet_dst_port", + "value": "transfer" + }, + { + "key": "packet_sequence", + "value": "988" + }, + { + "key": "packet_src_channel", + "value": "channel-104" + }, + { + "key": "packet_src_port", + "value": "transfer" + }, + { + "key": "packet_timeout_height", + "value": "0-0" + }, + { + "key": "packet_timeout_timestamp", + "value": "1711347430185000000" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "ibc_channel" + } + ] + }, + { + "type": "fungible_token_packet", + "attributes": [ + { + "key": "acknowledgement", + "value": "result:\"\\001\" " + }, + { + "key": "amount", + "value": "27978000" + }, + { + "key": "denom", + "value": "transfer/channel-104/uakt" + }, + { + "key": "memo", + "value": "" + }, + { + "key": "module", + "value": "transfer" + }, + { + "key": "receiver", + "value": "akash1t8np6xr8qr24yjyp3lkg9j4wyeazgf6frrzx4u" + }, + { + "key": "sender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "fungible_token_packet", + "attributes": [ + { + "key": "success", + "value": "\u0001" + } + ] + } + ], + "codespace": "" + } + ], + "begin_block_events": [ + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "20456465438196201488aarch" + }, + { + "key": "receiver", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coinbase", + "attributes": [ + { + "key": "amount", + "value": "20456465438196201488aarch" + }, + { + "key": "minter", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "spender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "spender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "receiver", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "recipient", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + }, + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "archway.rewards.v1.MinConsensusFeeSetEvent", + "attributes": [ + { + "key": "fee", + "value": "{\"denom\":\"aarch\",\"amount\":\"34094109063.660335813333333333\"}" + } + ] + }, + { + "type": "mint", + "attributes": [ + { + "key": "amount", + "value": "20456465438196201488" + }, + { + "key": "annual_provisions", + "value": "107592825618736741349012839.100000000000000000" + }, + { + "key": "bonded_ratio", + "value": "0.476278464914987794" + }, + { + "key": "inflation", + "value": "0.100000000000000000" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "spender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "receiver", + "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "15342349078647151116aarch" + }, + { + "key": "recipient", + "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" + }, + { + "key": "sender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "47031267452693036.061160109957597621aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "940625349053860721.223202199151952412aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "38476736132757653.641375706228733112aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "769534722655153072.827514124574662242aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "25198563408572443.297487568120742094aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "503971268171448865.949751362414841889aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "38385179966923893.758115958837052080aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "479814749586548671.976449485463151006aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "20848080058682149.927238603944519387aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "416961601173642998.544772078890387735aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "18078103662935996.564316767356891825aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "361562073258719931.286335347137836505aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "16397185525293103.453610095140066692aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "327943710505862069.072201902801333835aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "321840969895750362.322698020897468527aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "321840969895750362.322698020897468527aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "15497002790178990.382878376219577609aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "309940055803579807.657567524391552185aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "14382002009562408.966451471365272199aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "287640040191248179.329029427305443980aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13893332467457515.070627762265926164aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "277866649349150301.412555245318523271aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13770849876624121.332192990936737311aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "275416997532482426.643859818734746213aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "12930798182518861.484757122871543030aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "258615963650377229.695142457430860592aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "12030364971758872.030268279538284386aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "240607299435177440.605365590765687724aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11189751818200215.104161320082748986aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "223795036364004302.083226401654979719aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "22284930786917069.309869240938732002aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "222849307869170693.098692409387320015aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "10622762200262906.250589114950164761aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "212455244005258125.011782299003295211aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "20593888085947895.310473392523510734aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "205938880859478953.104733925235107341aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "10233575111733853.664058333319530926aarch" + }, + { + "key": "validator", + "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "204671502234677073.281166666390618516aarch" + }, + { + "key": "validator", + "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9990294308427255.981021251439344373aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "199805886168545119.620425028786887454aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9956509646731535.147278403734301398aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "199130192934630702.945568074686027966aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "19126950729710299.665644427976706534aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "191269507297102996.656444279767065337aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3795328565503973.184141327894708544aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "189766428275198659.207066394735427181aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9442139614759897.331870324410660370aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "188842792295197946.637406488213207399aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "37171458291268257.131570065986651951aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "185857291456341285.657850329933259756aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8909997069263457.716045493806167155aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "178199941385269154.320909876123343102aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8410863836693763.423641845394010617aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "168217276733875268.472836907880212335aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "16287634795052974.555039143568147364aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "162876347950529745.550391435681473638aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8116318548809015.185851059708506321aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "162326370976180303.717021194170126423aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "14106818207670570.608562862410733280aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "156742424529673006.761809582341480886aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7817509546278174.286098972010596527aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "156350190925563485.721979440211930538aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7698025627362544.745416469488871318aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "153960512547250894.908329389777426363aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "1468691530058656.639589777369466772aarch" + }, + { + "key": "validator", + "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "146869153005865663.958977736946677172aarch" + }, + { + "key": "validator", + "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13254946033113129.332220275501974624aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "132549460331131293.322202755019746245aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6528176308965305.138762208357045787aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "130563526179306102.775244167140915739aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6427765125466552.035382663728815800aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "128555302509331040.707653274576315992aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6369673068788454.612640168190546461aarch" + }, + { + "key": "validator", + "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "127393461375769092.252803363810929221aarch" + }, + { + "key": "validator", + "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "12731049483598902.774539034875018554aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "127310494835989027.745390348750185539aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6188648127981006.239817584115334679aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "123772962559620124.796351682306693584aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6111735218698457.658597005193378472aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "122234704373969153.171940103867569443aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11920977472838526.728569377167360808aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "119209774728385267.285693771673608080aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11798931103635591.155836728325712191aarch" + }, + { + "key": "validator", + "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "117989311036355911.558367283257121914aarch" + }, + { + "key": "validator", + "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5734886166478625.892898092108881652aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "114697723329572517.857961842177633032aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9032987084354732.600540116550070865aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "112912338554434157.506751456875885809aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5622139761003751.922093399217840541aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "112442795220075038.441867984356810827aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5467151622868464.860068008108763923aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "109343032457369297.201360162175278454aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5147485597735517.675781608689883791aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "102949711954710353.515632173797675817aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5061348711718600.465891267895790323aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "101226974234372009.317825357915806467aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5029050017899537.493160438270993264aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "100581000357990749.863208765419865282aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4959406531013593.852444214136180672aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "99188130620271877.048884282723613441aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4784203038222939.406288267155309764aarch" + }, + { + "key": "validator", + "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "95684060764458788.125765343106195284aarch" + }, + { + "key": "validator", + "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4660416003997820.740312005440280988aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "93208320079956414.806240108805619764aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9300475936685287.242513541288714658aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "93004759366852872.425135412887146582aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4626325987160778.397378224627902136aarch" + }, + { + "key": "validator", + "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "92526519743215567.947564492558042714aarch" + }, + { + "key": "validator", + "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "902962733350027.401752135061459718aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "90296273335002740.175213506145971754aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8912165512916799.835861475013525979aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "89121655129167998.358614750135259792aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8781155492791221.494594506355942232aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "87811554927912214.945945063559422315aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6899333091057620.960224373610959541aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "86241663638220262.002804670136994266aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4310085005410204.100167898860593316aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "86201700108204082.003357977211866318aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4165137000608207.977714955807129321aarch" + }, + { + "key": "validator", + "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "83302740012164159.554299116142586422aarch" + }, + { + "key": "validator", + "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "823400410887391.655444942037895916aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "82340041088739165.544494203789591620aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8110953022754377.656552773692154718aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "81109530227543776.565527736921547177aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4049923832171419.900874945961500186aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "80998476643428398.017498919230003713aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4046835101594465.126102101748185146aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "80936702031889302.522042034963702927aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4015504538361708.968609533070971737aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "80310090767234179.372190661419434749aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3989445221024750.193829797927477751aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "79788904420495003.876595958549555022aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7819950980242190.974745026504499838aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "78199509802421909.747450265044998376aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3893314638170688.030671063618776405aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "77866292763413760.613421272375528109aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7356227686733312.614918000804230323aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "73562276867333126.149180008042303234aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3651595789734440.460813787200889911aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "73031915794688809.216275744017798219aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6336760568920340.042851852762609760aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "70408450765781556.031687252917886220aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3257159969974389.397733527606727682aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "65143199399487787.954670552134553635aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3241903470240747.643062868104794157aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "64838069404814952.861257362095883149aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6479357479850821.563309842818828243aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "64793574798508215.633098428188282433aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3181101210787609.253499528559273910aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "63622024215752185.069990571185478197aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6341244082981521.831817288858422522aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "63412440829815218.318172888584225217aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5963842014307592.847667445233562256aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "59638420143075928.476674452335622559aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5748320385530191.674253504092312988aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "57483203855301916.742535040923129879aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2852413840903474.221838280346566438aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "57048276818069484.436765606931328767aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2815496826467752.580425254170529570aarch" + }, + { + "key": "validator", + "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "56309936529355051.608505083410591406aarch" + }, + { + "key": "validator", + "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2778202691396666.747218384581883466aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "55564053827933334.944367691637669328aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2694434066683173.206122624486548955aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "53888681333663464.122452489730979101aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2652887474298394.524581334018800918aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "53057749485967890.491626680376018355aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4945956833129978.687897043942664985aarch" + }, + { + "key": "validator", + "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "49459568331299786.878970439426649847aarch" + }, + { + "key": "validator", + "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2348424476570194.306780348897158990aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "46968489531403886.135606977943179798aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4466388844269614.461180848095981218aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "44663888442696144.611808480959812180aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4410639719897042.568753264099370019aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "44106397198970425.687532640993700187aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2180926627806602.966830879190971933aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43618532556132059.336617583819438666aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4334790628526192.728785775490332845aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43347906285261927.287857754903328446aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4317353020640258.703423690157865934aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43173530206402587.034236901578659340aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4310621135865702.319268914397417516aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43106211358657023.192689143974175157aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2151546397411960.927938840521971384aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43030927948239218.558776810439427683aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4276970154992218.095443976355904791aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42769701549922180.954439763559047908aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4227209931455874.017210362427827103aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42272099314558740.172103624278271034aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4224035363719377.513891413189025352aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42240353637193775.138914131890253522aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "" + }, + { + "key": "validator", + "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "36137022017131114.228519325308756161aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3577726581699250.284220154744698892aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "35777265816992502.842201547446988919aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2466956306598184.675480716666651432aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "35242232951402638.221153095237877595aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "983390744674140.023941688397971514aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "32779691489138000.798056279932383792aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "1717680363758128.131106183256179516aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1yw5nl74hv609enqxsn70k55p3pychyc9cvznds" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "17176803637581281.311061832561795160aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1yw5nl74hv609enqxsn70k55p3pychyc9cvznds" + } + ] + } + ], + "end_block_events": [ + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "spender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "receiver", + "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "5114116359549050372aarch" + }, + { + "key": "recipient", + "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" + }, + { + "key": "sender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + } + ], + "validator_updates": null, + "consensus_param_updates": { + "block": { + "max_bytes": "22020096", + "max_gas": "300000000" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000", + "max_bytes": "1048576" + }, + "validator": { + "pub_key_types": ["ed25519"] + } + } + } + } + } +] diff --git a/packages/node/test/kyve_block/bundle.json b/packages/node/test/kyve_block/bundle.json deleted file mode 100644 index f85e4ad06..000000000 --- a/packages/node/test/kyve_block/bundle.json +++ /dev/null @@ -1,3820 +0,0 @@ -{ - "key": "3856726", - "value": { - "block": { - "block_id": { - "hash": "51223D03D35E04476553C309FA4094E8EE09570178B4B77EB5D663F2BF72AB9E", - "parts": { - "total": 1, - "hash": "2D95CC59E4000651933F9E1D3C63BBC06480C9B6BDD201CB8B1FB08E5354AE7D" - } - }, - "block": { - "header": { - "version": { - "block": "11" - }, - "chain_id": "archway-1", - "height": "3856726", - "time": "2024-03-25T06:14:27.24295008Z", - "last_block_id": { - "hash": "C9C081761B20353325F5C2D8A53068F0DD59BD739D562F1017D047825928DF0D", - "parts": { - "total": 1, - "hash": "B645EAA4F54247468C1BA020A71AFCEFB72EAF900E1F3D219EB3FBA5756E4F16" - } - }, - "last_commit_hash": "935D03A37FF6C9C7BF1C89F6DB1A65AC70FA4A0F7CCFC248ED25251E4151423A", - "data_hash": "CE02B6109F04A6C01EB71819F9D8EF1CE28C3D8B1E37B8EFBFF2A1134BF409C0", - "validators_hash": "BE08D7C9A03E52687DB305B8CEF14F96D353FD6DC66F694C0D21FB2BF4C9C4DB", - "next_validators_hash": "BE08D7C9A03E52687DB305B8CEF14F96D353FD6DC66F694C0D21FB2BF4C9C4DB", - "consensus_hash": "22E3FA2D1695AE7DB62E55677BF0C914B1EC88D64CD8D280CF2E29B2E06D0965", - "app_hash": "4F36440223B8AA53C357A9203054C4CC54F669E59714A5F587AD308C5BD4141C", - "last_results_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", - "evidence_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", - "proposer_address": "F183805F63AD6C429B7157D90D7199F2075280AA" - }, - "data": { - "txs": [ - "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" - ] - }, - "evidence": { - "evidence": [] - }, - "last_commit": { - "height": "3856725", - "round": 0, - "block_id": { - "hash": "C9C081761B20353325F5C2D8A53068F0DD59BD739D562F1017D047825928DF0D", - "parts": { - "total": 1, - "hash": "B645EAA4F54247468C1BA020A71AFCEFB72EAF900E1F3D219EB3FBA5756E4F16" - } - }, - "signatures": [ - { - "block_id_flag": 2, - "validator_address": "454BA446172211B1CB7A08E14161FB3BA1493F73", - "timestamp": "2024-03-25T06:14:27.198711863Z", - "signature": "2e8XvUA4Tbn1wEbARGH8NB1UmMK6MS5vMlZjNBV1x4K1+SOGkqSfMdm/ulWngwiOygqBwLgsvmq/rhikwa2rDw==" - }, - { - "block_id_flag": 2, - "validator_address": "5E026F83F8DDC51308008A80518530E9C03C7771", - "timestamp": "2024-03-25T06:14:27.302921022Z", - "signature": "lq2SyHxljxPnLImJIS2/fPAKqyyP4pmhdx3Zs3mAt6gjK6mZUCkTQ1GVF3GAAzDmQplkbnIT5/Vehi31pja5Ag==" - }, - { - "block_id_flag": 2, - "validator_address": "C64F7CF03BBB07B80E1B557A185032114C1F0201", - "timestamp": "2024-03-25T06:14:27.268900037Z", - "signature": "lY9GJMAD7/zGk0S3Kc7VhE80xggXs68AXiYhiJnG5aB+IhpdEorKdGxXWrw/Tl7V/NNGwfM1DM+naq6e3rBeBg==" - }, - { - "block_id_flag": 2, - "validator_address": "9396A4ECDC186B5F92600579AEC5E04D1059642D", - "timestamp": "2024-03-25T06:14:27.292183475Z", - "signature": "ndgHemJ5qlwxgpfQ/6Y2PqFRNfOkS58jJC1up4gQ5ZYUggDBIVxYdNSqWscmvgpBZkz6IrIfUukO/JnZqcpJDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "192D17EFD1F6012E52A8833717D8621178168264", - "timestamp": "2024-03-25T06:14:27.21504644Z", - "signature": "n2jli5HiR7rDMEI36JqQvUem3RNarjPr1N0tqTQReYslCn8m9r2KRvj13WpaWx1nyc9bjF4/tEBhTmn3DUuRAg==" - }, - { - "block_id_flag": 2, - "validator_address": "56AE16561016ECD1B64540DCE711C588F06E2DBA", - "timestamp": "2024-03-25T06:14:27.204804746Z", - "signature": "SgF01ZGHIwwNjmyGYhSnzf6+xgTJRAozD2c0C76zCHnU7b3lo/7Xg29fJh4AZZw4c4ol8CstNBDh2CCcMSWwAg==" - }, - { - "block_id_flag": 2, - "validator_address": "3ABC887FAAB038EBB82506305FD928270AD2867C", - "timestamp": "2024-03-25T06:14:27.359862997Z", - "signature": "60Jc13MrHdG1zk2OFXEx39n0VfXvRD4rSvsu6gqNJ9FqNM+TcnZGN6nhLQFJ9ijFhqZhJwODI31B+zWJzv+yAg==" - }, - { - "block_id_flag": 2, - "validator_address": "7CF3A6E06DA02BF700E33372951EA2E95AF6A7C6", - "timestamp": "2024-03-25T06:14:27.243732794Z", - "signature": "uYOWyHr8KmR7rsrvgzKo7LJOvP0bPnzA0s3yVePxt6JlzAK+bvOuV1HJ6GBm7cg7BBhJQUzB5YUZbUdGbqwGCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "E89799B6440988A1AAEE14ADA7050FCFBCBE31B5", - "timestamp": "2024-03-25T06:14:27.28412331Z", - "signature": "oz0OU8f0jpbkMPye9psiy+qnE+Hpa9fkh+IlFN8u80Mgi3pB1ABAn4SAt08qGQu3eu/Gnuv21tWnDnmUpGo+AQ==" - }, - { - "block_id_flag": 2, - "validator_address": "E840B5676A5DA43F7ECA8385B461FA6BF0BE2CCB", - "timestamp": "2024-03-25T06:14:27.229527079Z", - "signature": "OY/V9y9gwWgKLgWPW6P4W73BPNAdcGR8KB+XnkM72My81/8NmzCh0F2OBysNRxYZ5qoV0TheXqc2WdVp2/SiDw==" - }, - { - "block_id_flag": 2, - "validator_address": "90FAA31CA9BE4E4BB8E4C9732EB69575F4C5B626", - "timestamp": "2024-03-25T06:14:27.251424274Z", - "signature": "25v4oL8wp+MbgxYl7V9LsCOvoohPeMejbim173bPKvmz9M8pKieyb5LoBO/9I0nHYvmLXuwLYTjj+iksIRy9Bw==" - }, - { - "block_id_flag": 2, - "validator_address": "CB8D061C7D78BAE099C50D6857B97AD4A9218776", - "timestamp": "2024-03-25T06:14:27.24295008Z", - "signature": "vUBPYARoWvUjAEqgp+UwXQSSmIGaW5Gajhi/E7PMOivzpY3trjjknomq3hzR9Jw4B0OQplviiJnRCn9voF/yAA==" - }, - { - "block_id_flag": 2, - "validator_address": "4630574528AEF5F2CE3BEA1BE9E092927E311F0E", - "timestamp": "2024-03-25T06:14:27.18719406Z", - "signature": "HwRudquc1x2MWz8e8a1B8EBhGYQIBMAFM24svk+SfjL/DMESJ2bEQwZvylYdNtRcuHsw6x17EfIHNuVNOAI3DA==" - }, - { - "block_id_flag": 2, - "validator_address": "B2FF86CCBBA2DB501E828E0E9D15EC14D50E0214", - "timestamp": "2024-03-25T06:14:27.191671125Z", - "signature": "y1shsVEvnmu7wPAcycLcpyqwsm2ZWyhpw/biuxFycx0/fhh+BlEX9QUIsJz1LDo52tPRIrbVNpmmTQ+9t4mBBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "CFBD265B3AB49045D2AEE7D001199ABD30BD1E5C", - "timestamp": "2024-03-25T06:14:27.209181671Z", - "signature": "IGfa6KghvryZkbonMVj/pXMQ6A+tsBDVN9OC1+KNBRl35eDe552hRjK07r1To4tMHM5+Fnz59a85ft7hconBCA==" - }, - { - "block_id_flag": 2, - "validator_address": "2348415EAAEAE89FE5A9412F2F45CA9AA5E73BBA", - "timestamp": "2024-03-25T06:14:27.348597083Z", - "signature": "MDv8yml9BxpRdKo/lTnhHfz/mCo9yeIEBbt5KjARvvTXlka5cwGwMW/hdCpNXMPqHqEv/I72mVQo/84tqyROCw==" - }, - { - "block_id_flag": 2, - "validator_address": "E4983569DBE9E32DC1C9C69CBE4DCF1CB82899AA", - "timestamp": "2024-03-25T06:14:27.242449608Z", - "signature": "43gXDvJMGoNR39pQdtx/w1moo3iGxEJM6CLxobXOx76WmtV0lT8izEqHXYOpPJFzd1alGpvmDWzFp7YAk5EuCw==" - }, - { - "block_id_flag": 2, - "validator_address": "F183805F63AD6C429B7157D90D7199F2075280AA", - "timestamp": "2024-03-25T06:14:27.205952311Z", - "signature": "ZotOXk+V0oh5eJFv0E/9l3oMnmLfdsrIu7+C1/Ufhl6W06g+Qx+FlGG6OcoJA4KKym/E7gLmkegZUKCz2B+DCA==" - }, - { - "block_id_flag": 2, - "validator_address": "5F647EE2AA22982E897765117160DA27BD8DD1AE", - "timestamp": "2024-03-25T06:14:27.21051342Z", - "signature": "SQuChlSd/54IYo9N4KAsUeoaXX21lD9Gvbq4tbSqa0QP8awWaav6S8pd0d5UN3Q5DaoJdgmP8JPNOWAowkNZDA==" - }, - { - "block_id_flag": 2, - "validator_address": "C6216B74B71AD3DD522E00D28BF1E7D7B9145869", - "timestamp": "2024-03-25T06:14:27.260030577Z", - "signature": "2ZBx8rLaNazZ93iQhmpAkYABtx424OfrXrDssBhZO3Cs+bO9StVeQOU06WXI0AQqtHD24Aw+Q5EqVAOBAWPNAg==" - }, - { - "block_id_flag": 2, - "validator_address": "31323915F9B0CBC60B4F371E454B5FB19B0AD26D", - "timestamp": "2024-03-25T06:14:27.296428597Z", - "signature": "gR96bGxmM/Xu5MBNPftimPjjgQDGagvG9tK4PA0UKARwf0wb3t4WspRcdv7sf8x05LWbx7CBb3DFoY5jcYA9AQ==" - }, - { - "block_id_flag": 2, - "validator_address": "90F0753D72B15384CD536B1FAE023BD7FF7D250E", - "timestamp": "2024-03-25T06:14:27.294846688Z", - "signature": "urgxmnMfREsnkRtkhs6JaLTnY35UlkabmVDFnmB3qGfOfDeVurLUcBWIe2pAdJAsu5NGqYiKhWwRjPlNxbSHCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "9417D3AA3F23E9D96CDCBA2045A07B401C1E11DC", - "timestamp": "2024-03-25T06:14:27.21561313Z", - "signature": "DQWOigfi6ey6I1U9VGIb5gjEDY/QKXtRqGdxxUVnAPlI0Az+QpHXQ3FzhMj6ChteqVWg/OzIpU8YencUPT0/AQ==" - }, - { - "block_id_flag": 2, - "validator_address": "38303246077ABA69E2782CB2C71C89DE9E2B7BCC", - "timestamp": "2024-03-25T06:14:27.273058159Z", - "signature": "ETdEehLafzgsITa1hBtEjKUcIg5SVPcrGUAmpW64Dju2AcfFoX7u0Hh8M3YW1JHb0ad0cZNC93q2Wm6NWtStBw==" - }, - { - "block_id_flag": 2, - "validator_address": "1D143C66358013DFA42A05A3BD9D00397AFDD6D4", - "timestamp": "2024-03-25T06:14:27.26998412Z", - "signature": "Xbhtj+DbTXVOLXc/eCszWFHCun34INCAn1OC9IxSM+pj261HVnUauh001rnFxzBjD52mxl7Wi2i4KoFd+TXxCA==" - }, - { - "block_id_flag": 2, - "validator_address": "8F41A1631BC7D5ED4915B673297D2F60A22C6E34", - "timestamp": "2024-03-25T06:14:27.208788012Z", - "signature": "vJts89t3tXLBb6LB/CF5UO1/l+gQP4teCQIOVj9Q3trUHB3SE4u1T9IPeQL5gblXTiwARrwkbccCuI0NUztlCw==" - }, - { - "block_id_flag": 2, - "validator_address": "8B714B0E76353D945D98D4974C8BD0B0748EC196", - "timestamp": "2024-03-25T06:14:27.233740258Z", - "signature": "hkqqwoCiTCNDURwo/9Pj4KqQ4cWKSnFnlqktW9wsohfmNdEZWjBCuFPfO7Etr2pfh0Cv5DVe7yTc5Sm4Nok8DQ==" - }, - { - "block_id_flag": 2, - "validator_address": "94B06CE54895A6138DB5D3E406E5914ED41445D9", - "timestamp": "2024-03-25T06:14:27.249889348Z", - "signature": "Fn/3ESz0Z8c79L37hKlyeSI3RR8ztarlrCmK8HLnU9CD7jaO1O9MJziqE56vATpHGAkDZEKPOSCbwJGu+cdgCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "ADADEE9B97C69600FEA8911323F3F5CB28906EE5", - "timestamp": "2024-03-25T06:14:27.399513013Z", - "signature": "Xb+eLvN/0KMqjCcYlq20t/gdR2tRf4f6p9w3IlcCseoR6F4p3RyHAV2RZ2TszcjUP8VYIAdCgukukIxofZhFCg==" - }, - { - "block_id_flag": 2, - "validator_address": "FD1E562DD7FA1296ACA834EF29AA0685A8AD8F33", - "timestamp": "2024-03-25T06:14:27.201830902Z", - "signature": "OMhImUqKrB6sbsBfDRcr5+F/+L4oNH8KuP+nBLmwp8RSXvW65oxMEyR/O9KqMtUl5Ib12TwI0BIHxNUWHDwaBA==" - }, - { - "block_id_flag": 2, - "validator_address": "A0212325DA0D8E777AA60AC5DA61DE409072726A", - "timestamp": "2024-03-25T06:14:27.208975888Z", - "signature": "nFEzQvXWCQzfQO1g7CAp5Qr8dgy2eOfF3WeWgcolIxq/2HSbLDO3uB+iIWMEkSTSkh9Zk/H1yCkeNfzMaFIuAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "CF65D933DAAD0646727C76795AAB0DE423B8C0E5", - "timestamp": "2024-03-25T06:14:27.216374782Z", - "signature": "GQZAf4We2Q3mKY1F8AVEirKOU/VXo/Ia1JJfkx0VreBDXqhAeJ0h/q64G7oXdw02Ed11Kc3CoqK7CtXuVAJBBg==" - }, - { - "block_id_flag": 2, - "validator_address": "80FF2FDD961F707F3C005A7FD41D55A74F076AA0", - "timestamp": "2024-03-25T06:14:27.224969374Z", - "signature": "tXcyjOQTYwoyhvsDhfAamhPjpLDytPKFsUIbVYeZO/hwmgnrZS8G6IH50gSS4BfhcMPQ6Bp0oRF0R8bBwldyAg==" - }, - { - "block_id_flag": 2, - "validator_address": "FF592BF088B8ADABFA6080AA820F7903F0F02046", - "timestamp": "2024-03-25T06:14:27.306082208Z", - "signature": "mqIIRczB6lyk6j5CqUK+VIun34fVFA/50fV6qcHZkJcCaYxZC+CKu88/KVPXfsCOHEEBxnvCC0d/AGpTPVbWAg==" - }, - { - "block_id_flag": 2, - "validator_address": "C5047A5B0C008A531993140151F3E54C1308A86F", - "timestamp": "2024-03-25T06:14:27.211417554Z", - "signature": "0qJEczrpIYdF8sdNT3p0gYivAFT/NeUvbml7mOkyDA/bsHGeXVDX+n5aLrkx/fYyqhs+rCB7bv23j7mI+Mn1Dw==" - }, - { - "block_id_flag": 2, - "validator_address": "43EAC69067530360F849375487ADA1F26FC026FE", - "timestamp": "2024-03-25T06:14:27.221068884Z", - "signature": "doK0ZlUgFFtnPJLgEXTp8W10EGXBBZC+u3YNYe1SD33W9LG4uTXfj0t0db4XsD7KIaZ7QWmdBP33ew0mStwKBg==" - }, - { - "block_id_flag": 2, - "validator_address": "5894E2D8B68C01CBC835985BADBF0AE378A5A6B6", - "timestamp": "2024-03-25T06:14:27.262841804Z", - "signature": "aQDifQtR7PY8mmujd353OZGJRJozbbPg9BpZP/WmjXQDLI/vuDDTMUJUfw0/JE9cDra42hnPQ5pf/8aarGWCCw==" - }, - { - "block_id_flag": 2, - "validator_address": "94A81ED9CF1EFE9672501231F0255F0C54A4F411", - "timestamp": "2024-03-25T06:14:27.213546159Z", - "signature": "SUpF6JTYtVLUX3QDVS5qNlSiJg8Nco3+3tO+XZ9ehfUFHqQ7hqchj4OFBHNbtF6KOZbolGz04ZSZrEaV6PTyDw==" - }, - { - "block_id_flag": 2, - "validator_address": "D78997B5A01D2D4E80C5189D930A14055002B478", - "timestamp": "2024-03-25T06:14:27.209686721Z", - "signature": "AiEAtstORITGefKUuruXaVLMV2PddgE+MvNgoefPNnaeTVRPRsgcMYCfk6TsLGDCkih4uTpGJIKyly/h1NIGCg==" - }, - { - "block_id_flag": 2, - "validator_address": "69C38FB90624F19356482DAA89E64D9957A37C00", - "timestamp": "2024-03-25T06:14:27.197381186Z", - "signature": "0zJHwlFfrnEX88Yhjwr7Mp/2UCaL66KY9K1H5DXwGjgBb6O7ozW5Ku36+RmT8/QFM+pQmQHUHf32De5nrpzIBw==" - }, - { - "block_id_flag": 2, - "validator_address": "2D63B9079FCAF8CEE74B072665A04599064BCB09", - "timestamp": "2024-03-25T06:14:27.187860932Z", - "signature": "FTIy7zamXLA6S/NzmMDHv7sy5/FGcIpChtLmNgzFhUz59P7uV2OT1RRVD56nWabrqCMOV6Qio1DEIdiptFoBDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "1AF66CF8C90E5D334FB095B4983210FDC2E2815F", - "timestamp": "2024-03-25T06:14:27.2934702Z", - "signature": "BmKsz5Lt6sxLRyv8UQDsYKuyTRJeuyG9NjAMzXgw5T1Da3Vx6EpRqhm5lY4ZpBzVLagXGD072Ix4q8Z56wV/DA==" - }, - { - "block_id_flag": 2, - "validator_address": "159424CD4756CBEF88083C1A11B6033423537A3A", - "timestamp": "2024-03-25T06:14:27.395386931Z", - "signature": "LP+S1UnorS51jwWhLUbepP/sgezYL1CJInFhR2c4oTc+k5iabeFofw04ZW/zQMNebDHXNF6oyWubaD2KnGc4CQ==" - }, - { - "block_id_flag": 2, - "validator_address": "C406A6BFB29F36979ADA959B917DD4A2A780E519", - "timestamp": "2024-03-25T06:14:27.299496138Z", - "signature": "7HTkVqMSkgQc3PqfW7twXSI9sIrkgwfyn16KML7y6gB677rk2Wn3YvVL2rn7JfC2Cnbj5PS17o53y7+76wY6CQ==" - }, - { - "block_id_flag": 2, - "validator_address": "92C0FD982DEC037B295494DC7ACF25FBB8E3EE5C", - "timestamp": "2024-03-25T06:14:21.339631074Z", - "signature": "9vtjqiTYXLoP6728kPDuJnt5Dq5cwauRcXs942pBJFw3go0TP2hWojpO5ljf9XqaUDdffIHqSsyclALtIqi5Bg==" - }, - { - "block_id_flag": 2, - "validator_address": "5883CB9214B4FE1A0CE68774D714425DC6024D52", - "timestamp": "2024-03-25T06:14:27.241979083Z", - "signature": "ILVsPy44TCgUW+VCQLazvEma7Knr/G9TgZF5UBHqRCkMu1loWS4WhfaLUeXYxWJ/oTzSt0B0eD1hoSYtJP3xAw==" - }, - { - "block_id_flag": 2, - "validator_address": "6C6412282FB32525FD92617157F154579434F9FC", - "timestamp": "2024-03-25T06:14:27.204271239Z", - "signature": "snrhUC6Qa3dhiQeIaI41CYAS41k91X544LpEnk24LHzEwSR0u9Qbrfum3ocvxfldTuC6N4S2URuGGIUfjU+0Cw==" - }, - { - "block_id_flag": 2, - "validator_address": "EEB553125D331715F799680FE763B33D4D8EC063", - "timestamp": "2024-03-25T06:14:27.233977273Z", - "signature": "gctjdRc+zF9OEV3xa6X/cjIaOoOVyOwWwumCbbomNmlv4VRyi6ctBJHVHtbrnampkDdT4EF1jwRriAznffzfDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "DB2D66F06C70A06818910685E8A51C73E6EF3324", - "timestamp": "2024-03-25T06:14:27.226749145Z", - "signature": "BIOK4yc3z8qjpeFyCAQ9deVWFd+N/JWBtyJCM3WoP6oeaCdImZlz1GMZpFdu/q910OlJ5ovLeVEPgKm2ygYeCA==" - }, - { - "block_id_flag": 2, - "validator_address": "07F4F6BEAC490B1508E93E38D9E5B3DC50716200", - "timestamp": "2024-03-25T06:14:27.325335199Z", - "signature": "PngsVhXlpeFwn/0SxHolgxNkKH5lXWkJKskaYJ6XlexUPImbJNT0dbHoWGqeMmaaHONyhvTL6rJZgZ+/SJtvAA==" - }, - { - "block_id_flag": 2, - "validator_address": "32F529A962B3F9D7896BD858D9970E3C1392570E", - "timestamp": "2024-03-25T06:14:27.435809271Z", - "signature": "P3b/VPqrxBgxf1uBMd+3oNssgAWvzJTYzSHTL+msiTEGNvXWJWO/iuzds59daZO5ZktKHLeebX/8hSO0LHPUCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "223BD658ADC0BE9E1A318EAEE26A927E9B782DFB", - "timestamp": "2024-03-25T06:14:27.298543778Z", - "signature": "22Ci/5gtqsUekp6U1XIPDU/6a4f9XJNuwPu5lNuU2GLcAeW5ztZqMHphb4kT0AHGdn04g41UFlKGaRMUmybbAA==" - }, - { - "block_id_flag": 2, - "validator_address": "B155936FBF30A4A21C2FD9B2A3CC1C2CACA9DDE7", - "timestamp": "2024-03-25T06:14:27.314051454Z", - "signature": "6DoBNRasJfqp5eTsWkX99hSTtq8aFYg7h1jydaYpB5DQAL/J5Tie0w1jd8gq981rZBOVUgfNuPkpl7OonwgsBw==" - }, - { - "block_id_flag": 2, - "validator_address": "D0810844A5202004AE1249CE17610A4AA5A1684E", - "timestamp": "2024-03-25T06:14:27.504915992Z", - "signature": "yB9nGNImbiz1x/fc/wMEnmbT5vahaPEWolorzE35PhOW+JveeTH5wXVfc8V2+PKIflFPn2ftbR/j7Jvns96GCw==" - }, - { - "block_id_flag": 2, - "validator_address": "0C170D04155D212B97B3D33AD24D0076053E70C2", - "timestamp": "2024-03-25T06:14:27.282067495Z", - "signature": "5S/h/C2XHP70XYO7WXAzOOHZCz0eyO+RLNO59c7VVfZcPloEomvwrVlyG+UOL1cHV0BxTqHOmy82+V0TE3tZAw==" - }, - { - "block_id_flag": 2, - "validator_address": "2859D4F84CABF0136BEAF3EFA339F5BF6F6CD39C", - "timestamp": "2024-03-25T06:14:27.229881613Z", - "signature": "GljjGBNXjaJdU3yObE7h58jJwbCoAoNLMtjvpMYG/UHtrk3vBvxiILksgS3nKxXnLYv+8UDqNaM9BYRs3cKlCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "195623E1DDC7F85D8E5015D79B9D0DA47A7F59C2", - "timestamp": "2024-03-25T06:14:27.238487848Z", - "signature": "UFjUdS/aJgk2DPWC/BJKgMmqIuGGQMrNwdAdLFKcRjHfjNmBS2JanaSt43Hrlrpha0USzAOUYecVp8Qnif+8Dw==" - }, - { - "block_id_flag": 2, - "validator_address": "7B0411064960AD679FC4A64A7066B401DF3C7F52", - "timestamp": "2024-03-25T06:14:27.294517354Z", - "signature": "xuSuad88AM2c9Jp3n3Q/tERfFoZrxBPv0I59ZJl1rLvqPE3nZBOuCBMwZPUCEa9136QsNfpXEemt/4jlliN5Cw==" - }, - { - "block_id_flag": 2, - "validator_address": "8066E3C72BE72F9CD84439FFB59D79B2C316C01D", - "timestamp": "2024-03-25T06:14:27.297025738Z", - "signature": "SsE4E3QYw+1rk9uhObCu3YUlHQSoREfMeVX456rSeQLhU+Lppat69YtxnG4FWGeBBzgMZ+jg+s+GyWhVOIjDBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "8CB1BE337D1427136EB8EDDD9232735E2405C50C", - "timestamp": "2024-03-25T06:14:27.248658018Z", - "signature": "SOO5yhm/Zs/qgTMYbId1yn44P4Bo/88BtNvJBEmziJeOwrpwV0So5q1FDQ2pK+ddAsc9ampt2pIA3gdlNimgDw==" - }, - { - "block_id_flag": 2, - "validator_address": "83CC77F0F60F418B9DE2A24642645777D2FBCC02", - "timestamp": "2024-03-25T06:14:27.254563507Z", - "signature": "aEt+2hSYgJibHGrvCK47cq4NOFSYyQR2lBn2qK7V9KJSRN0ccB5Bp/iM/OyhlJ7PrLOWanQghCqzotcQQb0KAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "D83516A8B94EA1DB899B7C80C76C05D0BE204004", - "timestamp": "2024-03-25T06:14:27.250738609Z", - "signature": "20E5FZHX7sCgykdz7wpaMpt/xCCUPy/3joMlb3vqagUT1OqVgFj5IonKpFPz8WDcZCDv2CEAjc2qzSb0zNAYCw==" - }, - { - "block_id_flag": 2, - "validator_address": "DBDE432B755C38F3136A75D2D3F530B5A74FBDF2", - "timestamp": "2024-03-25T06:14:27.226292884Z", - "signature": "OampF/a5bMIBndboMuM+rsJBoa6rDS1AKYQLf4QV3elgVSxYBPaWh32NGzKI0FvKtfNCo82GiWNyKKvBTXfiCA==" - }, - { - "block_id_flag": 2, - "validator_address": "8F9C9F4EC28C7E06F3D348394270FCA69DBA116B", - "timestamp": "2024-03-25T06:14:27.294859322Z", - "signature": "Aid0oQvPLKP2Ab78Nj2jnw/2TVc7ojnh8oi2q/dETrip9eEH8XSeQJ9+bKnFU2oKnmcK1FYkKwGzi5m2EfpEBg==" - }, - { - "block_id_flag": 2, - "validator_address": "F9F61FD65FB010A8C9365032D83CCAB9FEF69BFA", - "timestamp": "2024-03-25T06:14:27.20862173Z", - "signature": "Raa83ztno5967q1aeVw+SKas6WPNJz0xHOb3z4fAxrAZemNR5rkrEcBK5Dah6l8nQ70m0Y1OYRUEV1GE93e5Aw==" - }, - { - "block_id_flag": 2, - "validator_address": "02425C209B7A5BFDA29FEEC5876E12AEC64D4C81", - "timestamp": "2024-03-25T06:14:27.198883431Z", - "signature": "aFf3eD567PWOwcSWeKXFD156lM9AngvM6w738tUQGj9sI3sLLj+qHFDe2f54ZDx3ybBt01bpvk0Td1isEDhQBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "37CBD9EAD6B6632851646323C2D9127E79B1C37C", - "timestamp": "2024-03-25T06:14:27.250703418Z", - "signature": "aslqoF8TjiCalfO48S98TW5mdfUZ1IP3MK6JWupdwxaVwcEhDcr4wffSK5nqXSHdPhdFmSJsY16jN+4YfyCeAA==" - }, - { - "block_id_flag": 2, - "validator_address": "1DA762F8A91B63B90817D5D3A20D0A3E8CB240C9", - "timestamp": "2024-03-25T06:14:27.20908433Z", - "signature": "9kdJRK8+r0RRZ+q5eQQJPaP+17PKYyImLyHd5XOJqWU4JKS93eqQT6JHKJnTBGo0WAubVV90PI9DvgiWNtrpCw==" - }, - { - "block_id_flag": 2, - "validator_address": "012ED7FDCAFD53E87DBC4F98DCC93B73E30FFA2D", - "timestamp": "2024-03-25T06:14:27.270230258Z", - "signature": "gqwtVHmUbqy5DRDGg6eJjFS4nQgWmmM6e6t4Yx421IF/8/oWZeeMcjjFzlMxX4NonrEB8VBGHvY9hKL20/r2AQ==" - }, - { - "block_id_flag": 2, - "validator_address": "E27C9D446FA6A9CFCE43802136CF958E7F939226", - "timestamp": "2024-03-25T06:14:27.216205479Z", - "signature": "PC05d40CuIxreCOcSWZ4mLm34hTYPWMMpBdcSHxOsQ/IU3MLP3PTikl8j2ugL3umg8OCxnxT2ef80z9df388BQ==" - }, - { - "block_id_flag": 2, - "validator_address": "0B854339BDCC14B85FB8711E41C2942377476F70", - "timestamp": "2024-03-25T06:14:27.209033257Z", - "signature": "l95YxnFCwAt1QuqXomDAkzc1Mo6R9j62BHT0tCSpj98rm6PCjsfIRvEP/+j+gQEqB4jJvqq2U6ZYosm3950NDg==" - }, - { - "block_id_flag": 2, - "validator_address": "ECEE73D95A77E41A4AC3148D75BE7AEB02CC147D", - "timestamp": "2024-03-25T06:14:27.300665187Z", - "signature": "X4XT2w9MkSXRn5NDElBwstWc9nhGGh5NJzO68WUXbZGH87DJlR+V2NdEtYz1/2gfaHw2DH1CLbVN9O9xL0zZDw==" - }, - { - "block_id_flag": 2, - "validator_address": "E3DE542C5573C78253BF5DA6F20E2119C0F1BA48", - "timestamp": "2024-03-25T06:14:27.240320031Z", - "signature": "HeMVDGr5kMtKJe0QRFy/CR3CcfY/xzYb1zawQtvfMb2G7gc06jJ4fd+4OM2JjUrZzG8W7wNx9EWYBzg3wHtwCg==" - }, - { - "block_id_flag": 2, - "validator_address": "1A0DD1BA9B3EF21F6414210D0AA35EE0F9A12BE0", - "timestamp": "2024-03-25T06:14:27.248713782Z", - "signature": "Q9bKIijvXNhhpTJw8GYCn4L6v91/pU6Zc1DjhEofzSkQCzn514glSpn6xs+WQxZw6br6Dn35k42jkdQ8fdT3Ag==" - }, - { - "block_id_flag": 2, - "validator_address": "3E01DF5EF729ABFB3CB4E8CBAE5062D685009FB7", - "timestamp": "2024-03-25T06:14:27.216058329Z", - "signature": "qUlOsW7hLc4RkBFDR2vSqGtpqRsaY2S4c0kr5qgR0rdCVwfOrkVjhBDrtM23nBiRmvzffpsYEUZm687WXmrgBg==" - }, - { - "block_id_flag": 2, - "validator_address": "10AC1B41D924B67539EA8D755FB0158D57B0F555", - "timestamp": "2024-03-25T06:14:27.260938966Z", - "signature": "QG/5BZ+4eq7sJkbrSeiQf41c+yZqbKanwFkIYGD/wiiNMYEhq1b3iZwS5bJKKRLb4zGprDKQ9vaohyN0eSdJDw==" - }, - { - "block_id_flag": 2, - "validator_address": "F5EFDE8E7BF30A548B847ACD250407CF0CC0539E", - "timestamp": "2024-03-25T06:14:27.211301742Z", - "signature": "1fdvlOuPcdAzrMFJxUgUGbRqX8OP1pb+PvxBUFGqaIFtxn+juxFXF15fvHiGjzG+MSF8w9SDzWjHBM323+0ZDA==" - }, - { - "block_id_flag": 2, - "validator_address": "E42A113076FE41D20780BC6F2FA1C700B2756193", - "timestamp": "2024-03-25T06:14:27.304878958Z", - "signature": "LiS/Ncw9LZpOZ7eSxl3mrflu4EFoK+92+81btwv8OH1112OLCcuoUP8FkukKyD2A3eP9asEmnFoGYecMxU/YAw==" - }, - { - "block_id_flag": 2, - "validator_address": "A468764E5AC834870F79453F1CA26060DEBFA629", - "timestamp": "2024-03-25T06:14:27.232074527Z", - "signature": "owk9vcDs3qppskTOF5ukfV40YvWd3uKT2O5OpB+RkvUhsN49HeUCBN+twoNN2yE99F2M0SEitXRdKD/0rqQZCw==" - }, - { - "block_id_flag": 2, - "validator_address": "7991CF87E4FF6C6D46376939E6E7214FA7473AE0", - "timestamp": "2024-03-25T06:14:27.24642099Z", - "signature": "5ekIibouYY03U0xtyEJH3b2DY5rBsQmmujd4q+P/Hz7Hu6fjqsDVe5r/w5Y+SyJW4Dpeu3IUBlHRLtMdWrU6CQ==" - }, - { - "block_id_flag": 2, - "validator_address": "132A20818488C9362C9E37E529B879CBCD6FBDF3", - "timestamp": "2024-03-25T06:14:27.252922227Z", - "signature": "6XS3kXciqm/vyY5bILQ8+OIqNitOvmjcoTFECvuSwxQXonh3oLl9qDYMetl6TZzBfmWxOTwrvETU0YKanRP1Bg==" - }, - { - "block_id_flag": 2, - "validator_address": "4C10504F2614BE17668FB7EE4CCDC9BDBDC5E94D", - "timestamp": "2024-03-25T06:14:27.198949987Z", - "signature": "x0mukdGORqepq+INtUB8sifZ0EtHqhzXFZIgA1OMHyMEx3vg+m8qHdrxjfbN7QQcdkJGblG2UO9EMjQO5Tl6Bw==" - }, - { - "block_id_flag": 2, - "validator_address": "152DBAD504AF9B1C103D3D4BBBB472C45758F301", - "timestamp": "2024-03-25T06:14:27.301151981Z", - "signature": "JJ3DoJqBz2YjqdYElJT39L+viwFYy+svDpzgRBCflUGYDy41YyejvI7EoN21M3AbRylYVQrR3kF32aTvccTxDA==" - }, - { - "block_id_flag": 2, - "validator_address": "2191940572E2B2E4F477DA155AE95FA3697AF3D3", - "timestamp": "2024-03-25T06:14:27.222339495Z", - "signature": "RCpNsDllj2GCQ/wkgPlXPMB4a1b52U/kdFlasvR84uaZKhbf5vZKlQTlNMRk1UQ8OEduRfWuUUuVAnc8te+ICA==" - }, - { - "block_id_flag": 2, - "validator_address": "AF28D38FEA9D6F1A8559AE134EDA0F1FE1509768", - "timestamp": "2024-03-25T06:14:27.2892123Z", - "signature": "YvuPNZ2Pop9TeQjP231tgShezvdoIYj617baGJbRBfNxnuxzU2ZuouJOO2AtTgOr3yxxLmuntl7j21OYUugCBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "8D0008FE0C7A6EE7BDD1D59CAFFF96AE369C303F", - "timestamp": "2024-03-25T06:14:27.318615916Z", - "signature": "TMQnpCOmCG/XciqY1H1X+DRZn9d9a9ODBOgZAmGY1z98z3Le6ftIOtV4nBLNYbOw7JscKCy8HMTGOfUQTB32Ag==" - }, - { - "block_id_flag": 2, - "validator_address": "88102131B351CE7719EED9CADB15330217A9D038", - "timestamp": "2024-03-25T06:14:27.239020415Z", - "signature": "94mJSDK5AcChfp2Rs6w/LCl2Oa37J+S1wuqJD9MNDsSv8nx3ysxh7QkBqQrJmlO6z6zHQUw/H5frCFsAXqy9BA==" - }, - { - "block_id_flag": 2, - "validator_address": "9C3BFE7B68E53DFF9D3CF7B70E3B8115AFD42411", - "timestamp": "2024-03-25T06:14:27.402701022Z", - "signature": "8Pk9YesjiQUC9bTxL83CeDtofxEm6YesuPWfN3luxaBFY9crRetMZq6dVizo/lJz/teN2uLlVaKK4wmlivapDA==" - }, - { - "block_id_flag": 2, - "validator_address": "39BB490F1B1554AF3FB524CC89D1533EC5A02E2D", - "timestamp": "2024-03-25T06:14:27.203968116Z", - "signature": "tNL9c9RvIDEZr3sxrFzxxuzVnGZLFGNFabqtyEhDGzYp6fRtXHtcLOWkZoZVTBZsQ9TXRGADsNhxJbcTElenCA==" - }, - { - "block_id_flag": 2, - "validator_address": "750CA8CEE4ABA1CA93D1E0A524F26DA8A64EF7F7", - "timestamp": "2024-03-25T06:14:27.23364418Z", - "signature": "R318nz6/+S8PoN/2C/wHiT4zQdyqe5PlPP0C0ArZJ3DnK1NfM4O073tWOcQ/CTh24690+xhWRjOx32QfduEFBA==" - }, - { - "block_id_flag": 2, - "validator_address": "DBAC8BF532C03354ED8BCA5FB7992EA14C1B62C1", - "timestamp": "2024-03-25T06:14:27.263448028Z", - "signature": "1NFURpxVZOD3gXu9E7Bg77suvhIeJg6D5i+fVUTReoQnE38aJJwfCqrKPpnzkDOycHZlkONg/VkfMK0Cr5oVBg==" - }, - { - "block_id_flag": 2, - "validator_address": "E7F7CE3DC63D23B2AC7A233A432F8C7ED74B23B7", - "timestamp": "2024-03-25T06:14:27.192866526Z", - "signature": "n385e1IR/y0OfFgT/8284XFo+DP7hLA+LvNse0IhMnpZQpfn0z9Zwv5a6S16pcKGLtGcSS8bmTMgmifHOBb1Dg==" - }, - { - "block_id_flag": 2, - "validator_address": "23D911027C3A30470D63EBC2EDA4D71C91412543", - "timestamp": "2024-03-25T06:14:27.318050596Z", - "signature": "4ReDzyty2bN7bgbm5gqa+oHxL4oaxDzCOjqUIsbutxk+ydUQVoncqEbjVwn7xT69k6R5ZiHjzVrslJdGO72sCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "4B71B41D7DC82C7F44FADB7D527011678B14693D", - "timestamp": "2024-03-25T06:14:21.339631074Z", - "signature": "IGYRX6oOdKREREx+EmWDVYy4w7qsg3oaganYXH26V0S4hJLDb+ZbCDwIb1YNaolm2ASnA8ebbSf3eVwc7IkRAg==" - }, - { - "block_id_flag": 2, - "validator_address": "3A0C2AED56A4E76E52616CD336FBC311B3799322", - "timestamp": "2024-03-25T06:14:27.250498816Z", - "signature": "E2g6oC0ASeqUU8lUNRjGTkq6Nh7OjzjHgJAk2w9j44Xfl/iY0h1XClsASLOYBU5mi0jcwHtNGDiSebYszwhDCg==" - }, - { - "block_id_flag": 2, - "validator_address": "C071D8A87D78969620BC2D1AB55DCE5B683851ED", - "timestamp": "2024-03-25T06:14:27.217216828Z", - "signature": "/UaOablXzYlqttOw+DpJleRa2RbkOlFL+810RkWnMCN/kOKfaLXs283LOVVXcpfq3FL55m9/Se6WVysZZWoHBw==" - }, - { - "block_id_flag": 2, - "validator_address": "180049B647B4CE71C46D70E1AAAB869B2114D0A5", - "timestamp": "2024-03-25T06:14:27.276196465Z", - "signature": "0aUNZyRMWarl5PmjBpFFoZC0NQDIc9DWiVujKc/12VRpK7q2B8pmTRazKSKIPpCHyhccGuT8ZCnmzNXugG9fAw==" - }, - { - "block_id_flag": 2, - "validator_address": "C875B64A69611343F68BD7F1B81C16F971876720", - "timestamp": "2024-03-25T06:14:27.201976056Z", - "signature": "zt1C0dJQ2VM5LbntMfBNlo4FG45DoAJSydKY+siyF55pqdsxG3QW8lZY+QS/xNIDvB1zLce2d2pKNnqXiYmvDA==" - }, - { - "block_id_flag": 2, - "validator_address": "B6411041F5AA0C6E38612CC8E75BB70E74D0704E", - "timestamp": "2024-03-25T06:14:27.232543158Z", - "signature": "Q7HCCILuaWqAyYvcCLZAJ1Y0/K9DjXK3vi2ULYnBPLAUIMzK+6Vpqlf5qKwzyAyOJmFvg/iyGQp9SUgmTUunCA==" - }, - { - "block_id_flag": 2, - "validator_address": "ABE6553C7FCAB8753E1E2E0FCE046473F93CD6C3", - "timestamp": "2024-03-25T06:14:27.243673233Z", - "signature": "7jeKeynSTUFmxYOOWPXATSiL0Cw8aNY7zqyNqULCWANXBjrMIOOAFQi4MsUUxycX5fY+1bgWV/MWZvbq5UqOAw==" - } - ] - } - } - }, - "block_results": { - "height": "3856726", - "txs_results": [ - { - "code": 0, - "data": "Ei0KKy9pYmMuY29yZS5jbGllbnQudjEuTXNnVXBkYXRlQ2xpZW50UmVzcG9uc2USNQovL2liYy5jb3JlLmNoYW5uZWwudjEuTXNnQWNrbm93bGVkZ2VtZW50UmVzcG9uc2USAggC", - "info": "", - "gas_wanted": "484467", - "gas_used": "403673", - "events": [ - { - "type": "use_feegrant", - "attributes": [ - { - "key": "grantee", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" - }, - { - "key": "granter", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "update_feegrant", - "attributes": [ - { - "key": "grantee", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" - }, - { - "key": "granter", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "436020300000000000aarch" - }, - { - "key": "spender", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "436020300000000000aarch" - }, - { - "key": "receiver", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "436020300000000000aarch" - }, - { - "key": "recipient", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - }, - { - "key": "sender", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "tx", - "attributes": [ - { - "key": "fee", - "value": "436020300000000000aarch" - } - ] - }, - { - "type": "tx", - "attributes": [ - { - "key": "acc_seq", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4/16618" - } - ] - }, - { - "type": "tx", - "attributes": [ - { - "key": "signature", - "value": "BumjcrR0vVFIKuVEKGTGEiunbHUhBwxCvRP/Xx1ZSstpmRuWGYXspOe1yhyOtjG3hGpDu21Tj4Pho2sPDwqAwA==" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "action", - "value": "/ibc.core.client.v1.MsgUpdateClient" - }, - { - "key": "sender", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" - } - ] - }, - { - "type": "update_client", - "attributes": [ - { - "key": "client_id", - "value": "07-tendermint-70" - }, - { - "key": "client_type", - "value": "07-tendermint" - }, - { - "key": "consensus_height", - "value": "2-15581441" - }, - { - "key": "consensus_heights", - "value": "2-15581441" - }, - { - "key": "header", - "value": "0a262f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e48656164657212c5a4010afd3e0a92030a02080b120a616b6173686e65742d32188182b707220b08c0ac84b00610c79bc8022a480a20922d44f2f302a137e504e1e13c5db35bcaee72048cad6c938c973a3a88cba31e122408041220e3a4c96bfb381a352849de7f701d75a65756fd247e2b66bca84c0486bade38b93220ff89aeb30b95970271355e66c5cf6f5a3759b8f98140b304e229da94be82aa2d3a20b00698a377c95210ab27810302fd90a4b3c92e7965e6e6ed0787d3f2740e2d1f4220e8d022f1af4597974007b2d1bb08b67c53b16a751b6c7c7f110adee60a6b433c4a2017bed346ba6ba721b8eda75e77e94874c944bf1a5c2a09b047ecbe62fa4d293e5220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20360989c22a580cf79524f65c84c33c84a19b148131ed545a8abbecc4f4cdd883622092ae11933d53f4bcf0f988bf0ded0a23182ef48b2b9737d9aeeb1522e044ae6b6a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572148fca7539afd32000bf2c928fc69737483c49b75b12e53b088182b7071a480a202aba4963d64d21e23de083b5628fa44af519509483a780126e8f683be0fcc4d9122408011220b8756df795d8a350b875893cc8d125dd48ea6a89a8547fcf44b81a25b5a3a6bd226808021214b1852d17fa66b5382a8f770725cc5b228b3577501a0c08c5ac84b00610cde3c89a032240859df3a1a0bded57a0c491cb2ff75fa76a9a7483d74105c558cbcfc6f7892f57791a8f3bc1f142e916a23ee75a3bc03f314b8b9a0d7bad967a3e351f21f844042268080212142abc4854b1a1c5aa8403c4ea853a81aca901cc761a0c08c5ac84b00610fb96c2a4032240cb64bc7eb090214ae00aedbe9752e66f7997fce1933142b8a7949ec747dcdd89e8e8d0019bb720344def6d4dff02ed0f176059489101dcb4a1792600d7a40a0322680802121425b40fd5ae2ac26b4382b746f6cddb8c73ce60251a0c08c5ac84b00610d1fcf8a6032240dab2c9cce83842bdce9d53819555f416f29077b0bad03d7f656c1ac3dc4ad3bc6c357d556eb9da5223f9edd47753804eb6f04a6a84e8745257edaedefbe5bb05220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212140549633adf0dd5e91ec75458cbeec35ae4331ad11a0c08c5ac84b006109189e1a3032240fb4af079d53daad6894e66eff8f5d8be255e30b59407ebdf106c66f004cdd5943b0cf8d22d088047d58be23dc5e39cf29615659aaa0f5f2f29009dd6ed7b7408220f08011a0b088092b8c398feffffff01226808021214fe1d612fc9c346e51fa20ed491ebd81162c0e1101a0c08c5ac84b0061095cacaa903224012903fa5ab2717225df16e12c51e01335c54fa5f6baf5e81d2bd273c9553e201799687f10f844067ff94683c05a51520766b2ac1993b6102025a3e632dcdb604220f08011a0b088092b8c398feffffff0122680802121439d8e563c1af1285095ff5bee373e235d63d0cae1a0c08c5ac84b00610df94e7a4032240d321a1c03391bcb663c0d1483015cacd1d82a30158a88b5a7e16e09dbaa0f28a994ad1ba549846994927a8eaa26cbfd3485a1c223c9f2cc356d404ce48f65d0922680802121459835dcbb6ce79f1d12b86702e8690e5f5c514e51a0c08c5ac84b006108cb3a29c032240502a742634bb3dfaf9698a12b679b9c5a376529d28c0bd96543a9f97b39e64ba67b45e025ebe7f69f295ad2c571f5b09f29f01ffc973877f8db84ba8b45f830a2268080212147bd85b0a30cfae183af900b65bc0ec0a28063c991a0c08c5ac84b00610beabdfa00322404cee5b1f3333a536b6a2ee8a88dab1bb8f9bb96a7adef3017d91bef73e4ee68b7cdcfb17a9a81c22072590e0751b3f1d38dc3c85b266ab7b27f015b180d2ef012268080212140218a7a051c04fec85b4f92bfb00a8c4da1a9bd51a0c08c5ac84b006109d9fb1a4032240e065dbd8ba81c1edc4b734364cd4508e1e13bf635f55b0cd960ab638eca7d0c4ee9bc71add507465589417cba9743b7a36eda7b762bf39e80fe450b25aedcf01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214fe849f301b09dacebd2dce15d3ca34d6ba4ca4731a0c08c5ac84b00610cfe9fca9032240de372dbf43b1d6eb45f0d7c7b883e7c6f12d135aa048d6d6591606bd612b97dee6d39c5d212f71d5e53e27b583dd7380368f40f1231f24f1ef749d7a3dfa44092268080212142d9790447341f3371ad11b4b706332313cce33c31a0c08c5ac84b00610f49eba8d032240c4d9b5c20c4c6f1eeadcd03276fe835d71d0f671da5922755156995b91c9e5b484c3e9e3f00f60fcf0832c54a73792d14b6744f7a70ec2c64689008f88d47e0c226808021214dfe3e4385652c2f176ebe59c3dbe4198fd30da901a0c08c5ac84b00610f1f88fa4032240905089e3124740c3af81f36139a014193d6409a7302f1968113156df7f8a84dde0b2da23a6d407c4c0b73db858a0d6a501128545fe81b76239ffcdf61af55709220f08011a0b088092b8c398feffffff012268080212148fca7539afd32000bf2c928fc69737483c49b75b1a0c08c5ac84b006108dddf6a403224072b6a0e54c29d81467082fdd2509e2956f769fb6abe7c8bf84264504f36d3b7318cf74461e70725aa1cef8b219a9c97d535728a8add54fd835e1d6a083a5fe07226808021214eab91d7b40213e14e850a90d7c28e662466dd7c61a0c08c5ac84b00610c9d3db850322402e6bff1624a5953964863100c0d131ed93497c893d3bc967bef501846941e89259b549de34ea6d0cf83b1e72f483397ea5bb88e4f06b1f096f76f6d1c18ac8082268080212142bded3e9a310eeedfb7d4db1778a9413e29d97b11a0c08c5ac84b00610adb8d1a60322407e25144dfcc7af4f7fbbecba576e504a739f7148904c38e697fe5147e5a6d52d701b04b32e133662e2eb89a777a4e84eadd465edf732bec01a3b3f42a4ac040c2268080212141856685db8ac33cb29b9b1d35c034f16511d48501a0c08c5ac84b00610c0c6d2aa032240d7aba48b01d06f8a6a9d99a414e9c09703fbec6a1d1fb933ce4feb17034b1a6786e27b379399403ae69a30f0673a2e7c4fa8f6753a15726529d81dedd0f35704226808021214fac8f77451006668f58b8937a73ae86aee68e2531a0c08c5ac84b00610b784c99a032240a70c848545d669d2e8ea4e9c9bc57ac15fd5b008d8cad2241c5f32e14f44279232874ec8689e121e57b48a79e8d3ce952f4ac3612f486f4939843d7d1557b404226808021214f8bf2150619f6d553ec0ee4427e09ae4cf085aef1a0c08c5ac84b00610cca5aeaa0322408b2fd4a1d57abede09f226812790555a95d3ed43c1ded2c82bb6b424563ff7b554538fa4338e2d9ca7e9432fd1425d70f6f16ed5f802b011a926c1cd384c3c08226808021214ebaaecf31ec18dc4234e01c82b749ae2cd7a95771a0c08c5ac84b0061083abb0b20322408e624290f7816ef1552e51cbe6f94cab4c113276b8ad50bd2280408f9e3e35b4e400677f8db92024ce9fe0d777bb605be7a777fd3fbd76223daf5b83b524da09226808021214c3c730090bf75fc5bfdfbb4bd26589cf1c7b74871a0c08c5ac84b00610c9a6b7850322402fffe20e969254879e78defaefe87a43efa3578bc3ec3727f31667995bc5ee239fdb7a3334a29d92bc3f247c06059fcd8c05b522c71772905f9b7bcb552c7103220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214706fab402d748242cd0a22b49012a6c039feec651a0c08c5ac84b00610f6b49aa90322405a598006423467706d4806c454bdc8e101bc58ad24286bec38964c29447767f93e0b3fe8beca13a9ee57935c05cd01b536282a8e23c1fb7e96723795dd4a5007226808021214b4fd96d19a44fe4b6b05370f200d89251fb68b401a0c08c5ac84b00610f8fc81a50322402c23e85d098e4c8efb6c3dd40a0b52dcf5e47e1a226a5dbaa0482032253732b0eb59de81a8c2e3b8443697f94c71cc6e2e577367ca4b711b6bd08c332f6af100220f08011a0b088092b8c398feffffff012268080212149c29fe719923138d4a27bde5704563e45afc705d1a0c08c5ac84b00610ca9fecaa03224039125eabe6237dbcf691370a9ececacc1b38e5204ca9654ada8325631bbae9741f6c79fd4694cb0bdc461f26b97ca82b7970a5a21f83bc1497787f719cd12c0c220f08011a0b088092b8c398feffffff012268080212144451050fc63430d28fedd2a37f3ba16353c7e60a1a0c08c5ac84b00610809893a70322409fcb186b8cf687398b6a3776f57dd70f7146a4b0be0ed1523ff577be61ea10460fb1eed891a7ad5f02802b9ce018d6cda0f432199e661f75ea27b161bc547f0d226808021214a6e68f4720f047480f3bee8502304baf0faaa7a71a0c08c5ac84b00610ece1e5820322408870aeba3646534181cd016e7631af3d0c486e8822f67ef10856609557fb6532afbd775284f59a50af6b2869b7ca5cb5da0b26f36e41b7f4a3361371750a70052268080212144249abbc6cccb87ef36b481b3016ec33912901891a0c08c5ac84b00610a5faafb3032240a834a3efb9619ac1db9685bbc521baeb9813d1dad7682fcf006cd58c2ef45c8eacc9b9385751913a3e98951db1b1398dbc91f66cbf17a80814b15a0e2824e409226808021214c3266367ddf27040547dc92d5ebb1623caf2903d1a0c08c5ac84b00610dad3ceaa032240188e056696305f22a67d9904a067f0be7f87f1124ade527ef5d3060591379dba30fe57fc4aadf802104e6a2ca50f6a223f867c0fde5de2a7bb24ec21ccb3840422680802121483ee1db3ddc3112b91ee8d6e652cd5eef38c46e01a0c08c5ac84b00610e9db958b03224058a25bdb113d463cd40e59db67510699410caeb3bbef857db839aade920089259d4e941056c92e580295efec5ba048c8ac9a55d50d10de70276527cef1c3d50a2268080212145e56a5d935a9529b8999e1291c64b0ba3f9fd6631a0c08c5ac84b00610f7ac85ab032240da8b69eb538c660dbefb1efd4ecaf28d57867597666b1b2f6540c75b9d536c1484d28c6540f5c485b4ecc20b47f16631ebefd3375d7060fb1c74cba4f4d4e100226808021214fed8e547546670aa5256f64ea16d8bf1a340a5a31a0c08c5ac84b00610c4828da60322406d123b9e2f8162ce671174e124cb77b5f6ac23b7c540b1fe3c09f1dd38a700f2b43d2653c036fd3332e74484e917862a18880fc49c9a4590173c91bc89126a0f22680802121438fbd1eaedfbb5791314bc0661e3b9d145074d901a0c08c5ac84b0061093c98085032240af406ed28fcdbf4f6e1ad92519b72d170dc22bfc82771efd350780df40526811fddeabe3793007ef978b631bdf00ab7161833ca036d143da4e638edc39d80e0922680802121484b7580e977f1fd0448c4cbab82a7d3719367d571a0c08c5ac84b00610eb8d86b40322402f1a1d6f8af2949868ad0bd77365c4f6c24350b676882e523936a47faeac781fbe6d53222f6dd042a78423b7e7d2d3cd90ddb5fb6ffe141f8bae6ad2a70c930d226808021214c24fc0f3780141b5124c8a3bec39de645fb385e41a0c08c5ac84b00610a3e9fba7032240ef1ff6b813753376af4b67e184ee3fed97431a0e5c5696a99cc3a09e336ff714f00140f954960f5962b04e686902f9e420951ff44eaab73e079465fadb905b082268080212146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af81a0c08c5ac84b00610bcb9d4a20322403cba7354f25c17e980c55459ce5de1ac71f210e134d460642e422162e1dd8b692a86ac491ab562268b34e9a4859672d5cf7997903a5cb2ba94814982741b8203220f08011a0b088092b8c398feffffff01226808021214da250934d695a5a2457708f417f688ff8d9cc3261a0c08c5ac84b00610c0d7daac032240f9b9069ec79d2db8c9da98076d1512498c409f57d9d9df96ab7e3e1f8dab47d09cabdf75057f0f18c5953abfde4d16313cfb970d8156eb42dae960580e0f580a220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d21a0c08c5ac84b00610b0c5cea70322407154c18b984e0f75389b45f95d954e69348f63409bf051fb9cbb64649213602e294f9dfadbba3d46281473bb9a9ad01ad499a7539eee51d3bf1b165dbc24110e22680802121462683a7647539e61d001866edb1fb7152e1f79631a0c08c5ac84b00610a3ced5ad0322405d568927456830e6d1bac28dc454175f69993c2ae140fda1739ee1a12498fd8eeff23c636de597d703d1a3fc728c7139426b1634627ce9f0783458e7ba96ac0f226808021214b15aeec05b39196f3a972f5ab8b7c822e3336c3a1a0c08c5ac84b00610dae48ab00322404fd1cab90aa77443f1c7f16cfe829f6f53ffbbd1f2a0b7be4c1d1009b4a1fc433dc9cf40bc91ee6a054d92dc8805a977989d86f34f0d906bf8cf277550e7d50c226808021214f8933325d7838f9f70bf3ad2d8054ed2826cece51a0c08c5ac84b006109aeaa2a803224011a410d587d561a90d5ecd9d794c8c2b83ffcd4edadb5a0dffa5e9dc3b483193e9b760fc5d6ae85f05b1fc3302386a7ee7b06e89b719f1922e18b1c53ed9540a220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214a5af3f1e0814ef41b0613da1a8bafa20513723201a0c08c5ac84b0061085d3cfa703224022bc591f0043a4f15107ffcea4a3100aed1b27bea45541b59773ac2f4d9b1dc73db3158a5a128b7abd9741002207f58bba56027f2c769f97f6d6875a51d98a0b220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214fad3de3292c242997bf4000af8ffd4551272eb621a0c08c5ac84b00610d5f595fe022240a018672598c67c9ea1d14862e4f2c1fe84abc56724b5f855bd7582f8bce34081e11a8ce09d4d2bf08aacb28b39bb2d39dc541662aecd2e3df6ee228f286ffc00226808021214812dc4bd67175c2c4a74a13a4c6990fe41037a5b1a0c08c5ac84b00610d9a692b5032240384f5d91dd77fea058585a881b16c7ce31c19effb85304af002904b86987666f83e853263f3c46fdbdc2c8897a8ba2b6c9d8e0bdc945121385620da79c213b04220f08011a0b088092b8c398feffffff0122680802121430412ba7032186c3a2b1a6b440272e1d4780ab981a0c08c5ac84b00610e0b1e68d03224028370eb4cfb5dcd9aed66fc6db8dbe789a4025fb07aaf1f5b5f4a34463ca49ba2d18effada1b6751e8997709b7c6aff34b4c736c03264652b597558185d061002268080212148d5e2c42b5d2f9d8203f2a7e9173b5358952576a1a0c08c5ac84b00610c1d3bc9f0322400601d8877836d4e7508255146c1398b7627f3935235c9d13a00f2203e83cce64a90484dad6d6d4fb14f43232a7118e92f5cab96b7f5b3074d2ec9a7aad85050b220f08011a0b088092b8c398feffffff01226808021214330b0dee27003d8e8b24be39f82159f375127d321a0c08c5ac84b006109a81c0a603224042ee5c09a22b86a32cba7a5cff74b7e0dbc9cfbbb37faf41921c16af5592e32fd11bde5b1a86237bbfa786456e927de4940a2489e23b4bc5a4f34f82f17b330422680802121458b9f2517dbf8c55573fcfa9853fff27066d86ed1a0c08c5ac84b00610bb908ea20322403d32ba4d917430f76f20a50172bd47221c6359e3ecf4da5a098ba6dc99d1e558f3023e640b2d5cad9cce5857177745241ee9d459927cc5b2a4d79420eb639e0e220f08011a0b088092b8c398feffffff0122680802121458aff9ec275a66e7ad086d31e30fc59e02b94b921a0c08c5ac84b00610948887b20322400e70a330ba99a86d5419e4ed893ebed6aa62067c8cef32f17d4b200c1358f48d0d27106e1f3720146da4f423262a216d3f0f1b70b71c73c53b35f341c07fbd02220f08011a0b088092b8c398feffffff01226808021214ee2a8b5958586c495b1e7bf7ecfc284d83136c151a0c08c5ac84b00610f092ab8703224059e2e0d4331ec786e542c950b6da7dd0e757ba790a3beeba849bb9be2e979d06901b4fbd5dbd3be985cf85374f7367cbbb0376acd7640c867ff9f99854747f092268080212146d8f5894ab17dc6821a7d82c31a05d81b71c17391a0c08c5ac84b00610bfabfaa0032240f2c30fe5b8a0a4d64171ebf508ebbdc63a48110066a2dfb7f0d3c23d17b6738af902d6f8c337bc28c595ded70d2b2ca8049e68714974720400b8c2e2ff4f55092268080212143096bed304a51710ccde2dcdeb5c364c7559e7351a0c08c5ac84b0061086a690ab03224095d1ad85bea361349e57ec4fd4e10dbc1648e679c06d7ecc3b907fb33e342228e664ca182e9110b50175d6d6a21a2dc291437c1d24adfc5427d149d94617e30c226808021214c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f1a0c08c5ac84b00610f4dde9fe0222402233bd14a55b315bacbb57de5091a6948628851a1e630c9188967419b58745852dd0a73d8ceff4d7db35939c992b15a2993eaa435da4e6e2c9c8a3cba01e2109226808021214784cd03b935c7c3e75419b1f35b283e03faa7c0c1a0c08c5ac84b006108f81899c0322400ea212a580087311d4e13d4862d2957b448b31ec5ea34db1092076448f1701b5b23fe8e265aba9148e46205beb663d0c64d97252429338a8388e90b5a2fab70b220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212145245f51eeb87311e0544086e64df6e737afa01521a0c08c5ac84b00610f7f1faa50322401e147cd0d6d40d9fc280001c792b1b027179bda63ae43019256b1796ee8a40c06cd462887b2a1fd68935c3ee2981dc1a98cabc61ae71491d26abd3968886f004226808021214e7dc29639166155dc9ef5d562e44cefec2d169ca1a0c08c5ac84b00610dde093ab032240bac3c333026946c6cef7b263f9ee2a8834a45b7a366b09d1a126b211683a518586d71cf2752c4fa2e52cb6f0d77489db550be12e20caaf82dd789a47144b1803220f08011a0b088092b8c398feffffff0122680802121483a05569feb3c027db1f5e85c48073d6994040ee1a0c08c5ac84b00610c29ee5b30322403523860032e460064bc7a274826dbf67e4577967644266114696cd1ca01bcde0f1a029c53caee332e7ae620a202c1ed4dc7e44c5c5509598efe3ec1dc200e40f226808021214618ca0614c7ea885243f3580790708979be7bd451a0c08c5ac84b00610afa485a5032240973420c1533fb165fe2cc2b345eca839ef3cd3e98b6df638601fb0a64619f31c66dea36915962583f4f78d7742ea386b2702f15624bd4000c6da55782928b902226808021214f8426ee2307c31165cce1cc4da9762ae74f84ec11a0c08c5ac84b00610f7fed0b303224099a1ea5beea3f8f9afb8766f797fb65f71a4bad207ea275077fd4e37c54c31c4de63fc52536dbe4d69986f72da593bc081069e3f42f976a5014435fd96092804226808021214f063a67840c7d6411bd0c4b9603a1c6c7440d3f91a0c08c5ac84b0061082f3b58303224049f91e2c1a96f7675715b2347b9e2fe04c0c7f6b1f5fa66c3e77667caf8d327765f57f6c74bb08395a9e32b05faba764f4289eb44c107efafbc8f8e2c2b83504226808021214c7ed8e58ed8bbc7c0e9911bfaa38c725c00383641a0c08c5ac84b00610bac6e299032240b3c8e95e5b76ab342e1059bae1eec41f572492383c16592a9b09c74d80dfd800555489cb7e0f4697673dadc52237e49ecb69731e2a0368a6a6b239d6156cd406226808021214bdc269f2f62e3b02d6eb049bd2a11a425cfe3f291a0c08c5ac84b00610f182d9a70322402cc04249565c79527bf8a2784351eed93d111aaa111aea25a689ec924adbd55021afd1799fcd2fc9e560536204da4a25f095e651f527695bcc19c1d5106af40d220f08011a0b088092b8c398feffffff012268080212140808a48a93fba44a17029c17b16ad5cb1ccccfce1a0c08c5ac84b00610bd81ad8b032240912941700df39f699fc34b21faed36ce15627db84dde35cf78ca722cbbce6d874ea36d3575cbe8f747cae1dbb9b4d4136f876c5f719bb98cbbae40d0f82acd0b22680802121465a73fb6a5b297299393c8cc9a342242b13697441a0c08c5ac84b00610acdd889e032240752a924c7393e9ffab930c86f04f1655fe1e741ee7f82012bba78fe3e3d4f95457a28eff334a17e51f7b4d53499c852ef6950224f79b133a2c18303808778a03220f08011a0b088092b8c398feffffff0122680802121472f92fd75727431194c7129be2411a9093e6d57c1a0c08c5ac84b00610d6f0aec60322403ae6ed72d3224c9d276162630709ef68412e77a29c4c234ccdde0afcf97d74c7c22ba7d5f2743bea49a766008b3f8211289b76178f636e0bb4e8320d28b0130422680802121411c30fd0a3bda953d88a2157a69b2cab52b41f051a0c08c5ac84b00610cafeed860322402f5d7772ce53445c16156edddf5f2e2590fd089d3d4d8be0761a686b4c658b46ad4f856180ff59bb0098ab01a47e366ec6f42b5a6db83ebf824aa0cd712ad80b22680802121409d7dd253fe3ea53eb16a5c4492166688b3c65801a0c08c5ac84b0061080d8e5ac03224069ddedc5a33917d6a39d334acc752e318bc84c968b473ff769d895f1f6e1d0649d91a2ff141bcca83a7f62a157595d9d569c25029ada94cfaf9efe053e8bc304226808021214f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a1a0c08c5ac84b00610e5a0eea3032240324a9848b8a67cb786a7783b490d6698f4a0e793defcef6e572d5e4b03d6e9d1ce04fe78555eedc6376e7007382bfc3a41c29124a3760170d300688f81591b05220f08011a0b088092b8c398feffffff0112db320a3f0a14b1852d17fa66b5382a8f770725cc5b228b35775012220a20ec06936d55936aca5c041b091c7a311b1f3065bd2b65b60be25ed09104feb8f318f4d3aa060a3f0a142abc4854b1a1c5aa8403c4ea853a81aca901cc7612220a201addaecd87a7fdaf28bb67bc3533bc705bdfb52007365b7d67685f1d65030dde18a8eea8030a3f0a1425b40fd5ae2ac26b4382b746f6cddb8c73ce602512220a203183f39d70ce25f0a8ea02a762e43dd6fa8ec4037e1bd210acfb49570cd0666f18be80f7020a3f0a148dab929d392163909bfc1b2c8be1d4ff5b058f8612220a20e75d7c6c4a161f130000560c02ad4bfb70709ec2b625d3157a19c50a2987cf8e1896b3ed020a3f0a14408b9882eaa1e636bd48998340babe0153050cc312220a20b0d65ae97827e39346b7e0c6390d116301139a6e2d9a189c4edf26782621a38e18f18ad2020a3f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f3010a3f0a140549633adf0dd5e91ec75458cbeec35ae4331ad112220a20cdb58d6d7fa134d2dac24605a3d616d48fe41f8ed872f8e4c98e9037666db16918daf7ea010a3f0a14fd46533e10d45d8fbfda2588c70f927d2e44bc7912220a20e7de761f86056b4946d8d50100da0515061465b0b26cfafd5ddf97f71b41a86e18e7b9e8010a3f0a14fe1d612fc9c346e51fa20ed491ebd81162c0e11012220a20b017d03e09d1d7283fc27775ad243788236939851a5a326ea084fa62a80bbae618c2fac9010a3f0a1483337fa8c2a5bf1283a58384c0ccee0811919e0a12220a20147ee0dd6069170d26c95238e5a979a0ad370b68178926e806b17775cb5d38e018beb8c7010a3f0a1439d8e563c1af1285095ff5bee373e235d63d0cae12220a20e383ebbe5ff6bd0539f2e8618dbd95dd5da15a4147575da0215cf14f3f386b8c18f1a6c1010a3f0a1459835dcbb6ce79f1d12b86702e8690e5f5c514e512220a20e2e8b19d9012cbd9b00e9bdbd3195ea5107d730d5beb9eb771efaf4e0b3a1dee18bb93bd010a3f0a147bd85b0a30cfae183af900b65bc0ec0a28063c9912220a20c68b2e6e48b7049594cf7e6f24a4f2323d7356233a614e7cf7fd5101cc9be97f18edacb6010a3f0a140218a7a051c04fec85b4f92bfb00a8c4da1a9bd512220a203d94dcb94e8d15630e1934ae4fa0bb644f962bfc81b9d9be368882c1017f983e1885afad010a3f0a143596e89e65d41be8200b436c2986e97e9dd1ecce12220a2003512e3640974bc65e350e91c68b130e769ee58eef0f68eff9fd0763a08d441a18c6bb9d010a3f0a14923b8fcd3097ba253408cf32f8a77da355bbc86312220a204137811e4eaf4874c7d64915b28c174eeb7a1be95d314c7b7822f6f93ec5470518f18198010a3f0a14fe849f301b09dacebd2dce15d3ca34d6ba4ca47312220a20a6322cef180e269ebc624714d13c4955dbba0f408cd8e10d997dc7024494f80418f49c95010a3f0a142d9790447341f3371ad11b4b706332313cce33c312220a20d927b9a6b67b352b9c5747c6595766c1ad25c7708d04264aa17e3c580fd98b2718929894010a3f0a14dfe3e4385652c2f176ebe59c3dbe4198fd30da9012220a2072e20f388f16bae585240348109645b102e2f29ab77cbbce7817b5d123bd0df018f2fb92010a3f0a14536c4cc1cf97c4df693b3e7e6604bf0b14f4257e12220a2003c83e556021016aaaffc2f6aa48fdf788d033c3da0924cd21ccdf6dd5cf32d518f7868c010a3f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018e6ad8b010a3f0a14eab91d7b40213e14e850a90d7c28e662466dd7c612220a20d683dd49bf1096490b5ef089100917f040751afd2f698f161e1f80bc2db9511a18e58384010a3e0a142bded3e9a310eeedfb7d4db1778a9413e29d97b112220a20d854ff20e923fd27aeaea258d784afcb9d87c9fe3927d9ad5ae0b1669d1c2d751892bd780a3e0a141856685db8ac33cb29b9b1d35c034f16511d485012220a20e8527069a1e7bfbe25eaafafad88a1ed0f32db8e4e0a1669972c796f6cad6a4e1889a16b0a3e0a14fac8f77451006668f58b8937a73ae86aee68e25312220a20e408946e01267bc86fb50deacc86dafdaedb3a805a9c45eba47810700fadd18618cbd6610a3e0a14f8bf2150619f6d553ec0ee4427e09ae4cf085aef12220a20c7c5ffac225b15476f87b43d652e06304a965e7491d18fb0d9a0a6a208dbf8e818fffa5f0a3e0a14ebaaecf31ec18dc4234e01c82b749ae2cd7a957712220a20755b3e61036e77ae0f9d8b69df1a9cfc0e47c1fcc6bfdb15a675d47def8061fb18bdef5e0a3e0a14c3c730090bf75fc5bfdfbb4bd26589cf1c7b748712220a20f9bbb0bd1d1e5502d4c4c35da60e4f4a738e18ee28455c77888aac7fc3114a7a18a9ec530a3e0a14b4058eebe8da7015a6c0c29f3c53451563478fb712220a20f45743b9d87fdab24ccd8d07f917679c2d29d0f1e1d71113a5d4d93961fc4ea118f0b5500a3e0a14795ad41bb274e23b8d82b32b4f878c30ff76f3ee12220a202687ca37348621f6f0d7bb0d8181b6d7036887940813b7061ca7999a48bd1f8c1895a54c0a3e0a14fabfce1baa453eaf8255bedc5ee8eff464aa37b512220a208ba26509d1dbd124081bef7bde188ede90cb2ade0f6aefe1fe71193800ba962a18b381410a3e0a14706fab402d748242cd0a22b49012a6c039feec6512220a20243bafe50ae8db47bb23976a2aa10d8e60fbf66a6b3400239bfbf6709aad11d518e3d83d0a3e0a14b4fd96d19a44fe4b6b05370f200d89251fb68b4012220a20e738929a9dd600112b677dfee30227dc396c0683beb26cf7ad1c4d439ee972e31899da390a3e0a14aa6786a7b42270295639f5980e8c3648286caea212220a2096a759920df5363c9aee820cd5220ae927c60b510ec497653d3dbf6ec63c8a9f18a5bd390a3e0a149c29fe719923138d4a27bde5704563e45afc705d12220a207017fbc65e3fb62fbebc1b894125a9cd147a8f5cf87bd37590d70a64c7f6401218818e380a3e0a14a21ccd762306bb2651b2a24cfa15ae537c8c633f12220a207ac3ae3da8ea25e443879b5c1b321c3fb05a5c8f793925eec64aa650629e362418ee8b380a3e0a144451050fc63430d28fedd2a37f3ba16353c7e60a12220a204b534106cdefad4f0da9ee1eec2d7c2985ce1c0cfbd47d9461382afd729dc2bb18cd88360a3e0a14a6e68f4720f047480f3bee8502304baf0faaa7a712220a20b217c1303ec5ae61af90f6a8a72caa57b6e59c416f12e8d256dd904b429998ca18e3ce350a3e0a144249abbc6cccb87ef36b481b3016ec339129018912220a203b9674d593af41c481890f6e1fc3aa279cbe5d58eac58671f35734c59f3743c118d1e1330a3e0a14c3266367ddf27040547dc92d5ebb1623caf2903d12220a203aa92f59e180f35d9419add9a3ce6ad0a608541b811424aa85df565d2032c3af189aa3320a3e0a1483ee1db3ddc3112b91ee8d6e652cd5eef38c46e012220a20d6af075513a9e2d25972bc4893c4807336f3a00d98ebd3749980b1afedef30dc18e3b62e0a3e0a145e56a5d935a9529b8999e1291c64b0ba3f9fd66312220a2008983fbb9c4eeb900ad180158ca77242a29063669ae1a4a32641572ddfda83c91888a32d0a3e0a14fed8e547546670aa5256f64ea16d8bf1a340a5a312220a20f89aeac801b13028472b4733dde75e161b1bfc186b587c469097c0a66b431aba18fb872d0a3e0a1438fbd1eaedfbb5791314bc0661e3b9d145074d9012220a208db395073ffa6278e1c05481ad6a52d50468a90d94efa80b42348f3c62eb0e05189ba52c0a3e0a1484b7580e977f1fd0448c4cbab82a7d3719367d5712220a20eea097ce993a3c7a4e47141404bf14c149be585520e763c22f5cb34909cfbad418dcd4290a3e0a14c24fc0f3780141b5124c8a3bec39de645fb385e412220a20047bbb54c5e59a5b740162e0fa02d35efdde81994b5317100fd79214de3529001891e2270a3e0a146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af812220a20ed9d6aa7a16df68792b42371f386b5308c347f3e8e2f9301a857dfc3f1e72e4718b4d2270a3e0a14373328b487c327e51cb513e60a8a1c5fdaff5b3012220a20647bc426173aa99f2a5bcac2145078d050c7eb72d3b361a4aedf21ac0e5ebb9618aff9250a3e0a14da250934d695a5a2457708f417f688ff8d9cc32612220a20a5bc8d67cf595fe8d576257a97d3832df9fc480216a7df493366f92f8736a0ed18f696240a3e0a144198498bc2c20053e5aaaa4ce9cb7e3b93b8e85e12220a20f69e8798c93227eefb3ccf7efc20c3bd96cae139281f2e699f5b4de17878756c18bd99230a3e0a14e28bf9e8ff9ef17268d26a50f7cd998bee4db3f012220a20ea21311aa1f222afdaf21a2c5cfac248ac8fbe816354e466ac4fafb4f60a513218c8b1220a3e0a14fb2ef7e3b80bf63f9ddc9e2431addbcdc6e7644a12220a203f282143c907b1ef86202f71ffd761693a40748b26961ef5c94930b7cde0812118f1af210a3e0a1479efa8b65cb1f1aa69373ad3d01f442dcfcf938112220a20c85bd96888a6971f1bb95ca0f354f681584c883d7746a7fb312239bc1322d48318f1ac200a3e0a1480524f180664c5a1ac66bdd30bcedb36bbac096a12220a20b00c9552aa825e3e8d0bb9e230fb8e558eb54a0c6fc2b6dde7ea466199e954e018bca8200a3e0a14b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d212220a2030534ef00c64b39ab07df356961b4b6420733389a599242ee26e94de6c76dd7a18daa2200a3e0a1462683a7647539e61d001866edb1fb7152e1f796312220a205040fe5690b8fb12333f1d1b85180a52a9deffa01cf759b6d0efa4e420cdf33018bb9a200a3e0a14b15aeec05b39196f3a972f5ab8b7c822e3336c3a12220a203b9adeab28a2e7165d38299fe0eeb6fb0b6aba7cc201fd5d4955b1fcb56cf9e4189981200a3e0a14f8933325d7838f9f70bf3ad2d8054ed2826cece512220a200a3812c57d816fb4a3ec3686c3b306938d6c72bfce34a23154acd414fa37c5f7189deb1f0a3e0a140d97b64748720fe5d1ddf647ef06eba901caee8612220a20d395877c653467006556d1476ac4b68c9902364ab7fb6507a1a7758f56863cda18f8bf1f0a3e0a145b205289e6d60f7bf3fb4a15db5343da30a2509e12220a200b37c2a9a04bc6a04a68cee15624ced60f603b0939fa9c3ae3c7ddebe96140b5188dab1f0a3e0a14a5af3f1e0814ef41b0613da1a8bafa205137232012220a208ae4723213b340fb244a0d54f6d316aec71776d0fe2cc36d32436f752a1fd44018eca31f0a3e0a149dc49bd022e7e81dbcead966fff4f9af77052f2a12220a207a12ce70a7e988b9ec8ffe03d3ed4758875105bbf15ae78d5d2f46ae67464afd18efcf1e0a3e0a14fd1df5c5f5ea867fb21aa05c00926fabd2639e1612220a20dbb0e5b2016dd75f871ff64f4c8d472fc0da4289690f515f5f173aba8892ab3518d1ec1d0a3e0a14f7a35051ba1ce4f9d5b43157c522275dd90a454212220a2035e4cd35fd12e58f067b8852369bded41708336daca6c176bcbc7cdd8161057818ebab1d0a3e0a14fad3de3292c242997bf4000af8ffd4551272eb6212220a207024974db2eac3a6d3b1106acb52b39e21506c7e26c9f5a61fa86a45e86ce832188eba1c0a3e0a14812dc4bd67175c2c4a74a13a4c6990fe41037a5b12220a20458370b1f37e8de7fa4bae977b90a569285ffe1d37c0460e5b138ad2ecdd738518d6a21b0a3e0a143ded012b42f48947bbb2bd8eef7c0d69d217dce012220a20c2a41771f5e9612ed358c08e997f94be52a4486b6567816e9f50e9f686899b7e18eec5190a3e0a1430412ba7032186c3a2b1a6b440272e1d4780ab9812220a2032307c624e438a213e57ac577044cf328cbb305cc604693611092f77dfe13adf18ce99190a3e0a148d5e2c42b5d2f9d8203f2a7e9173b5358952576a12220a206afd4890886c667d79ee871ae1c1b2b83fdcc26c6fb1cda40695e2091157b152189087190a3e0a143c70fac7857389b869696e8f3e1f48be0be0242912220a20dfdd72d0732e60bf39286432b6b41fb10c0d8905d70897bf2291989e1eeac26518cbda170a3e0a14330b0dee27003d8e8b24be39f82159f375127d3212220a203db48acea4cb759b208b418b3e826ab9c75a77ca3fc7eeb647b84b1ea422308a18bbdc160a3e0a1458b9f2517dbf8c55573fcfa9853fff27066d86ed12220a20d0fa86b1e1eca13d135c07d3dc25814367bff1fafe25e8d8872897d6a0bde59018d79d140a3e0a146f23af09898a93352392cd0977bd5be5c74ef70912220a205ae5773928fed10cbf6f4d5f80d6533501b66736864a3b50e96c58021389b20818a3bc120a3e0a1458aff9ec275a66e7ad086d31e30fc59e02b94b9212220a20640499f5afeeb7ab49c601221c44fb762f3c02d05d5032bde7bab27823a5827718a7a4120a3e0a14e357f35a66a72eb8162f5a66ea221b9025ff56bc12220a20ac38b9ef0c5f7314dec03f8ad4d2fedd35f9d49bc5bb9de48832b55c00d6571518c3f3110a3e0a14ee2a8b5958586c495b1e7bf7ecfc284d83136c1512220a2099a8eeb2d17d0dff6b915cf6c65ffd563606dfd60640a35b8e082d40f67dca3318a683110a3e0a146d8f5894ab17dc6821a7d82c31a05d81b71c173912220a2065348bed02c217dacb610d4c8b7ae45d00389078b18df73e644174a0752c3c8418ceac100a3e0a143096bed304a51710ccde2dcdeb5c364c7559e73512220a20d77807b7263fd82cd116f733f78d7415eb08ac78be46a5e31d20b5285565bfee18ecf70e0a3e0a14c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f12220a20d61e7cdcfae95db114e7dce184ca3b11d59fc64b9163bc02bc8728631b4b5f5718c9e40e0a3e0a14784cd03b935c7c3e75419b1f35b283e03faa7c0c12220a205364bf153a2c5eb3e916bf62c327bbe782ee6b275863c9a11f8af39f7bef4eed18a2e00c0a3e0a142640a32bf68b7f9723e001c2e4b4e32e00b9467912220a209e5d22a072e232bf5c277dffa170ebc80db49d5496c0b638b6af2c01ea993c0c18b1dd0c0a3e0a14caab75b9c6d41e924cd1b526f5e2d123db756bc412220a2091da6ce3e1debed393e42c02a9641e42e965fe5b4095699c3db096049b29b4ea18d9c10c0a3e0a145245f51eeb87311e0544086e64df6e737afa015212220a203df173fba4427fd0acd8bc0f6c83f8f13a7944e5ad20c5f365c7390e5382313918acc00b0a3e0a14e7dc29639166155dc9ef5d562e44cefec2d169ca12220a203f0eb2d5e935320f269d5ab878104d36be1a2bc38d5ef1b2fe66760814a93c9818affd0a0a3e0a1457f61959ff8a08562bb0aba4921c5ef1b307dc6312220a20f5d18e7d52e05100d55e2f5fd0aa9fa8ba710f0801d7f605985b9732063b1c58188fee0a0a3e0a1483a05569feb3c027db1f5e85c48073d6994040ee12220a2087e931b901b4fb3d4733e821ad082d39d13930a1705baf4f5876a941e12f22dd18e3b30a0a3e0a14618ca0614c7ea885243f3580790708979be7bd4512220a200ec759549c85f6a5a4dbc79f7b112de4592dff74e9562d71c45a8fd3161dc9f318fbfc090a3e0a14f8426ee2307c31165cce1cc4da9762ae74f84ec112220a202cb896fc05f2f31a15a470963122fad880de8d26bff2a259291fb18af4d5914418dcf7090a3e0a14f063a67840c7d6411bd0c4b9603a1c6c7440d3f912220a20f9b393d098812877c926b72ffb2acea890ef4e8d321595c8b3f6d2b6ad92dff118a5ac090a3e0a14c7ed8e58ed8bbc7c0e9911bfaa38c725c003836412220a2060d20c0dd3ac3a21ffdbb7a4f0e6e704ff5fc0a6d11b10d1ee194b1a1fedbf7518e788090a3e0a14bdc269f2f62e3b02d6eb049bd2a11a425cfe3f2912220a203cb375c0722fd44d8da62db992e0bb34036e931ab217862892eca2cbcfbb2e9218eff9080a3e0a14c1976fefd48939e2327cbf83f367841028b95e0e12220a208aaa1c11dc4b43e95603cb10d9d24b6215e0232c5d87bb80539d440d6792e22618bb88080a3e0a140808a48a93fba44a17029c17b16ad5cb1ccccfce12220a20cdee5cd83bf3e85634a60f171c51cabba3fe76257605782eeb11d3a9d735c31a1899fd070a3e0a1465a73fb6a5b297299393c8cc9a342242b136974412220a207887710424a3375409f13d31bfed217c1524fb0db7c4f64db96671a5bdcebbc418e48d070a3e0a140c714e67a83273e3c3e35b17ca8ee140551a536012220a203452cde83ab0a21e43c9b749851e03b2ed0421aea710281711ca57d448af7bc218fc90060a3e0a1472f92fd75727431194c7129be2411a9093e6d57c12220a208ed5b1abd4aa4593dcb9c790927ac89f866e54c73d593554e13ef1efd86ab66918c0eb050a3e0a1411c30fd0a3bda953d88a2157a69b2cab52b41f0512220a2079e66631b3171534f3bce2430e6f9a87d83b94d0fcc4d21068dfcd3e2002df3e18d788040a3e0a1409d7dd253fe3ea53eb16a5c4492166688b3c658012220a20a24599a1f46bad5422ffb0d05e83a4394b602ffa007fe3393c985569ee7aa07f18acff030a3e0a14f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a12220a205556636b3bbc09f22e546840fa79d6628e36b4e4ff8d6978d9b274a5a92d932b18abfe020a3d0a1413a56fa6f11adaa2b09d97e57b36277319f22df012220a20315f78bea93b18884bab79e68711a9c05c67953b78788979e80c7fb1fc4caad618ab73123f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018e6ad8b0118d988be3e1a07080210c080b70722db320a3f0a14b1852d17fa66b5382a8f770725cc5b228b35775012220a20ec06936d55936aca5c041b091c7a311b1f3065bd2b65b60be25ed09104feb8f318edd3aa060a3f0a142abc4854b1a1c5aa8403c4ea853a81aca901cc7612220a201addaecd87a7fdaf28bb67bc3533bc705bdfb52007365b7d67685f1d65030dde1894eea8030a3f0a1425b40fd5ae2ac26b4382b746f6cddb8c73ce602512220a203183f39d70ce25f0a8ea02a762e43dd6fa8ec4037e1bd210acfb49570cd0666f189d80f7020a3f0a148dab929d392163909bfc1b2c8be1d4ff5b058f8612220a20e75d7c6c4a161f130000560c02ad4bfb70709ec2b625d3157a19c50a2987cf8e1891b3ed020a3f0a14408b9882eaa1e636bd48998340babe0153050cc312220a20b0d65ae97827e39346b7e0c6390d116301139a6e2d9a189c4edf26782621a38e18dc8ad2020a3f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f3010a3f0a140549633adf0dd5e91ec75458cbeec35ae4331ad112220a20cdb58d6d7fa134d2dac24605a3d616d48fe41f8ed872f8e4c98e9037666db16918daf7ea010a3f0a14fd46533e10d45d8fbfda2588c70f927d2e44bc7912220a20e7de761f86056b4946d8d50100da0515061465b0b26cfafd5ddf97f71b41a86e18dab9e8010a3f0a14fe1d612fc9c346e51fa20ed491ebd81162c0e11012220a20b017d03e09d1d7283fc27775ad243788236939851a5a326ea084fa62a80bbae618c2fac9010a3f0a1483337fa8c2a5bf1283a58384c0ccee0811919e0a12220a20147ee0dd6069170d26c95238e5a979a0ad370b68178926e806b17775cb5d38e018beb8c7010a3f0a1439d8e563c1af1285095ff5bee373e235d63d0cae12220a20e383ebbe5ff6bd0539f2e8618dbd95dd5da15a4147575da0215cf14f3f386b8c18f1a6c1010a3f0a1459835dcbb6ce79f1d12b86702e8690e5f5c514e512220a20e2e8b19d9012cbd9b00e9bdbd3195ea5107d730d5beb9eb771efaf4e0b3a1dee18b593bd010a3f0a147bd85b0a30cfae183af900b65bc0ec0a28063c9912220a20c68b2e6e48b7049594cf7e6f24a4f2323d7356233a614e7cf7fd5101cc9be97f18edacb6010a3f0a140218a7a051c04fec85b4f92bfb00a8c4da1a9bd512220a203d94dcb94e8d15630e1934ae4fa0bb644f962bfc81b9d9be368882c1017f983e1885afad010a3f0a143596e89e65d41be8200b436c2986e97e9dd1ecce12220a2003512e3640974bc65e350e91c68b130e769ee58eef0f68eff9fd0763a08d441a18c6bb9d010a3f0a14923b8fcd3097ba253408cf32f8a77da355bbc86312220a204137811e4eaf4874c7d64915b28c174eeb7a1be95d314c7b7822f6f93ec5470518f18198010a3f0a14fe849f301b09dacebd2dce15d3ca34d6ba4ca47312220a20a6322cef180e269ebc624714d13c4955dbba0f408cd8e10d997dc7024494f80418f49c95010a3f0a142d9790447341f3371ad11b4b706332313cce33c312220a20d927b9a6b67b352b9c5747c6595766c1ad25c7708d04264aa17e3c580fd98b2718f29794010a3f0a14dfe3e4385652c2f176ebe59c3dbe4198fd30da9012220a2072e20f388f16bae585240348109645b102e2f29ab77cbbce7817b5d123bd0df018f2fb92010a3f0a14536c4cc1cf97c4df693b3e7e6604bf0b14f4257e12220a2003c83e556021016aaaffc2f6aa48fdf788d033c3da0924cd21ccdf6dd5cf32d518f7868c010a3f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018ddad8b010a3f0a14eab91d7b40213e14e850a90d7c28e662466dd7c612220a20d683dd49bf1096490b5ef089100917f040751afd2f698f161e1f80bc2db9511a18e58384010a3e0a142bded3e9a310eeedfb7d4db1778a9413e29d97b112220a20d854ff20e923fd27aeaea258d784afcb9d87c9fe3927d9ad5ae0b1669d1c2d751892bd780a3e0a141856685db8ac33cb29b9b1d35c034f16511d485012220a20e8527069a1e7bfbe25eaafafad88a1ed0f32db8e4e0a1669972c796f6cad6a4e1889a16b0a3e0a14fac8f77451006668f58b8937a73ae86aee68e25312220a20e408946e01267bc86fb50deacc86dafdaedb3a805a9c45eba47810700fadd18618cbd6610a3e0a14f8bf2150619f6d553ec0ee4427e09ae4cf085aef12220a20c7c5ffac225b15476f87b43d652e06304a965e7491d18fb0d9a0a6a208dbf8e818fefa5f0a3e0a14ebaaecf31ec18dc4234e01c82b749ae2cd7a957712220a20755b3e61036e77ae0f9d8b69df1a9cfc0e47c1fcc6bfdb15a675d47def8061fb18bdef5e0a3e0a14c3c730090bf75fc5bfdfbb4bd26589cf1c7b748712220a20f9bbb0bd1d1e5502d4c4c35da60e4f4a738e18ee28455c77888aac7fc3114a7a18a7ec530a3e0a14b4058eebe8da7015a6c0c29f3c53451563478fb712220a20f45743b9d87fdab24ccd8d07f917679c2d29d0f1e1d71113a5d4d93961fc4ea118f0b5500a3e0a14795ad41bb274e23b8d82b32b4f878c30ff76f3ee12220a202687ca37348621f6f0d7bb0d8181b6d7036887940813b7061ca7999a48bd1f8c1895a54c0a3e0a14fabfce1baa453eaf8255bedc5ee8eff464aa37b512220a208ba26509d1dbd124081bef7bde188ede90cb2ade0f6aefe1fe71193800ba962a18b381410a3e0a14706fab402d748242cd0a22b49012a6c039feec6512220a20243bafe50ae8db47bb23976a2aa10d8e60fbf66a6b3400239bfbf6709aad11d518e3d83d0a3e0a14b4fd96d19a44fe4b6b05370f200d89251fb68b4012220a20e738929a9dd600112b677dfee30227dc396c0683beb26cf7ad1c4d439ee972e31898da390a3e0a14aa6786a7b42270295639f5980e8c3648286caea212220a2096a759920df5363c9aee820cd5220ae927c60b510ec497653d3dbf6ec63c8a9f18a5bd390a3e0a149c29fe719923138d4a27bde5704563e45afc705d12220a207017fbc65e3fb62fbebc1b894125a9cd147a8f5cf87bd37590d70a64c7f6401218808e380a3e0a14a21ccd762306bb2651b2a24cfa15ae537c8c633f12220a207ac3ae3da8ea25e443879b5c1b321c3fb05a5c8f793925eec64aa650629e362418ee8b380a3e0a144451050fc63430d28fedd2a37f3ba16353c7e60a12220a204b534106cdefad4f0da9ee1eec2d7c2985ce1c0cfbd47d9461382afd729dc2bb18cd88360a3e0a14a6e68f4720f047480f3bee8502304baf0faaa7a712220a20b217c1303ec5ae61af90f6a8a72caa57b6e59c416f12e8d256dd904b429998ca18e3ce350a3e0a144249abbc6cccb87ef36b481b3016ec339129018912220a203b9674d593af41c481890f6e1fc3aa279cbe5d58eac58671f35734c59f3743c118d1e1330a3e0a14c3266367ddf27040547dc92d5ebb1623caf2903d12220a203aa92f59e180f35d9419add9a3ce6ad0a608541b811424aa85df565d2032c3af189aa3320a3e0a1483ee1db3ddc3112b91ee8d6e652cd5eef38c46e012220a20d6af075513a9e2d25972bc4893c4807336f3a00d98ebd3749980b1afedef30dc18e3b62e0a3e0a145e56a5d935a9529b8999e1291c64b0ba3f9fd66312220a2008983fbb9c4eeb900ad180158ca77242a29063669ae1a4a32641572ddfda83c91888a32d0a3e0a14fed8e547546670aa5256f64ea16d8bf1a340a5a312220a20f89aeac801b13028472b4733dde75e161b1bfc186b587c469097c0a66b431aba18fb872d0a3e0a1438fbd1eaedfbb5791314bc0661e3b9d145074d9012220a208db395073ffa6278e1c05481ad6a52d50468a90d94efa80b42348f3c62eb0e05189ba52c0a3e0a1484b7580e977f1fd0448c4cbab82a7d3719367d5712220a20eea097ce993a3c7a4e47141404bf14c149be585520e763c22f5cb34909cfbad418dcd4290a3e0a14c24fc0f3780141b5124c8a3bec39de645fb385e412220a20047bbb54c5e59a5b740162e0fa02d35efdde81994b5317100fd79214de3529001891e2270a3e0a146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af812220a20ed9d6aa7a16df68792b42371f386b5308c347f3e8e2f9301a857dfc3f1e72e4718b4d2270a3e0a14373328b487c327e51cb513e60a8a1c5fdaff5b3012220a20647bc426173aa99f2a5bcac2145078d050c7eb72d3b361a4aedf21ac0e5ebb9618aff9250a3e0a14da250934d695a5a2457708f417f688ff8d9cc32612220a20a5bc8d67cf595fe8d576257a97d3832df9fc480216a7df493366f92f8736a0ed18f696240a3e0a144198498bc2c20053e5aaaa4ce9cb7e3b93b8e85e12220a20f69e8798c93227eefb3ccf7efc20c3bd96cae139281f2e699f5b4de17878756c18bd99230a3e0a14e28bf9e8ff9ef17268d26a50f7cd998bee4db3f012220a20ea21311aa1f222afdaf21a2c5cfac248ac8fbe816354e466ac4fafb4f60a513218c8b1220a3e0a14fb2ef7e3b80bf63f9ddc9e2431addbcdc6e7644a12220a203f282143c907b1ef86202f71ffd761693a40748b26961ef5c94930b7cde0812118f1af210a3e0a1479efa8b65cb1f1aa69373ad3d01f442dcfcf938112220a20c85bd96888a6971f1bb95ca0f354f681584c883d7746a7fb312239bc1322d48318f1ac200a3e0a1480524f180664c5a1ac66bdd30bcedb36bbac096a12220a20b00c9552aa825e3e8d0bb9e230fb8e558eb54a0c6fc2b6dde7ea466199e954e018aba8200a3e0a14b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d212220a2030534ef00c64b39ab07df356961b4b6420733389a599242ee26e94de6c76dd7a18daa2200a3e0a1462683a7647539e61d001866edb1fb7152e1f796312220a205040fe5690b8fb12333f1d1b85180a52a9deffa01cf759b6d0efa4e420cdf33018bb9a200a3e0a14b15aeec05b39196f3a972f5ab8b7c822e3336c3a12220a203b9adeab28a2e7165d38299fe0eeb6fb0b6aba7cc201fd5d4955b1fcb56cf9e4189981200a3e0a14f8933325d7838f9f70bf3ad2d8054ed2826cece512220a200a3812c57d816fb4a3ec3686c3b306938d6c72bfce34a23154acd414fa37c5f7189deb1f0a3e0a140d97b64748720fe5d1ddf647ef06eba901caee8612220a20d395877c653467006556d1476ac4b68c9902364ab7fb6507a1a7758f56863cda18f8bf1f0a3e0a145b205289e6d60f7bf3fb4a15db5343da30a2509e12220a200b37c2a9a04bc6a04a68cee15624ced60f603b0939fa9c3ae3c7ddebe96140b5188dab1f0a3e0a14a5af3f1e0814ef41b0613da1a8bafa205137232012220a208ae4723213b340fb244a0d54f6d316aec71776d0fe2cc36d32436f752a1fd44018eca31f0a3e0a149dc49bd022e7e81dbcead966fff4f9af77052f2a12220a207a12ce70a7e988b9ec8ffe03d3ed4758875105bbf15ae78d5d2f46ae67464afd18efcf1e0a3e0a14fd1df5c5f5ea867fb21aa05c00926fabd2639e1612220a20dbb0e5b2016dd75f871ff64f4c8d472fc0da4289690f515f5f173aba8892ab3518d0ec1d0a3e0a14f7a35051ba1ce4f9d5b43157c522275dd90a454212220a2035e4cd35fd12e58f067b8852369bded41708336daca6c176bcbc7cdd8161057818ebab1d0a3e0a14fad3de3292c242997bf4000af8ffd4551272eb6212220a207024974db2eac3a6d3b1106acb52b39e21506c7e26c9f5a61fa86a45e86ce832188eba1c0a3e0a14812dc4bd67175c2c4a74a13a4c6990fe41037a5b12220a20458370b1f37e8de7fa4bae977b90a569285ffe1d37c0460e5b138ad2ecdd738518d6a21b0a3e0a143ded012b42f48947bbb2bd8eef7c0d69d217dce012220a20c2a41771f5e9612ed358c08e997f94be52a4486b6567816e9f50e9f686899b7e18eec5190a3e0a1430412ba7032186c3a2b1a6b440272e1d4780ab9812220a2032307c624e438a213e57ac577044cf328cbb305cc604693611092f77dfe13adf18ce99190a3e0a148d5e2c42b5d2f9d8203f2a7e9173b5358952576a12220a206afd4890886c667d79ee871ae1c1b2b83fdcc26c6fb1cda40695e2091157b152189087190a3e0a143c70fac7857389b869696e8f3e1f48be0be0242912220a20dfdd72d0732e60bf39286432b6b41fb10c0d8905d70897bf2291989e1eeac26518cbda170a3e0a14330b0dee27003d8e8b24be39f82159f375127d3212220a203db48acea4cb759b208b418b3e826ab9c75a77ca3fc7eeb647b84b1ea422308a18bbdc160a3e0a1458b9f2517dbf8c55573fcfa9853fff27066d86ed12220a20d0fa86b1e1eca13d135c07d3dc25814367bff1fafe25e8d8872897d6a0bde59018d79d140a3e0a146f23af09898a93352392cd0977bd5be5c74ef70912220a205ae5773928fed10cbf6f4d5f80d6533501b66736864a3b50e96c58021389b20818a3bc120a3e0a1458aff9ec275a66e7ad086d31e30fc59e02b94b9212220a20640499f5afeeb7ab49c601221c44fb762f3c02d05d5032bde7bab27823a5827718a7a4120a3e0a14e357f35a66a72eb8162f5a66ea221b9025ff56bc12220a20ac38b9ef0c5f7314dec03f8ad4d2fedd35f9d49bc5bb9de48832b55c00d6571518c3f3110a3e0a14ee2a8b5958586c495b1e7bf7ecfc284d83136c1512220a2099a8eeb2d17d0dff6b915cf6c65ffd563606dfd60640a35b8e082d40f67dca3318a683110a3e0a146d8f5894ab17dc6821a7d82c31a05d81b71c173912220a2065348bed02c217dacb610d4c8b7ae45d00389078b18df73e644174a0752c3c8418ceac100a3e0a143096bed304a51710ccde2dcdeb5c364c7559e73512220a20d77807b7263fd82cd116f733f78d7415eb08ac78be46a5e31d20b5285565bfee18ecf70e0a3e0a14c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f12220a20d61e7cdcfae95db114e7dce184ca3b11d59fc64b9163bc02bc8728631b4b5f5718c9e40e0a3e0a14784cd03b935c7c3e75419b1f35b283e03faa7c0c12220a205364bf153a2c5eb3e916bf62c327bbe782ee6b275863c9a11f8af39f7bef4eed18a2e00c0a3e0a142640a32bf68b7f9723e001c2e4b4e32e00b9467912220a209e5d22a072e232bf5c277dffa170ebc80db49d5496c0b638b6af2c01ea993c0c18b1dd0c0a3e0a14caab75b9c6d41e924cd1b526f5e2d123db756bc412220a2091da6ce3e1debed393e42c02a9641e42e965fe5b4095699c3db096049b29b4ea18d9c10c0a3e0a145245f51eeb87311e0544086e64df6e737afa015212220a203df173fba4427fd0acd8bc0f6c83f8f13a7944e5ad20c5f365c7390e5382313918acc00b0a3e0a14e7dc29639166155dc9ef5d562e44cefec2d169ca12220a203f0eb2d5e935320f269d5ab878104d36be1a2bc38d5ef1b2fe66760814a93c9818affd0a0a3e0a1457f61959ff8a08562bb0aba4921c5ef1b307dc6312220a20f5d18e7d52e05100d55e2f5fd0aa9fa8ba710f0801d7f605985b9732063b1c58188fee0a0a3e0a1483a05569feb3c027db1f5e85c48073d6994040ee12220a2087e931b901b4fb3d4733e821ad082d39d13930a1705baf4f5876a941e12f22dd18e3b30a0a3e0a14618ca0614c7ea885243f3580790708979be7bd4512220a200ec759549c85f6a5a4dbc79f7b112de4592dff74e9562d71c45a8fd3161dc9f318fbfc090a3e0a14f8426ee2307c31165cce1cc4da9762ae74f84ec112220a202cb896fc05f2f31a15a470963122fad880de8d26bff2a259291fb18af4d5914418dcf7090a3e0a14f063a67840c7d6411bd0c4b9603a1c6c7440d3f912220a20f9b393d098812877c926b72ffb2acea890ef4e8d321595c8b3f6d2b6ad92dff118a5ac090a3e0a14c7ed8e58ed8bbc7c0e9911bfaa38c725c003836412220a2060d20c0dd3ac3a21ffdbb7a4f0e6e704ff5fc0a6d11b10d1ee194b1a1fedbf7518e788090a3e0a14bdc269f2f62e3b02d6eb049bd2a11a425cfe3f2912220a203cb375c0722fd44d8da62db992e0bb34036e931ab217862892eca2cbcfbb2e9218eff9080a3e0a14c1976fefd48939e2327cbf83f367841028b95e0e12220a208aaa1c11dc4b43e95603cb10d9d24b6215e0232c5d87bb80539d440d6792e22618bb88080a3e0a140808a48a93fba44a17029c17b16ad5cb1ccccfce12220a20cdee5cd83bf3e85634a60f171c51cabba3fe76257605782eeb11d3a9d735c31a1899fd070a3e0a1465a73fb6a5b297299393c8cc9a342242b136974412220a207887710424a3375409f13d31bfed217c1524fb0db7c4f64db96671a5bdcebbc418da8d070a3e0a140c714e67a83273e3c3e35b17ca8ee140551a536012220a203452cde83ab0a21e43c9b749851e03b2ed0421aea710281711ca57d448af7bc218fc90060a3e0a1472f92fd75727431194c7129be2411a9093e6d57c12220a208ed5b1abd4aa4593dcb9c790927ac89f866e54c73d593554e13ef1efd86ab66918bceb050a3e0a1411c30fd0a3bda953d88a2157a69b2cab52b41f0512220a2079e66631b3171534f3bce2430e6f9a87d83b94d0fcc4d21068dfcd3e2002df3e18d788040a3e0a1409d7dd253fe3ea53eb16a5c4492166688b3c658012220a20a24599a1f46bad5422ffb0d05e83a4394b602ffa007fe3393c985569ee7aa07f18acff030a3e0a14f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a12220a205556636b3bbc09f22e546840fa79d6628e36b4e4ff8d6978d9b274a5a92d932b18abfe020a3d0a1413a56fa6f11adaa2b09d97e57b36277319f22df012220a20315f78bea93b18884bab79e68711a9c05c67953b78788979e80c7fb1fc4caad618ab73123f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f30118a287be3e" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "module", - "value": "ibc_client" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "action", - "value": "/ibc.core.channel.v1.MsgAcknowledgement" - }, - { - "key": "sender", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" - } - ] - }, - { - "type": "acknowledge_packet", - "attributes": [ - { - "key": "connection_id", - "value": "connection-75" - }, - { - "key": "packet_channel_ordering", - "value": "ORDER_UNORDERED" - }, - { - "key": "packet_connection", - "value": "connection-75" - }, - { - "key": "packet_dst_channel", - "value": "channel-126" - }, - { - "key": "packet_dst_port", - "value": "transfer" - }, - { - "key": "packet_sequence", - "value": "988" - }, - { - "key": "packet_src_channel", - "value": "channel-104" - }, - { - "key": "packet_src_port", - "value": "transfer" - }, - { - "key": "packet_timeout_height", - "value": "0-0" - }, - { - "key": "packet_timeout_timestamp", - "value": "1711347430185000000" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "module", - "value": "ibc_channel" - } - ] - }, - { - "type": "fungible_token_packet", - "attributes": [ - { - "key": "acknowledgement", - "value": "result:\"\\001\" " - }, - { - "key": "amount", - "value": "27978000" - }, - { - "key": "denom", - "value": "transfer/channel-104/uakt" - }, - { - "key": "memo", - "value": "" - }, - { - "key": "module", - "value": "transfer" - }, - { - "key": "receiver", - "value": "akash1t8np6xr8qr24yjyp3lkg9j4wyeazgf6frrzx4u" - }, - { - "key": "sender", - "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" - } - ] - }, - { - "type": "fungible_token_packet", - "attributes": [ - { - "key": "success", - "value": "\u0001" - } - ] - } - ], - "codespace": "" - } - ], - "begin_block_events": [ - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "20456465438196201488aarch" - }, - { - "key": "receiver", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coinbase", - "attributes": [ - { - "key": "amount", - "value": "20456465438196201488aarch" - }, - { - "key": "minter", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "spender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "receiver", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "recipient", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - }, - { - "key": "sender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "spender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "receiver", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "recipient", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - }, - { - "key": "sender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "archway.rewards.v1.MinConsensusFeeSetEvent", - "attributes": [ - { - "key": "fee", - "value": "{\"denom\":\"aarch\",\"amount\":\"34094109063.660335813333333333\"}" - } - ] - }, - { - "type": "mint", - "attributes": [ - { - "key": "amount", - "value": "20456465438196201488" - }, - { - "key": "annual_provisions", - "value": "107592825618736741349012839.100000000000000000" - }, - { - "key": "bonded_ratio", - "value": "0.476278464914987794" - }, - { - "key": "inflation", - "value": "0.100000000000000000" - } - ] - }, - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "spender", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "receiver", - "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "recipient", - "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" - }, - { - "key": "sender", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "47031267452693036.061160109957597621aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "940625349053860721.223202199151952412aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "38476736132757653.641375706228733112aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "769534722655153072.827514124574662242aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "25198563408572443.297487568120742094aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "503971268171448865.949751362414841889aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "38385179966923893.758115958837052080aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "479814749586548671.976449485463151006aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "20848080058682149.927238603944519387aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "416961601173642998.544772078890387735aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "18078103662935996.564316767356891825aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "361562073258719931.286335347137836505aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "16397185525293103.453610095140066692aarch" - }, - { - "key": "validator", - "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "327943710505862069.072201902801333835aarch" - }, - { - "key": "validator", - "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "321840969895750362.322698020897468527aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "321840969895750362.322698020897468527aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "15497002790178990.382878376219577609aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "309940055803579807.657567524391552185aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "14382002009562408.966451471365272199aarch" - }, - { - "key": "validator", - "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "287640040191248179.329029427305443980aarch" - }, - { - "key": "validator", - "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "13893332467457515.070627762265926164aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "277866649349150301.412555245318523271aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "13770849876624121.332192990936737311aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "275416997532482426.643859818734746213aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "12930798182518861.484757122871543030aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "258615963650377229.695142457430860592aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "12030364971758872.030268279538284386aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "240607299435177440.605365590765687724aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "11189751818200215.104161320082748986aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "223795036364004302.083226401654979719aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "22284930786917069.309869240938732002aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "222849307869170693.098692409387320015aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "10622762200262906.250589114950164761aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "212455244005258125.011782299003295211aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "20593888085947895.310473392523510734aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "205938880859478953.104733925235107341aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "10233575111733853.664058333319530926aarch" - }, - { - "key": "validator", - "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "204671502234677073.281166666390618516aarch" - }, - { - "key": "validator", - "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9990294308427255.981021251439344373aarch" - }, - { - "key": "validator", - "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "199805886168545119.620425028786887454aarch" - }, - { - "key": "validator", - "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9956509646731535.147278403734301398aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "199130192934630702.945568074686027966aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "19126950729710299.665644427976706534aarch" - }, - { - "key": "validator", - "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "191269507297102996.656444279767065337aarch" - }, - { - "key": "validator", - "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3795328565503973.184141327894708544aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "189766428275198659.207066394735427181aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9442139614759897.331870324410660370aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "188842792295197946.637406488213207399aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "37171458291268257.131570065986651951aarch" - }, - { - "key": "validator", - "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "185857291456341285.657850329933259756aarch" - }, - { - "key": "validator", - "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8909997069263457.716045493806167155aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "178199941385269154.320909876123343102aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8410863836693763.423641845394010617aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "168217276733875268.472836907880212335aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "16287634795052974.555039143568147364aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "162876347950529745.550391435681473638aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8116318548809015.185851059708506321aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "162326370976180303.717021194170126423aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "14106818207670570.608562862410733280aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "156742424529673006.761809582341480886aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "7817509546278174.286098972010596527aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "156350190925563485.721979440211930538aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "7698025627362544.745416469488871318aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "153960512547250894.908329389777426363aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "1468691530058656.639589777369466772aarch" - }, - { - "key": "validator", - "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "146869153005865663.958977736946677172aarch" - }, - { - "key": "validator", - "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "13254946033113129.332220275501974624aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "132549460331131293.322202755019746245aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6528176308965305.138762208357045787aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "130563526179306102.775244167140915739aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6427765125466552.035382663728815800aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "128555302509331040.707653274576315992aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6369673068788454.612640168190546461aarch" - }, - { - "key": "validator", - "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "127393461375769092.252803363810929221aarch" - }, - { - "key": "validator", - "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "12731049483598902.774539034875018554aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "127310494835989027.745390348750185539aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6188648127981006.239817584115334679aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "123772962559620124.796351682306693584aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6111735218698457.658597005193378472aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "122234704373969153.171940103867569443aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "11920977472838526.728569377167360808aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "119209774728385267.285693771673608080aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "11798931103635591.155836728325712191aarch" - }, - { - "key": "validator", - "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "117989311036355911.558367283257121914aarch" - }, - { - "key": "validator", - "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5734886166478625.892898092108881652aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "114697723329572517.857961842177633032aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9032987084354732.600540116550070865aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "112912338554434157.506751456875885809aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5622139761003751.922093399217840541aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "112442795220075038.441867984356810827aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5467151622868464.860068008108763923aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "109343032457369297.201360162175278454aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5147485597735517.675781608689883791aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "102949711954710353.515632173797675817aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5061348711718600.465891267895790323aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "101226974234372009.317825357915806467aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5029050017899537.493160438270993264aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "100581000357990749.863208765419865282aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4959406531013593.852444214136180672aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "99188130620271877.048884282723613441aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4784203038222939.406288267155309764aarch" - }, - { - "key": "validator", - "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "95684060764458788.125765343106195284aarch" - }, - { - "key": "validator", - "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4660416003997820.740312005440280988aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "93208320079956414.806240108805619764aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9300475936685287.242513541288714658aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "93004759366852872.425135412887146582aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4626325987160778.397378224627902136aarch" - }, - { - "key": "validator", - "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "92526519743215567.947564492558042714aarch" - }, - { - "key": "validator", - "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "902962733350027.401752135061459718aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "90296273335002740.175213506145971754aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8912165512916799.835861475013525979aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "89121655129167998.358614750135259792aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8781155492791221.494594506355942232aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "87811554927912214.945945063559422315aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6899333091057620.960224373610959541aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "86241663638220262.002804670136994266aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4310085005410204.100167898860593316aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "86201700108204082.003357977211866318aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4165137000608207.977714955807129321aarch" - }, - { - "key": "validator", - "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "83302740012164159.554299116142586422aarch" - }, - { - "key": "validator", - "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "823400410887391.655444942037895916aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "82340041088739165.544494203789591620aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8110953022754377.656552773692154718aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "81109530227543776.565527736921547177aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4049923832171419.900874945961500186aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "80998476643428398.017498919230003713aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4046835101594465.126102101748185146aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "80936702031889302.522042034963702927aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4015504538361708.968609533070971737aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "80310090767234179.372190661419434749aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3989445221024750.193829797927477751aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "79788904420495003.876595958549555022aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "7819950980242190.974745026504499838aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "78199509802421909.747450265044998376aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3893314638170688.030671063618776405aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "77866292763413760.613421272375528109aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "7356227686733312.614918000804230323aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "73562276867333126.149180008042303234aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3651595789734440.460813787200889911aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "73031915794688809.216275744017798219aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6336760568920340.042851852762609760aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "70408450765781556.031687252917886220aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3257159969974389.397733527606727682aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "65143199399487787.954670552134553635aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3241903470240747.643062868104794157aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "64838069404814952.861257362095883149aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6479357479850821.563309842818828243aarch" - }, - { - "key": "validator", - "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "64793574798508215.633098428188282433aarch" - }, - { - "key": "validator", - "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3181101210787609.253499528559273910aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "63622024215752185.069990571185478197aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6341244082981521.831817288858422522aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "63412440829815218.318172888584225217aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5963842014307592.847667445233562256aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "59638420143075928.476674452335622559aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5748320385530191.674253504092312988aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "57483203855301916.742535040923129879aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2852413840903474.221838280346566438aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "57048276818069484.436765606931328767aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2815496826467752.580425254170529570aarch" - }, - { - "key": "validator", - "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "56309936529355051.608505083410591406aarch" - }, - { - "key": "validator", - "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2778202691396666.747218384581883466aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "55564053827933334.944367691637669328aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2694434066683173.206122624486548955aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "53888681333663464.122452489730979101aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2652887474298394.524581334018800918aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "53057749485967890.491626680376018355aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4945956833129978.687897043942664985aarch" - }, - { - "key": "validator", - "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "49459568331299786.878970439426649847aarch" - }, - { - "key": "validator", - "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2348424476570194.306780348897158990aarch" - }, - { - "key": "validator", - "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "46968489531403886.135606977943179798aarch" - }, - { - "key": "validator", - "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4466388844269614.461180848095981218aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "44663888442696144.611808480959812180aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4410639719897042.568753264099370019aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "44106397198970425.687532640993700187aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2180926627806602.966830879190971933aarch" - }, - { - "key": "validator", - "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43618532556132059.336617583819438666aarch" - }, - { - "key": "validator", - "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4334790628526192.728785775490332845aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43347906285261927.287857754903328446aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4317353020640258.703423690157865934aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43173530206402587.034236901578659340aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4310621135865702.319268914397417516aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43106211358657023.192689143974175157aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2151546397411960.927938840521971384aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43030927948239218.558776810439427683aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4276970154992218.095443976355904791aarch" - }, - { - "key": "validator", - "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "42769701549922180.954439763559047908aarch" - }, - { - "key": "validator", - "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4227209931455874.017210362427827103aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "42272099314558740.172103624278271034aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4224035363719377.513891413189025352aarch" - }, - { - "key": "validator", - "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "42240353637193775.138914131890253522aarch" - }, - { - "key": "validator", - "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "" - }, - { - "key": "validator", - "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "36137022017131114.228519325308756161aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3577726581699250.284220154744698892aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "35777265816992502.842201547446988919aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2466956306598184.675480716666651432aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "35242232951402638.221153095237877595aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "983390744674140.023941688397971514aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "32779691489138000.798056279932383792aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "1717680363758128.131106183256179516aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1yw5nl74hv609enqxsn70k55p3pychyc9cvznds" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "17176803637581281.311061832561795160aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1yw5nl74hv609enqxsn70k55p3pychyc9cvznds" - } - ] - } - ], - "end_block_events": [ - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "spender", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "receiver", - "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "recipient", - "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" - }, - { - "key": "sender", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - } - ] - } - ], - "validator_updates": null, - "consensus_param_updates": { - "block": { - "max_bytes": "22020096", - "max_gas": "300000000" - }, - "evidence": { - "max_age_num_blocks": "100000", - "max_age_duration": "172800000000000", - "max_bytes": "1048576" - }, - "validator": { - "pub_key_types": ["ed25519"] - } - } - } - } -} From 1f6f3fae3088ea2849567a9e42299cbea2dc85e5 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 9 Apr 2024 19:42:26 +0800 Subject: [PATCH 25/81] update tmpDir root --- packages/node/src/indexer/api.service.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 735e99e0b..a87247cb3 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -101,7 +101,6 @@ export class ApiService this.registry = await this.buildRegistry(); if (this.nodeConfig.kyveEndpoint) { - const tmpDir = await makeTempDir(); // still need to use cosmosClient to proxy rpcCalls const cosmosClient = await CosmosClientConnection.create( (network.endpoint as string[])[0], @@ -119,7 +118,7 @@ export class ApiService this.nodeConfig.storageUrl, this.nodeConfig.kyveChainId, cosmosClient, - tmpDir, + this.project.root, ), (connection: KyveConnection) => Promise.resolve(network.chainId), ); From c94b2181bb8f46fda1c69659b7fc456ff53526ea Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 10 Apr 2024 10:02:03 +0800 Subject: [PATCH 26/81] fixed tests, refactor based on comments --- packages/node/src/configure/NodeConfig.ts | 6 +- packages/node/src/indexer/api.service.ts | 28 ++-- packages/node/src/utils/kyve/kyve.spec.ts | 18 +-- packages/node/src/utils/kyve/kyve.ts | 142 ++++++++---------- .../node/src/utils/kyve/kyveConnection.ts | 1 + 5 files changed, 92 insertions(+), 103 deletions(-) diff --git a/packages/node/src/configure/NodeConfig.ts b/packages/node/src/configure/NodeConfig.ts index 4a5367261..d86ac9b27 100644 --- a/packages/node/src/configure/NodeConfig.ts +++ b/packages/node/src/configure/NodeConfig.ts @@ -7,7 +7,7 @@ import { IConfig, NodeConfig } from '@subql/node-core'; export interface ICosmosConfig extends IConfig { kyveChainId: SupportedChains; kyveEndpoint: string; - storageUrl: string; + kyveStorageUrl: string; } export class CosmosNodeConfig extends NodeConfig { @@ -35,7 +35,7 @@ export class CosmosNodeConfig extends NodeConfig { return this._config.kyveChainId; } - get storageUrl(): string { - return this._config.storageUrl; + get kyveStorageUrl(): string { + return this._config.kyveStorageUrl; } } diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index a87247cb3..f9b0a503a 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -108,18 +108,28 @@ export class ApiService this.registry, ); + // TODO + // instead waiting to try to get cosmos client through another connection instead of creating await this.createConnections( network, - (endpoint) => - KyveConnection.create( - this.nodeConfig.kyveEndpoint, - network.chainId, + (endpoint) => { + if (endpoint === this.nodeConfig.kyveEndpoint) { + return KyveConnection.create( + this.nodeConfig.kyveEndpoint, + network.chainId, + this.registry, + this.nodeConfig.kyveStorageUrl, + this.nodeConfig.kyveChainId, + cosmosClient, + this.project.root, + ); + } + return CosmosClientConnection.create( + endpoint, + this.fetchBlocksBatches, this.registry, - this.nodeConfig.storageUrl, - this.nodeConfig.kyveChainId, - cosmosClient, - this.project.root, - ), + ); + }, (connection: KyveConnection) => Promise.resolve(network.chainId), ); } else { diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index c4fc42773..e58ee474d 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -22,7 +22,7 @@ import { MsgStoreCode, MsgUpdateAdmin, } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; -import { isEqual } from 'lodash'; +import { isEqual, toLower } from 'lodash'; import rimraf from 'rimraf'; import { HttpClient } from '../../indexer/rpc-clients'; import { LazyBlockContent } from '../cosmos'; @@ -85,7 +85,7 @@ describe('KyveApi', () => { retrieveBundleDataSpy.mockRestore(); }); afterAll(async () => { - await promisify(rimraf)(tmpPath); + // await promisify(rimraf)(tmpPath); }); it('ensure bundleDetails', async () => { @@ -200,7 +200,7 @@ describe('KyveApi', () => { return { data: mockStream }; }); - const pollSpy = jest.spyOn(kyveApi, 'pollUntilReadable'); + const pollSpy = jest.spyOn(kyveApi as any, 'pollUntilReadable'); await expect( Promise.all([ @@ -213,16 +213,16 @@ describe('KyveApi', () => { expect(pollSpy).toHaveBeenCalled(); - const MAX_COMPRESSION_BYTE_SIZE = 2 * 10 ** 9; - const r = await kyveApi.readFromFile( path.join(tmpPath, `bundle_${(kyveApi as any).cachedBundleDetails.id}`), ); - const unzipped = gunzipSync(zipped, { - maxOutputLength: MAX_COMPRESSION_BYTE_SIZE, - }); - // TODO for some reason it does not equal + const stats = await fs.promises.stat( + path.join(tmpPath, `bundle_${(kyveApi as any).cachedBundleDetails.id}`), + ); + const permissions = (stats.mode & 0o777).toString(8); + + expect(permissions).toBe(444); expect(r).toEqual(JSON.stringify(block_3856726)); }); describe('able to wrap kyveBlock', () => { diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 6ef70e072..ed496e3e5 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -20,7 +20,7 @@ import { QueryPoolsResponse, } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; import { delay, getLogger } from '@subql/node-core'; -import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; +import axios, { AxiosResponse } from 'axios'; import { BlockContent } from '../../indexer/types'; import { LazyBlockContent } from '../cosmos'; import { BundleDetails } from './kyveTypes'; @@ -42,24 +42,15 @@ interface UnZippedKyveBlockReponse { } export class KyveApi { - private readonly lcdClient: KyveLCDClientType; - private respAdaptor = adaptor37.responses; - private poolId: string; private currentBundleId = -1; private cachedBundleDetails: BundleDetails; private constructor( - private chainId: string, - private endpoint: string, private readonly storageUrl: string, - private readonly kyveChainId: SupportedChains, private readonly tmpCacheDir: string, - ) { - this.lcdClient = new KyveSDK(this.kyveChainId, { - rpc: this.endpoint, - }).createLCDClient(); - this.storageUrl = storageUrl; - } + private readonly poolId: string, + private readonly lcdClient: KyveLCDClientType, + ) {} static async create( chainId: string, // chainId for indexing chain @@ -68,54 +59,42 @@ export class KyveApi { kyveChainId: SupportedChains, tmpCacheDir: string, ): Promise { - const kyve = new KyveApi( - chainId, - endpoint, - storageUrl, - kyveChainId, - tmpCacheDir, - ); - await kyve.setPoolId(); + const lcdClient = new KyveSDK(kyveChainId, { + rpc: endpoint, + }).createLCDClient(); - return kyve; - } + const poolId = await KyveApi.fetchPoolId(chainId, lcdClient); - get getLcdClient(): KyveLCDClientType { - return this.lcdClient; - } + const kyve = new KyveApi(storageUrl, tmpCacheDir, poolId, lcdClient); - private async getAllPools(): Promise { - return (await this.lcdClient.kyve.query.v1beta1.pools()) as unknown as QueryPoolsResponse; + return kyve; } - private async setPoolId(): Promise { - const pools = await this.getAllPools(); + static async fetchPoolId( + chainId: string, + lcdClient: KyveLCDClientType, + ): Promise { + const poolsResponse = + (await lcdClient.kyve.query.v1beta1.pools()) as unknown as QueryPoolsResponse; - let pool: PoolResponse; - for (const p of pools.pools) { + for (const p of poolsResponse.pools) { try { const config = JSON.parse(p.data.config); - - if (config.network === this.chainId) { - pool = p as unknown as PoolResponse; - break; + if (config.network === chainId) { + return p.id; // Return the matching pool ID } } catch (error) { throw new Error( - `Error parsing JSON for pool with id ${p.id}:, ${error}`, + `Error parsing JSON for pool with id ${p.id}: ${error}`, ); } } - if (!pool) { - throw new Error(`${this.chainId} is not available on Kyve network`); - } - - this.poolId = pool.id; + throw new Error(`${chainId} is not available on Kyve network`); } private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { - return this.respAdaptor.decodeBlock({ + return adaptor37.responses.decodeBlock({ id: 1, jsonrpc: '2.0', result: block, @@ -125,13 +104,17 @@ export class KyveApi { private decodeBlockResult( blockResult: JsonRpcSuccessResponse, ): BlockResultsResponse { - return this.respAdaptor.decodeBlockResults({ + return adaptor37.responses.decodeBlockResults({ id: 1, jsonrpc: '2.0', result: blockResult, }); } + private getBundelFileName(id: string): string { + return path.join(this.tmpCacheDir, `bundle_${id}`); + } + private async getBundleById(bundleId: number): Promise { const bundleDetail = await this.lcdClient.kyve.query.v1beta1.finalizedBundle({ @@ -217,14 +200,14 @@ export class KyveApi { ); await this.clearFileCache(); } catch (e) { - /* empty */ + /* if file does not exist, no need to clear fileCache */ } - return this.jsonParseWrapper(await this.getFileCacheData()); + return JSON.parse(await this.getFileCacheData()); } } - async pollUntilReadable(bundleFilePath: string): Promise { + private async pollUntilReadable(bundleFilePath: string): Promise { // eslint-disable-next-line no-constant-condition while (true) { try { @@ -249,27 +232,23 @@ export class KyveApi { const gunzip = zlib.createUnzip({ maxOutputLength: MAX_COMPRESSION_BYTE_SIZE /* avoid zip bombs */, }); - zippedBundleData.data - .pipe(gunzip) - .pipe(writeStream) - .on('error', (err) => { - // TODO i am unsure if this is working with async - if (err.code === 'EEXIST') { - return this.pollUntilReadable(bundleFilePath); - } else { - throw err; - } - }) - .on('finish', () => { - return fs.promises.chmod(bundleFilePath, 0o444); - }); + + await new Promise((resolve, reject) => { + zippedBundleData.data + .pipe(gunzip) + .on('error', reject) + .pipe(writeStream) + .on('error', (err) => { + reject(err); + }) + .on('finish', resolve); + }); + + await fs.promises.chmod(bundleFilePath, 0o444); } async getFileCacheData(): Promise { - const bundleFilePath = path.join( - this.tmpCacheDir, - `bundle_${this.cachedBundleDetails.id}`, - ); + const bundleFilePath = this.getBundelFileName(this.cachedBundleDetails.id); try { await this.downloadAndProcessBundle(bundleFilePath); @@ -283,25 +262,25 @@ export class KyveApi { } } - private jsonParseWrapper(data: string) { - try { - return JSON.parse(data); - } catch (e) { - throw new Error(`Failed to parse storageData. ${e}`); - } - } - async readFromFile(bundleFilePath: string): Promise { return fs.promises.readFile(bundleFilePath, 'utf-8'); } async clearFileCache(): Promise { - await fs.promises.unlink( - path.join( - this.tmpCacheDir, - `bundle_${parseDecimal(this.cachedBundleDetails.id) - 2}`, - ), - ); + const currentBundleId = parseDecimal(this.cachedBundleDetails.id); + const files = await fs.promises.readdir(this.tmpCacheDir); + + const minAllowedBundleId = currentBundleId - 2; + + const filesToRemove = files.filter((file) => { + const match = file.match(/bundle_(\d+)/); // Extract bundle ID from filename + return match && parseDecimal(match[1]) <= minAllowedBundleId; + }); + + for (const file of filesToRemove) { + const filePath = path.join(this.tmpCacheDir, file); + await fs.promises.unlink(filePath); + } } async getBlockByHeight( @@ -373,7 +352,7 @@ export class KyveApi { } private async retrieveBundleData(): Promise { - const axiosConfig: AxiosRequestConfig = { + return axios({ method: 'get', url: this.cachedBundleDetails.storage_id, baseURL: this.storageUrl, @@ -384,8 +363,7 @@ export class KyveApi { Connection: 'keep-alive', 'Content-Encoding': 'gzip', }, - }; - return axios(axiosConfig); + }); } async fetchBlocksBatches( diff --git a/packages/node/src/utils/kyve/kyveConnection.ts b/packages/node/src/utils/kyve/kyveConnection.ts index 51bee5c78..67818e1ce 100644 --- a/packages/node/src/utils/kyve/kyveConnection.ts +++ b/packages/node/src/utils/kyve/kyveConnection.ts @@ -87,6 +87,7 @@ export class KyveConnection } safeApi(height: number): any { + // provide the same logic for as unsafe api throw new Error('SafeApi should not be used for kyve-connection'); } From 8c5c57af60de596c3fb720da726c806b303bf709 Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 10 Apr 2024 12:25:49 +0800 Subject: [PATCH 27/81] fix kyve connections --- packages/node/src/indexer/api.service.ts | 68 +++++++------------ .../node/src/utils/kyve/kyveConnection.ts | 16 +++-- 2 files changed, 32 insertions(+), 52 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index f9b0a503a..8dfd8a3d7 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -62,13 +62,6 @@ export class ApiService super(connectionPoolService, eventEmitter); this.nodeConfig = new CosmosNodeConfig(nodeConfig); } - // create a temp file - // download the block content - - // the first worker that would load the bundle - // file lock to control permission on doing it - - // clean up old bundles private async buildRegistry(): Promise { const chaintypes = await this.getChainType(this.project.network); @@ -100,55 +93,40 @@ export class ApiService this.registry = await this.buildRegistry(); + await this.createConnections( + network, + (endpoint) => + CosmosClientConnection.create( + endpoint, + this.fetchBlocksBatches, + this.registry, + ), + (connection: CosmosClientConnection) => { + const api = connection.unsafeApi; + return api.getChainId(); + }, + ); + if (this.nodeConfig.kyveEndpoint) { - // still need to use cosmosClient to proxy rpcCalls - const cosmosClient = await CosmosClientConnection.create( - (network.endpoint as string[])[0], - this.fetchBlocksBatches, - this.registry, - ); + // this.connectionPoolService.updateConnection() - // TODO - // instead waiting to try to get cosmos client through another connection instead of creating await this.createConnections( network, (endpoint) => { - if (endpoint === this.nodeConfig.kyveEndpoint) { - return KyveConnection.create( - this.nodeConfig.kyveEndpoint, - network.chainId, - this.registry, - this.nodeConfig.kyveStorageUrl, - this.nodeConfig.kyveChainId, - cosmosClient, - this.project.root, - ); - } - return CosmosClientConnection.create( - endpoint, - this.fetchBlocksBatches, + return KyveConnection.create( + this.nodeConfig.kyveEndpoint, + network.chainId, this.registry, + this.nodeConfig.kyveStorageUrl, + this.nodeConfig.kyveChainId, + this.project.root, + this.unsafeApi, + this.safeApi.bind(this), ); }, (connection: KyveConnection) => Promise.resolve(network.chainId), ); - } else { - await this.createConnections( - network, - (endpoint) => - CosmosClientConnection.create( - endpoint, - this.fetchBlocksBatches, - this.registry, - ), - (connection: CosmosClientConnection) => { - const api = connection.unsafeApi; - return api.getChainId(); - }, - ); } - - // } return this; } diff --git a/packages/node/src/utils/kyve/kyveConnection.ts b/packages/node/src/utils/kyve/kyveConnection.ts index 67818e1ce..448e73b40 100644 --- a/packages/node/src/utils/kyve/kyveConnection.ts +++ b/packages/node/src/utils/kyve/kyveConnection.ts @@ -10,7 +10,7 @@ import { IApiConnectionSpecific, NetworkMetadataPayload, } from '@subql/node-core'; -import { CosmosClient } from '../../indexer/api.service'; +import { CosmosClient, CosmosSafeClient } from '../../indexer/api.service'; import { CosmosClientConnection } from '../../indexer/cosmosClient.connection'; import { BlockContent } from '../../indexer/types'; import { KyveApi } from './kyve'; @@ -32,14 +32,15 @@ export class KyveConnection private fetchBlocksBatches: KyveFetchFunc, chainId: string, private registry: Registry, - cosmosClient: CosmosClientConnection, + private _unsafeApi: CosmosClient, + private _safeApi: (height) => CosmosSafeClient, ) { this.networkMeta = { chain: chainId, specName: undefined, genesisHash: undefined, }; - this.unsafeApi = cosmosClient.unsafeApi; + this.unsafeApi = this._unsafeApi; } static async create( @@ -48,8 +49,9 @@ export class KyveConnection registry: Registry, storageUrl: string, kyveChainId: SupportedChains, - cosmosClient: CosmosClientConnection, tmpCacheDir: string, + unsafeApi: CosmosClient, + safeApi: (height: number) => CosmosSafeClient, ): Promise { const kyveApi = await KyveApi.create( chainId, @@ -63,7 +65,8 @@ export class KyveConnection kyveApi.fetchBlocksBatches.bind(kyveApi), chainId, registry, - cosmosClient, + unsafeApi, + safeApi, ); logger.info(`connected to Kyve via ${endpoint}`); @@ -87,8 +90,7 @@ export class KyveConnection } safeApi(height: number): any { - // provide the same logic for as unsafe api - throw new Error('SafeApi should not be used for kyve-connection'); + return this._safeApi(height); } async apiConnect(): Promise { From 8ebb313499c6718052ff610dcc0cd765243a409c Mon Sep 17 00:00:00 2001 From: bz888 Date: Thu, 11 Apr 2024 10:39:12 +0800 Subject: [PATCH 28/81] refactor fetch block funciton on api service to support kyve --- packages/node/src/indexer/api.service.ts | 54 +++++---- packages/node/src/utils/kyve/kyve.spec.ts | 24 ++-- packages/node/src/utils/kyve/kyve.ts | 19 ++-- .../node/src/utils/kyve/kyveConnection.ts | 103 ------------------ packages/node/src/yargs.ts | 2 +- 5 files changed, 62 insertions(+), 140 deletions(-) delete mode 100644 packages/node/src/utils/kyve/kyveConnection.ts diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 8dfd8a3d7..57d715be0 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -17,7 +17,6 @@ import { } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; -import { makeTempDir } from '@subql/common'; import { CosmosProjectNetConfig } from '@subql/common-cosmos'; import { getLogger, @@ -38,12 +37,14 @@ import { import { CosmosNodeConfig } from '../configure/NodeConfig'; import { SubqueryProject } from '../configure/SubqueryProject'; import * as CosmosUtil from '../utils/cosmos'; -import { KyveConnection } from '../utils/kyve/kyveConnection'; +import { KyveApi } from '../utils/kyve/kyve'; import { CosmosClientConnection } from './cosmosClient.connection'; import { BlockContent } from './types'; const logger = getLogger('api'); +const MAX_RECONNECT_ATTEMPTS = 5; + @Injectable() export class ApiService extends BaseApiService[]> @@ -51,6 +52,7 @@ export class ApiService { private fetchBlocksBatches = CosmosUtil.fetchBlocksBatches; private nodeConfig: CosmosNodeConfig; + private kyveApi: KyveApi; registry: Registry; constructor( @@ -108,28 +110,42 @@ export class ApiService ); if (this.nodeConfig.kyveEndpoint) { - // this.connectionPoolService.updateConnection() - - await this.createConnections( - network, - (endpoint) => { - return KyveConnection.create( - this.nodeConfig.kyveEndpoint, - network.chainId, - this.registry, - this.nodeConfig.kyveStorageUrl, - this.nodeConfig.kyveChainId, - this.project.root, - this.unsafeApi, - this.safeApi.bind(this), - ); - }, - (connection: KyveConnection) => Promise.resolve(network.chainId), + this.kyveApi = await KyveApi.create( + network.chainId, + this.nodeConfig.kyveEndpoint, + this.nodeConfig.kyveStorageUrl, + this.nodeConfig.kyveChainId, + this.project.root, // TODO this wont work for local ); } + return this; } + // Overrides the super function because of the kyve integration + async fetchBlocks( + heights: number[], + numAttempts = MAX_RECONNECT_ATTEMPTS, + ): Promise { + try { + if (this.kyveApi) { + return this.kyveApi.fetchBlocksBatches(this.registry, heights); + } else { + throw new Error('No kyve connection'); + } + } catch (e) { + if (e.message === 'No kyve connection') { + return this.retryFetch(async () => { + // Get the latest fetch function from the provider + const apiInstance = this.connectionPoolService.api; + return apiInstance.fetchBlocks(heights); + }, numAttempts); + } + + throw e; + } + } + get api(): CosmosClient { return this.unsafeApi; } diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index e58ee474d..b620df5fe 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -50,7 +50,7 @@ describe('KyveApi', () => { let registry: Registry; let tmpPath: string; - let retrieveBundleDataSpy: jest.SpyInstance; + let retrieveBundleDataSpy = jest.spyOn(kyveApi as any, 'retrieveBundleData'); const zipped = gzipSync(Buffer.from(JSON.stringify(block_3856726))); const mockStream = new Readable({ @@ -124,15 +124,19 @@ describe('KyveApi', () => { expect(laterBundle).toBe(113773); }); it('retrieve and unzip storage data', async () => { - const data = await (kyveApi as any).retrieveBundleData( - 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', - 100000, - ); - const unzipped = await (kyveApi as any).unzipStorageData( - '1', - data.storageData, + const id = 8; + (kyveApi as any).cachedBundleDetails = await (kyveApi as any).getBundleById( + id, ); - expect(unzipped).toBeDefined(); + + const bundleFileName = (kyveApi as any).getBundleFilePath(id); + await kyveApi.downloadAndProcessBundle(bundleFileName); + + const v = await kyveApi.readFromFile(bundleFileName); + + const b = (kyveApi as any).findBlockByHeight(1338, JSON.parse(v)); + + expect(b).toBeDefined(); }); it('Should increment bundleId when height exceeds cache', async () => { (kyveApi as any).currentBundleId = 0; @@ -222,7 +226,7 @@ describe('KyveApi', () => { ); const permissions = (stats.mode & 0o777).toString(8); - expect(permissions).toBe(444); + expect(permissions).toBe('444'); expect(r).toEqual(JSON.stringify(block_3856726)); }); describe('able to wrap kyveBlock', () => { diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index ed496e3e5..0a7b07439 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -111,8 +111,8 @@ export class KyveApi { }); } - private getBundelFileName(id: string): string { - return path.join(this.tmpCacheDir, `bundle_${id}`); + private getBundleFilePath(id: string): string { + return path.join(this.tmpCacheDir, `bundle_${id}.json`); } private async getBundleById(bundleId: number): Promise { @@ -204,6 +204,12 @@ export class KyveApi { } return JSON.parse(await this.getFileCacheData()); + } else { + return JSON.parse( + await this.readFromFile( + this.getBundleFilePath(this.cachedBundleDetails.id), + ), + ); } } @@ -235,12 +241,11 @@ export class KyveApi { await new Promise((resolve, reject) => { zippedBundleData.data + .on('error', (err) => reject(err)) .pipe(gunzip) - .on('error', reject) + .on('error', (err) => reject(err)) .pipe(writeStream) - .on('error', (err) => { - reject(err); - }) + .on('error', (err) => reject(err)) .on('finish', resolve); }); @@ -248,7 +253,7 @@ export class KyveApi { } async getFileCacheData(): Promise { - const bundleFilePath = this.getBundelFileName(this.cachedBundleDetails.id); + const bundleFilePath = this.getBundleFilePath(this.cachedBundleDetails.id); try { await this.downloadAndProcessBundle(bundleFilePath); diff --git a/packages/node/src/utils/kyve/kyveConnection.ts b/packages/node/src/utils/kyve/kyveConnection.ts deleted file mode 100644 index 448e73b40..000000000 --- a/packages/node/src/utils/kyve/kyveConnection.ts +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors -// SPDX-License-Identifier: GPL-3.0 - -import { Registry } from '@cosmjs/proto-signing'; -import { SupportedChains } from '@kyvejs/sdk/src/constants'; -import { - ApiConnectionError, - ApiErrorType, - getLogger, - IApiConnectionSpecific, - NetworkMetadataPayload, -} from '@subql/node-core'; -import { CosmosClient, CosmosSafeClient } from '../../indexer/api.service'; -import { CosmosClientConnection } from '../../indexer/cosmosClient.connection'; -import { BlockContent } from '../../indexer/types'; -import { KyveApi } from './kyve'; - -const logger = getLogger('kyve-API'); - -type KyveFetchFunc = ( - registry: Registry, - batch: number[], -) => Promise; - -export class KyveConnection - implements IApiConnectionSpecific -{ - unsafeApi: CosmosClient; - readonly networkMeta: NetworkMetadataPayload; - - private constructor( - private fetchBlocksBatches: KyveFetchFunc, - chainId: string, - private registry: Registry, - private _unsafeApi: CosmosClient, - private _safeApi: (height) => CosmosSafeClient, - ) { - this.networkMeta = { - chain: chainId, - specName: undefined, - genesisHash: undefined, - }; - this.unsafeApi = this._unsafeApi; - } - - static async create( - endpoint: string, // kyve LCD Endpoint - chainId: string, - registry: Registry, - storageUrl: string, - kyveChainId: SupportedChains, - tmpCacheDir: string, - unsafeApi: CosmosClient, - safeApi: (height: number) => CosmosSafeClient, - ): Promise { - const kyveApi = await KyveApi.create( - chainId, - endpoint, - storageUrl, - kyveChainId, - tmpCacheDir, - ); - - const connection = new KyveConnection( - kyveApi.fetchBlocksBatches.bind(kyveApi), - chainId, - registry, - unsafeApi, - safeApi, - ); - - logger.info(`connected to Kyve via ${endpoint}`); - - return connection; - } - - async fetchBlocks(heights: number[]): Promise { - const blocks = await this.fetchBlocksBatches(this.registry, heights); - return blocks; - } - - handleError = KyveConnection.handleError; - - static handleError(error: Error): ApiConnectionError { - return new ApiConnectionError( - 'KyveError', - error.message, - ApiErrorType.Default, - ); - } - - safeApi(height: number): any { - return this._safeApi(height); - } - - async apiConnect(): Promise { - return Promise.resolve(); - } - - async apiDisconnect(): Promise { - return Promise.resolve(); - } -} diff --git a/packages/node/src/yargs.ts b/packages/node/src/yargs.ts index 13ef20130..e59378528 100644 --- a/packages/node/src/yargs.ts +++ b/packages/node/src/yargs.ts @@ -35,7 +35,7 @@ export const yargsOptions = yargsBuilder({ 'If indexing a network that Kyve supports adding a Kyve LCD endpoint will fetch blocks from Kyve', type: 'string', }, - 'storage-url': { + 'kyve-storage-url': { demandOption: false, describe: 'When indexing from kyve, you can alternatively provide a different storageUrl to index data from, it is defaulted to arweave.', From c5e36571ef3beca5c3deed8ca8ccfc9adaeb4a89 Mon Sep 17 00:00:00 2001 From: bz888 Date: Thu, 11 Apr 2024 11:10:47 +0800 Subject: [PATCH 29/81] update tests --- packages/node/src/utils/kyve/kyve.spec.ts | 40 ++++++++++++++++------- packages/node/src/utils/kyve/kyve.ts | 5 +-- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index b620df5fe..5105f44b1 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -5,7 +5,7 @@ import fs from 'fs'; import path from 'path'; import { Readable } from 'stream'; import { promisify } from 'util'; -import { gunzipSync, gzipSync } from 'zlib'; +import { gzipSync } from 'zlib'; import { GeneratedType, Registry } from '@cosmjs/proto-signing'; import { defaultRegistryTypes } from '@cosmjs/stargate'; import { Tendermint37Client } from '@cosmjs/tendermint-rpc'; @@ -13,6 +13,7 @@ import { BlockResponse, BlockResultsResponse, } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; +import KyveSDK from '@kyvejs/sdk'; import { makeTempDir } from '@subql/common'; import { MsgClearAdmin, @@ -22,7 +23,7 @@ import { MsgStoreCode, MsgUpdateAdmin, } from 'cosmjs-types/cosmwasm/wasm/v1/tx'; -import { isEqual, toLower } from 'lodash'; +import { isEqual } from 'lodash'; import rimraf from 'rimraf'; import { HttpClient } from '../../indexer/rpc-clients'; import { LazyBlockContent } from '../cosmos'; @@ -43,6 +44,10 @@ const kyveBundlePath = path.join( ); const block_3856726 = require(kyveBundlePath); +const KYVE_ENDPOINT = 'https://rpc-eu-1.kyve.network'; +const KYVE_STORAGE_URL = 'https://arweave.net'; +const KYVE_CHAINID = 'kyve-1'; + jest.setTimeout(100000); describe('KyveApi', () => { let kyveApi: KyveApi; @@ -50,7 +55,7 @@ describe('KyveApi', () => { let registry: Registry; let tmpPath: string; - let retrieveBundleDataSpy = jest.spyOn(kyveApi as any, 'retrieveBundleData'); + let retrieveBundleDataSpy: jest.SpyInstance; const zipped = gzipSync(Buffer.from(JSON.stringify(block_3856726))); const mockStream = new Readable({ @@ -66,13 +71,14 @@ describe('KyveApi', () => { registry = new Registry([...defaultRegistryTypes, ...wasmTypes]); kyveApi = await KyveApi.create( 'archway-1', - 'https://rpc-eu-1.kyve.network', - 'https://arweave.net', - 'kyve-1', + KYVE_ENDPOINT, + KYVE_STORAGE_URL, + KYVE_CHAINID, tmpPath, ); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); + retrieveBundleDataSpy = jest.spyOn(kyveApi as any, 'retrieveBundleData'); }); afterEach(() => { @@ -85,7 +91,7 @@ describe('KyveApi', () => { retrieveBundleDataSpy.mockRestore(); }); afterAll(async () => { - // await promisify(rimraf)(tmpPath); + await promisify(rimraf)(tmpPath); }); it('ensure bundleDetails', async () => { @@ -155,9 +161,14 @@ describe('KyveApi', () => { const [kyveBlockInfo] = await kyveApi.getBlockByHeight(height); expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); }); - it('determine correct pool', () => { - expect((kyveApi as any).poolId).toBe('2'); - expect((kyveApi as any).chainId).toBe('archway-1'); + it('determine correct pool', async () => { + const lcdClient = new KyveSDK(KYVE_CHAINID, { + rpc: KYVE_ENDPOINT, + }).createLCDClient(); + + const poolId = await KyveApi.fetchPoolId('archway-1', lcdClient); + + expect(poolId).toBe('2'); }); it('able to update and clear file cache', async () => { const checkFileExist = async (filePath: string) => { @@ -218,12 +229,17 @@ describe('KyveApi', () => { expect(pollSpy).toHaveBeenCalled(); const r = await kyveApi.readFromFile( - path.join(tmpPath, `bundle_${(kyveApi as any).cachedBundleDetails.id}`), + (kyveApi as any).getBundleFilePath( + (kyveApi as any).cachedBundleDetails.id, + ), ); const stats = await fs.promises.stat( - path.join(tmpPath, `bundle_${(kyveApi as any).cachedBundleDetails.id}`), + (kyveApi as any).getBundleFilePath( + (kyveApi as any).cachedBundleDetails.id, + ), ); + const permissions = (stats.mode & 0o777).toString(8); expect(permissions).toBe('444'); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 0a7b07439..1a8cea236 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -15,10 +15,7 @@ import { } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; // Currently these types are not exported -import { - PoolResponse, - QueryPoolsResponse, -} from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; +import { QueryPoolsResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; import { delay, getLogger } from '@subql/node-core'; import axios, { AxiosResponse } from 'axios'; import { BlockContent } from '../../indexer/types'; From dc371fe16f331468a7def6143c3c39138a67aef1 Mon Sep 17 00:00:00 2001 From: bz888 Date: Thu, 11 Apr 2024 11:30:09 +0800 Subject: [PATCH 30/81] fix mock stream tests --- packages/node/src/utils/kyve/kyve.spec.ts | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 5105f44b1..6b19c8db4 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -57,13 +57,8 @@ describe('KyveApi', () => { let tmpPath: string; let retrieveBundleDataSpy: jest.SpyInstance; - const zipped = gzipSync(Buffer.from(JSON.stringify(block_3856726))); - const mockStream = new Readable({ - read() { - this.push(zipped); - this.push(null); - }, - }); + let zippedMockResp: Buffer; + let mockStream: Readable; beforeAll(async () => { tmpPath = await makeTempDir(); @@ -80,6 +75,15 @@ describe('KyveApi', () => { tendermint = await Tendermint37Client.create(client); retrieveBundleDataSpy = jest.spyOn(kyveApi as any, 'retrieveBundleData'); }); + beforeEach(() => { + zippedMockResp = gzipSync(Buffer.from(JSON.stringify(block_3856726))); + mockStream = new Readable({ + read() { + this.push(zippedMockResp); + this.push(null); + }, + }); + }); afterEach(() => { // reset cache @@ -204,7 +208,7 @@ describe('KyveApi', () => { ).resolves.toBe(false); expect(clearFileSpy).toHaveBeenCalledTimes(1); }); - it('able to download and write to file', async () => { + it('able to download and write to file, with simulated workers', async () => { (kyveApi as any).cachedBundleDetails = await (kyveApi as any).getBundleById( 1, ); From f62e1b0ed16e71f7fd089d336b3b390bb60bb5e4 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 12 Apr 2024 06:39:47 +0800 Subject: [PATCH 31/81] update workers fetch module and changelog --- packages/node/CHANGELOG.md | 6 +++--- packages/node/src/indexer/worker/worker-fetch.module.ts | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/node/CHANGELOG.md b/packages/node/CHANGELOG.md index ae70e9370..1ee533189 100644 --- a/packages/node/CHANGELOG.md +++ b/packages/node/CHANGELOG.md @@ -7,9 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Support for KYVE integration with supporting flags (#235) - - `--kyveEndpoint` - - `--kyveChainId` - - `--storageUrl` + - `--kyve-endpoint` + - `--kyve-chain-id` + - `--kyve-storage-url` ## [3.10.0] - 2024-04-10 ### Changed diff --git a/packages/node/src/indexer/worker/worker-fetch.module.ts b/packages/node/src/indexer/worker/worker-fetch.module.ts index 7c6840fa7..437b0d327 100644 --- a/packages/node/src/indexer/worker/worker-fetch.module.ts +++ b/packages/node/src/indexer/worker/worker-fetch.module.ts @@ -50,7 +50,12 @@ import { WorkerUnfinalizedBlocksService } from './worker.unfinalizedBlocks.servi await apiService.init(); return apiService; }, - inject: ['ISubqueryProject', ConnectionPoolService, EventEmitter2], + inject: [ + 'ISubqueryProject', + ConnectionPoolService, + EventEmitter2, + NodeConfig, + ], }, SandboxService, DsProcessorService, From 1ac6fada1268ed87cd0d8d46c945ba7fa2b772b8 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 12 Apr 2024 08:15:35 +0800 Subject: [PATCH 32/81] rebase main --- packages/node/src/indexer/api.service.ts | 4 +- .../src/indexer/cosmosClient.connection.ts | 9 +- packages/node/src/init.ts | 1 - packages/node/src/utils/kyve/kyve.ts | 24 +- yarn.lock | 4837 ++++++++++++++++- 5 files changed, 4623 insertions(+), 252 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 57d715be0..5552f9b73 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -4,7 +4,7 @@ import { CosmWasmClient, IndexedTx } from '@cosmjs/cosmwasm-stargate'; import { toHex } from '@cosmjs/encoding'; import { Uint53 } from '@cosmjs/math'; -import { DecodeObject, GeneratedType, Registry } from '@cosmjs/proto-signing'; +import { GeneratedType, Registry } from '@cosmjs/proto-signing'; import { Block, defaultRegistryTypes, SearchTxQuery } from '@cosmjs/stargate'; import { Tendermint37Client, @@ -126,7 +126,7 @@ export class ApiService async fetchBlocks( heights: number[], numAttempts = MAX_RECONNECT_ATTEMPTS, - ): Promise { + ): Promise[]> { try { if (this.kyveApi) { return this.kyveApi.fetchBlocksBatches(this.registry, heights); diff --git a/packages/node/src/indexer/cosmosClient.connection.ts b/packages/node/src/indexer/cosmosClient.connection.ts index cb0e1a224..35b40d008 100644 --- a/packages/node/src/indexer/cosmosClient.connection.ts +++ b/packages/node/src/indexer/cosmosClient.connection.ts @@ -17,7 +17,6 @@ import { CosmosEvent, CosmosTransaction, } from '@subql/types-cosmos'; -import { wrapEvent } from '../utils/cosmos'; import { CosmosClient, CosmosSafeClient } from './api.service'; import { HttpClient, WebsocketClient } from './rpc-clients'; import { BlockContent } from './types'; @@ -30,14 +29,8 @@ const RETRY_DELAY = 2_500; const logger = getLogger('cosmos-client-connection'); type FetchFunc = ( - batch: number[], api: CosmosClient, - wrapEventsFunc: ( - block: CosmosBlock, - txs: CosmosTransaction[], - registry: Registry, - eventIdx: number, - ) => CosmosEvent[], + batch: number[], ) => Promise[]>; export class CosmosClientConnection diff --git a/packages/node/src/init.ts b/packages/node/src/init.ts index 45295bff8..535a50073 100644 --- a/packages/node/src/init.ts +++ b/packages/node/src/init.ts @@ -63,7 +63,6 @@ export async function bootstrap(): Promise { logger.info(`Node started on port: ${port}`); } catch (e) { - console.trace(e); logger.error(e, 'Node failed to start'); process.exit(1); } diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 1a8cea236..b81d2da38 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -7,8 +7,8 @@ import path from 'path'; import * as zlib from 'zlib'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; import { Registry } from '@cosmjs/proto-signing'; -import { Log } from '@cosmjs/stargate/build/logs'; -import { adaptor37 } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; +import { logs } from '@cosmjs/stargate'; +import { Responses } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; // adaptor is not exported import { BlockResponse, BlockResultsResponse, @@ -16,10 +16,10 @@ import { import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; // Currently these types are not exported import { QueryPoolsResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; -import { delay, getLogger } from '@subql/node-core'; +import { delay, getLogger, IBlock } from '@subql/node-core'; import axios, { AxiosResponse } from 'axios'; import { BlockContent } from '../../indexer/types'; -import { LazyBlockContent } from '../cosmos'; +import { formatBlockUtil, LazyBlockContent } from '../cosmos'; import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms @@ -91,7 +91,7 @@ export class KyveApi { } private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { - return adaptor37.responses.decodeBlock({ + return Responses.decodeBlock({ id: 1, jsonrpc: '2.0', result: block, @@ -101,7 +101,7 @@ export class KyveApi { private decodeBlockResult( blockResult: JsonRpcSuccessResponse, ): BlockResultsResponse { - return adaptor37.responses.decodeBlockResults({ + return Responses.decodeBlockResults({ id: 1, jsonrpc: '2.0', result: blockResult, @@ -310,8 +310,10 @@ export class KyveApi { return kyveBlockResult; } - private reconstructLogs(blockResultResponse: BlockResultsResponse): Log[] { - const logs: Log[] = []; + private reconstructLogs( + blockResultResponse: BlockResultsResponse, + ): logs.Log[] { + const logs: logs.Log[] = []; for (const tx of blockResultResponse.results) { let currentLog: any = { @@ -371,7 +373,7 @@ export class KyveApi { async fetchBlocksBatches( registry: Registry, blockArray: number[], - ): Promise { + ): Promise[]> { const blocks = await this.fetchBlocksArray(blockArray); return blocks.map(([blockInfo, blockResults]) => { try { @@ -380,7 +382,9 @@ export class KyveApi { `txInfos doesn't match up with block (${blockInfo.block.header.height}) transactions expected ${blockInfo.block.txs.length}, received: ${blockResults.results.length}`, ); - return new LazyBlockContent(blockInfo, blockResults, registry); + return formatBlockUtil( + new LazyBlockContent(blockInfo, blockResults, registry), + ); } catch (e) { logger.error( e, diff --git a/yarn.lock b/yarn.lock index 95ce57613..2b18810a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -148,6 +148,706 @@ __metadata: languageName: node linkType: hard +"@aws-crypto/crc32@npm:3.0.0": + version: 3.0.0 + resolution: "@aws-crypto/crc32@npm:3.0.0" + dependencies: + "@aws-crypto/util": ^3.0.0 + "@aws-sdk/types": ^3.222.0 + tslib: ^1.11.1 + checksum: 9fdb3e837fc54119b017ea34fd0a6d71d2c88075d99e1e818a5158e0ad30ced67ddbcc423a11ceeef6cc465ab5ffd91830acab516470b48237ca7abd51be9642 + languageName: node + linkType: hard + +"@aws-crypto/crc32c@npm:3.0.0": + version: 3.0.0 + resolution: "@aws-crypto/crc32c@npm:3.0.0" + dependencies: + "@aws-crypto/util": ^3.0.0 + "@aws-sdk/types": ^3.222.0 + tslib: ^1.11.1 + checksum: 0a116b5d1c5b09a3dde65aab04a07b32f543e87b68f2d175081e3f4a1a17502343f223d691dd883ace1ddce65cd40093673e7c7415dcd99062202ba87ffb4038 + languageName: node + linkType: hard + +"@aws-crypto/ie11-detection@npm:^3.0.0": + version: 3.0.0 + resolution: "@aws-crypto/ie11-detection@npm:3.0.0" + dependencies: + tslib: ^1.11.1 + checksum: 299b2ddd46eddac1f2d54d91386ceb37af81aef8a800669281c73d634ed17fd855dcfb8b3157f2879344b93a2666a6d602550eb84b71e4d7868100ad6da8f803 + languageName: node + linkType: hard + +"@aws-crypto/sha1-browser@npm:3.0.0": + version: 3.0.0 + resolution: "@aws-crypto/sha1-browser@npm:3.0.0" + dependencies: + "@aws-crypto/ie11-detection": ^3.0.0 + "@aws-crypto/supports-web-crypto": ^3.0.0 + "@aws-crypto/util": ^3.0.0 + "@aws-sdk/types": ^3.222.0 + "@aws-sdk/util-locate-window": ^3.0.0 + "@aws-sdk/util-utf8-browser": ^3.0.0 + tslib: ^1.11.1 + checksum: 78c379e105a0c4e7b2ed745dffd8f55054d7dde8b350b61de682bbc3cd081a50e2f87861954fa9cd53c7ea711ebca1ca0137b14cb36483efc971f60f573cf129 + languageName: node + linkType: hard + +"@aws-crypto/sha256-browser@npm:3.0.0": + version: 3.0.0 + resolution: "@aws-crypto/sha256-browser@npm:3.0.0" + dependencies: + "@aws-crypto/ie11-detection": ^3.0.0 + "@aws-crypto/sha256-js": ^3.0.0 + "@aws-crypto/supports-web-crypto": ^3.0.0 + "@aws-crypto/util": ^3.0.0 + "@aws-sdk/types": ^3.222.0 + "@aws-sdk/util-locate-window": ^3.0.0 + "@aws-sdk/util-utf8-browser": ^3.0.0 + tslib: ^1.11.1 + checksum: ca89456bf508db2e08060a7f656460db97ac9a15b11e39d6fa7665e2b156508a1758695bff8e82d0a00178d6ac5c36f35eb4bcfac2e48621265224ca14a19bd2 + languageName: node + linkType: hard + +"@aws-crypto/sha256-js@npm:3.0.0, @aws-crypto/sha256-js@npm:^3.0.0": + version: 3.0.0 + resolution: "@aws-crypto/sha256-js@npm:3.0.0" + dependencies: + "@aws-crypto/util": ^3.0.0 + "@aws-sdk/types": ^3.222.0 + tslib: ^1.11.1 + checksum: 644ded32ea310237811afae873d3c7320739cb6f6cc39dced9c94801379e68e5ee2cca0c34f0384793fa9e750a7e0a5e2468f95754bd08e6fd72ab833c8fe23c + languageName: node + linkType: hard + +"@aws-crypto/supports-web-crypto@npm:^3.0.0": + version: 3.0.0 + resolution: "@aws-crypto/supports-web-crypto@npm:3.0.0" + dependencies: + tslib: ^1.11.1 + checksum: 35479a1558db9e9a521df6877a99f95670e972c602f2a0349303477e5d638a5baf569fb037c853710e382086e6fd77e8ed58d3fb9b49f6e1186a9d26ce7be006 + languageName: node + linkType: hard + +"@aws-crypto/util@npm:^3.0.0": + version: 3.0.0 + resolution: "@aws-crypto/util@npm:3.0.0" + dependencies: + "@aws-sdk/types": ^3.222.0 + "@aws-sdk/util-utf8-browser": ^3.0.0 + tslib: ^1.11.1 + checksum: d29d5545048721aae3d60b236708535059733019a105f8a64b4e4a8eab7cf8dde1546dc56bff7de20d36140a4d1f0f4693e639c5732a7059273a7b1e56354776 + languageName: node + linkType: hard + +"@aws-sdk/client-s3@npm:^3.370.0": + version: 3.554.0 + resolution: "@aws-sdk/client-s3@npm:3.554.0" + dependencies: + "@aws-crypto/sha1-browser": 3.0.0 + "@aws-crypto/sha256-browser": 3.0.0 + "@aws-crypto/sha256-js": 3.0.0 + "@aws-sdk/client-sts": 3.554.0 + "@aws-sdk/core": 3.554.0 + "@aws-sdk/credential-provider-node": 3.554.0 + "@aws-sdk/middleware-bucket-endpoint": 3.535.0 + "@aws-sdk/middleware-expect-continue": 3.535.0 + "@aws-sdk/middleware-flexible-checksums": 3.535.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-location-constraint": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-sdk-s3": 3.552.0 + "@aws-sdk/middleware-signing": 3.552.0 + "@aws-sdk/middleware-ssec": 3.537.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/signature-v4-multi-region": 3.552.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@aws-sdk/xml-builder": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/eventstream-serde-browser": ^2.2.0 + "@smithy/eventstream-serde-config-resolver": ^2.2.0 + "@smithy/eventstream-serde-node": ^2.2.0 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-blob-browser": ^2.2.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/hash-stream-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/md5-js": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-stream": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + "@smithy/util-waiter": ^2.2.0 + tslib: ^2.6.2 + checksum: bf5b0bd41af005e2acc3565b28410bc49bb150750d7ec3037040b0baaf6a594b760336f4a4aa7d434c80ff134e3e717c46c8187ebd2d872c199cbc85b934baf4 + languageName: node + linkType: hard + +"@aws-sdk/client-sso-oidc@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/client-sso-oidc@npm:3.554.0" + dependencies: + "@aws-crypto/sha256-browser": 3.0.0 + "@aws-crypto/sha256-js": 3.0.0 + "@aws-sdk/client-sts": 3.554.0 + "@aws-sdk/core": 3.554.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + peerDependencies: + "@aws-sdk/credential-provider-node": ^3.554.0 + checksum: 91d0f6b8c5c787e2b705803d615f9400430ea0bca9d12171a5e7abe5c53cd83f711300e5c0a106dc4f1f1259adf08f87b728f9820679aa5ca73cd66a09bf8dd4 + languageName: node + linkType: hard + +"@aws-sdk/client-sso@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/client-sso@npm:3.554.0" + dependencies: + "@aws-crypto/sha256-browser": 3.0.0 + "@aws-crypto/sha256-js": 3.0.0 + "@aws-sdk/core": 3.554.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 08dbaca87bb25d7662a2e856dca16f92bc461b9cf50e048c679969df93189f653c2bc74c8be1ac3e82e720d2742fc81af554a04f0ebf83353c1fa6e30fdbbecf + languageName: node + linkType: hard + +"@aws-sdk/client-sts@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/client-sts@npm:3.554.0" + dependencies: + "@aws-crypto/sha256-browser": 3.0.0 + "@aws-crypto/sha256-js": 3.0.0 + "@aws-sdk/core": 3.554.0 + "@aws-sdk/middleware-host-header": 3.535.0 + "@aws-sdk/middleware-logger": 3.535.0 + "@aws-sdk/middleware-recursion-detection": 3.535.0 + "@aws-sdk/middleware-user-agent": 3.540.0 + "@aws-sdk/region-config-resolver": 3.535.0 + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@aws-sdk/util-user-agent-browser": 3.535.0 + "@aws-sdk/util-user-agent-node": 3.535.0 + "@smithy/config-resolver": ^2.2.0 + "@smithy/core": ^1.4.2 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/hash-node": ^2.2.0 + "@smithy/invalid-dependency": ^2.2.0 + "@smithy/middleware-content-length": ^2.2.0 + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-body-length-browser": ^2.2.0 + "@smithy/util-body-length-node": ^2.3.0 + "@smithy/util-defaults-mode-browser": ^2.2.1 + "@smithy/util-defaults-mode-node": ^2.3.1 + "@smithy/util-endpoints": ^1.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + peerDependencies: + "@aws-sdk/credential-provider-node": ^3.554.0 + checksum: dee932b55e89f9b68275d21861f534ae1cdf006410841fe84bab38df12253ebafd4928e440d6243391c3234f2509b943628c5368d2bcd0489ea240464d65edc6 + languageName: node + linkType: hard + +"@aws-sdk/core@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/core@npm:3.554.0" + dependencies: + "@smithy/core": ^1.4.2 + "@smithy/protocol-http": ^3.3.0 + "@smithy/signature-v4": ^2.2.1 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + fast-xml-parser: 4.2.5 + tslib: ^2.6.2 + checksum: 61e48deee6146aa92fca14f787dfcfe1ef91e0b9feda897d375174643071119aa5b0d51185f9a23843a8aaa82372187af4bb6aa9489e20b1fc651c1734592b40 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-env@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/credential-provider-env@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: ec7d011051d69643efd26fe7f3767b1301c6e6bdba12640dad542b60efb2b5fe31df01f8137703d814cf857a69485cc928d0de49ab56c5d05f79815dce19bdbf + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-http@npm:3.552.0": + version: 3.552.0 + resolution: "@aws-sdk/credential-provider-http@npm:3.552.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-stream": ^2.2.0 + tslib: ^2.6.2 + checksum: 86be07b2a0c73b5c1140557e00b08c091303da1908ff40a29bcc69b73bf4ad175a5ad945e0d45d5c76b02bee3f15a947abb18838b2771ad71feb795a5309a446 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-ini@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/credential-provider-ini@npm:3.554.0" + dependencies: + "@aws-sdk/client-sts": 3.554.0 + "@aws-sdk/credential-provider-env": 3.535.0 + "@aws-sdk/credential-provider-process": 3.535.0 + "@aws-sdk/credential-provider-sso": 3.554.0 + "@aws-sdk/credential-provider-web-identity": 3.554.0 + "@aws-sdk/types": 3.535.0 + "@smithy/credential-provider-imds": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 5b93ba3d3cf98cd0738b871db1036303ab0b05538171a650168aefc0071a1e51e4bbd0b88d06047b6170fbf20417069beb29d8f71cae13d87c4e17c736a5a252 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-node@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/credential-provider-node@npm:3.554.0" + dependencies: + "@aws-sdk/credential-provider-env": 3.535.0 + "@aws-sdk/credential-provider-http": 3.552.0 + "@aws-sdk/credential-provider-ini": 3.554.0 + "@aws-sdk/credential-provider-process": 3.535.0 + "@aws-sdk/credential-provider-sso": 3.554.0 + "@aws-sdk/credential-provider-web-identity": 3.554.0 + "@aws-sdk/types": 3.535.0 + "@smithy/credential-provider-imds": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: b8dfbbace2c279792934057de6879d47fb95b5c068aed0938f5c104b79034982b04e34739dba78274c9fabaf97f6079a9938ff3b01765fc3042b15abbf273190 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-process@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/credential-provider-process@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: af5fad70513e8d0bc10013f220588e45e83d488e0780873d7e76bf5b7099e70c9b4e49b6409d16add64ae212c53a472b12a2178e8bafd7878fdf121d6e2fd112 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-sso@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/credential-provider-sso@npm:3.554.0" + dependencies: + "@aws-sdk/client-sso": 3.554.0 + "@aws-sdk/token-providers": 3.554.0 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 0665748fce2ef6c4572570be35af31a55cee3fa3be49ef7a15be9e25ac54d3528c5a0b82c9672b7e147a9114525aeef7d9bb2a9270ef3d3e09de91d940da3779 + languageName: node + linkType: hard + +"@aws-sdk/credential-provider-web-identity@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.554.0" + dependencies: + "@aws-sdk/client-sts": 3.554.0 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: e47772ca693bb2a0b02a1bf1b7ce288fd141510e944145d3188f532feffa3f7511f037ed5203c581764ab9d397c358c63baf28f3cf96bbce98c303ed7b9f1a2a + languageName: node + linkType: hard + +"@aws-sdk/middleware-bucket-endpoint@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-bucket-endpoint@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-arn-parser": 3.535.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-config-provider": ^2.3.0 + tslib: ^2.6.2 + checksum: d72dfd197dc9aa1ed8ea3de6fb0a18363688fa8e18f6a9d01cb2f425087c5b72aa4bfd0955715c84da86adf9a46029755cff55a02a6ffbf4459009982a5a5415 + languageName: node + linkType: hard + +"@aws-sdk/middleware-expect-continue@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-expect-continue@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: fdac9bc59833ca9688155f115f85c31f690df5ef690e9a8921b94b87c4faac3eb3ff10641699822faaaf9a6cc4ce4c67e693a7b4befe8baf8138a9d276d6714d + languageName: node + linkType: hard + +"@aws-sdk/middleware-flexible-checksums@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-flexible-checksums@npm:3.535.0" + dependencies: + "@aws-crypto/crc32": 3.0.0 + "@aws-crypto/crc32c": 3.0.0 + "@aws-sdk/types": 3.535.0 + "@smithy/is-array-buffer": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 14c04cd932bdb9029466079b248c1fa8222183de4c288bf12ad661cdc7717938485fdb973b7948da729e5be218573cfd2cbe74b51a1bc2bd27131ca7d67909c1 + languageName: node + linkType: hard + +"@aws-sdk/middleware-host-header@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-host-header@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 13a22a5b19912a86fe872c9c0f6ba9ab758ba9483ce9a2e73fa68acae498b68404e38e7fc1e3962639a6c3f80ebe19ea5c5340e1024e11ab417998696c8a5dca + languageName: node + linkType: hard + +"@aws-sdk/middleware-location-constraint@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-location-constraint@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 4e89b6c5d4253568e599f0e8be37e80cf12a755ba89b89d9c9ae2ced75213850c41922fa1871a9c92345057e15d5db956a353841eb63353d8f2bb69a61d4a10d + languageName: node + linkType: hard + +"@aws-sdk/middleware-logger@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-logger@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: e264d05aa88fadd94d17000b1df79bf1931c5fbc2c871616de9b836bab7254d8c21e0fc2ac509a07af578bd823b795efafaf48daca805bc4493986288ed0c4ab + languageName: node + linkType: hard + +"@aws-sdk/middleware-recursion-detection@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/middleware-recursion-detection@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: b6b518243a10dcdcea7c1fd4790cf2e1e0e3d4363ebce51ac364c9b15631a6f3d1db44d00e7c75cbdf1d558a0d868583d6e1853e571e15e23d0d2901f168e2e4 + languageName: node + linkType: hard + +"@aws-sdk/middleware-sdk-s3@npm:3.552.0": + version: 3.552.0 + resolution: "@aws-sdk/middleware-sdk-s3@npm:3.552.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-arn-parser": 3.535.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/signature-v4": ^2.2.1 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-config-provider": ^2.3.0 + tslib: ^2.6.2 + checksum: 386a6dc3bda4574a6a306ca09e22ff7dca3816edd5c364769850226f7ada5ce6a1e370f1f6fc4885342c55e6ef8283b095093d22bc2462b555f0916b41ab3247 + languageName: node + linkType: hard + +"@aws-sdk/middleware-signing@npm:3.552.0": + version: 3.552.0 + resolution: "@aws-sdk/middleware-signing@npm:3.552.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/signature-v4": ^2.2.1 + "@smithy/types": ^2.12.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: d46fa3f0a03cbbccd6f4435faed5722a80745ca65a99dd0dc9e9ea9235bfb59b6bbc3cae301d07694d981d8905d6e4c707c9653d0004b6ecf87e52a324165024 + languageName: node + linkType: hard + +"@aws-sdk/middleware-ssec@npm:3.537.0": + version: 3.537.0 + resolution: "@aws-sdk/middleware-ssec@npm:3.537.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 7a963134cab4c9056d249113f6d5e2847be28847fc8c39b943c487ff5d22b9b1d91092e801694e2da95929a4820c45f6b5afc22c655a6dcfb5eb82e44952de14 + languageName: node + linkType: hard + +"@aws-sdk/middleware-user-agent@npm:3.540.0": + version: 3.540.0 + resolution: "@aws-sdk/middleware-user-agent@npm:3.540.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@aws-sdk/util-endpoints": 3.540.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 7ee609fb2b669f93657a87c291dff17f8315973ddbbeee36c54a0233b4911091916880f6e27da93fef01e5fd53654b3834a68cf74256b88b1c4dbe5880a4c14f + languageName: node + linkType: hard + +"@aws-sdk/region-config-resolver@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/region-config-resolver@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-config-provider": ^2.3.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: 7b556e47c721c0829ae635203a1dbcab7040e2885d2bdc37898eb3139dabb5f6da580b860202e3b7737330bfc02de5084a98ff8f8b5c36adcfe8e076b82d3487 + languageName: node + linkType: hard + +"@aws-sdk/signature-v4-multi-region@npm:3.552.0": + version: 3.552.0 + resolution: "@aws-sdk/signature-v4-multi-region@npm:3.552.0" + dependencies: + "@aws-sdk/middleware-sdk-s3": 3.552.0 + "@aws-sdk/types": 3.535.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/signature-v4": ^2.2.1 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: b0faf043028a8cbbf7d1ab76caf8e681c9e0e08a57ae8caff529e5e228765793da47830abd65301e379bdd1236b0a827dcf732a189ffba6723098bf9ed3b0349 + languageName: node + linkType: hard + +"@aws-sdk/token-providers@npm:3.554.0": + version: 3.554.0 + resolution: "@aws-sdk/token-providers@npm:3.554.0" + dependencies: + "@aws-sdk/client-sso-oidc": 3.554.0 + "@aws-sdk/types": 3.535.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: ff6e13ab91ac9d5e0f7de8673a16b541b41dc445c7ec3dae66d85e47514c808ed059af4702156b437c4d2a510d378a83662ee988a853cdf2625cde886fe962cb + languageName: node + linkType: hard + +"@aws-sdk/types@npm:3.535.0, @aws-sdk/types@npm:^3.222.0": + version: 3.535.0 + resolution: "@aws-sdk/types@npm:3.535.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 3f735c78ea3a6f37d05387286f6d18b0e5deb41442095bd2f7c27b000659962872d1c801fa8484a6ac4b7d2725b2e176dc628c3fa2a903a3141d4be76488d48f + languageName: node + linkType: hard + +"@aws-sdk/util-arn-parser@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/util-arn-parser@npm:3.535.0" + dependencies: + tslib: ^2.6.2 + checksum: 0e4c4ea080c7c6da00d359c337a1f9d961eac20c35cebad9cb6bb9b618f981955643990de7bfd6b53c29367a6d33550fe27b2a7539efdff08e01bdd303f0c5c2 + languageName: node + linkType: hard + +"@aws-sdk/util-endpoints@npm:3.540.0": + version: 3.540.0 + resolution: "@aws-sdk/util-endpoints@npm:3.540.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + "@smithy/util-endpoints": ^1.2.0 + tslib: ^2.6.2 + checksum: 62312773965480f8df5edb62ecf82ab3e54d5aa1b1f7eebdad78a2925eab47218b0268bc25a5d03598ac4d0c08935733031a2e3e1ce72531535ed1ea8a9b56c3 + languageName: node + linkType: hard + +"@aws-sdk/util-locate-window@npm:^3.0.0": + version: 3.535.0 + resolution: "@aws-sdk/util-locate-window@npm:3.535.0" + dependencies: + tslib: ^2.6.2 + checksum: b421e1b08adfdd0e51c73a0b244a67188e745b870da712560d8edb28c41076f9dc94c24577bb9d07ea1f04e8ee6b543f00d1ae0617db8d729f16588238fbebae + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-browser@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/util-user-agent-browser@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/types": ^2.12.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 148b82900e4b9efd24f5fc4152a8d6010c90eb019517fa3c00c3ac42205055f7611ef3834fb63397def40e600ea20f901177a7dd5b6aefa2aef4208e994f7d90 + languageName: node + linkType: hard + +"@aws-sdk/util-user-agent-node@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/util-user-agent-node@npm:3.535.0" + dependencies: + "@aws-sdk/types": 3.535.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: f214c406fccde14591d1df25fed662e573510cdf1d5829d22e7a93e517ea4a3905acd123eaaeafdb8b217400e8c8e159231d37be02b67307922023996b398f42 + languageName: node + linkType: hard + +"@aws-sdk/util-utf8-browser@npm:^3.0.0": + version: 3.259.0 + resolution: "@aws-sdk/util-utf8-browser@npm:3.259.0" + dependencies: + tslib: ^2.3.1 + checksum: b6a1e580da1c9b62c749814182a7649a748ca4253edb4063aa521df97d25b76eae3359eb1680b86f71aac668e05cc05c514379bca39ebf4ba998ae4348412da8 + languageName: node + linkType: hard + +"@aws-sdk/xml-builder@npm:3.535.0": + version: 3.535.0 + resolution: "@aws-sdk/xml-builder@npm:3.535.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 9320f6600c7852b681ed4171f1521eda166321ef7ffea5a6b99a1d328835bb12f7423431ea23a696c678ec4fc8e6dbb2f979d941289f6e0cb55c3da7d5eee140 + languageName: node + linkType: hard + "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.18.6, @babel/code-frame@npm:^7.22.13": version: 7.22.13 resolution: "@babel/code-frame@npm:7.22.13" @@ -2019,6 +2719,15 @@ __metadata: languageName: node linkType: hard +"@babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.23.4": + version: 7.24.4 + resolution: "@babel/runtime@npm:7.24.4" + dependencies: + regenerator-runtime: ^0.14.0 + checksum: 2f27d4c0ffac7ae7999ac0385e1106f2a06992a8bdcbf3da06adcac7413863cd08c198c2e4e970041bbea849e17f02e1df18875539b6afba76c781b6b59a07c3 + languageName: node + linkType: hard + "@babel/template@npm:^7.18.10, @babel/template@npm:^7.22.15, @babel/template@npm:^7.22.5, @babel/template@npm:^7.3.3": version: 7.22.15 resolution: "@babel/template@npm:7.22.15" @@ -2175,7 +2884,36 @@ __metadata: languageName: node linkType: hard -"@confio/ics23@npm:^0.6.8": +"@bundlr-network/client@npm:^0.8.9": + version: 0.8.9 + resolution: "@bundlr-network/client@npm:0.8.9" + dependencies: + "@solana/wallet-adapter-base": ^0.9.2 + "@solana/web3.js": ^1.36.0 + "@supercharge/promise-pool": ^2.1.0 + algosdk: ^1.13.1 + arbundles: ^0.6.21 + arweave: ^1.11.4 + async-retry: ^1.3.3 + axios: ^0.25.0 + base64url: ^3.0.1 + bignumber.js: ^9.0.1 + bs58: ^4.0.1 + commander: ^8.2.0 + csv: ^6.0.5 + ethers: ^5.5.1 + inquirer: ^8.2.0 + js-sha256: ^0.9.0 + mime-types: ^2.1.34 + near-api-js: ^0.44.2 + near-seed-phrase: ^0.2.0 + bin: + bundlr: build/node/cli.js + checksum: 08f9c0c594a8f7a2bb57e721e9c4a5b2f803f74ed99dcfeb8f1744c6c3faef02ef834ad9ba5b62661bd13f85e7a344cb38994466af11c8bb4fae64389f7718ca + languageName: node + linkType: hard + +"@confio/ics23@npm:^0.6.3, @confio/ics23@npm:^0.6.8": version: 0.6.8 resolution: "@confio/ics23@npm:0.6.8" dependencies: @@ -2185,6 +2923,42 @@ __metadata: languageName: node linkType: hard +"@cosmjs/amino@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/amino@npm:0.27.1" + dependencies: + "@cosmjs/crypto": 0.27.1 + "@cosmjs/encoding": 0.27.1 + "@cosmjs/math": 0.27.1 + "@cosmjs/utils": 0.27.1 + checksum: c558332edae18c182224314dd31a47383d5edfd1f7e594202be587349b45cdeed12c8958b8c85f1d38a604fa46fa5589b35fbfd8f20f4541e80f1315537b9346 + languageName: node + linkType: hard + +"@cosmjs/amino@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/amino@npm:0.30.1" + dependencies: + "@cosmjs/crypto": ^0.30.1 + "@cosmjs/encoding": ^0.30.1 + "@cosmjs/math": ^0.30.1 + "@cosmjs/utils": ^0.30.1 + checksum: aa254f936fd95e146e05cc4d6e51f86f4fe7f2048d337d197ccb2cb6e488f8b8061aa6b21e63b1f7001d99b80417f029ef75a12bd0478749286932834157c5aa + languageName: node + linkType: hard + +"@cosmjs/amino@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/amino@npm:0.31.3" + dependencies: + "@cosmjs/crypto": ^0.31.3 + "@cosmjs/encoding": ^0.31.3 + "@cosmjs/math": ^0.31.3 + "@cosmjs/utils": ^0.31.3 + checksum: 30e55ed256e1ba8a84b8a92062fd48aed43b1d638b8917af8b28ae007a1eff3ffc9ffb743400db23c583dc2fefae12c3dd8b315451a09f6da9c10a07ce714dfa + languageName: node + linkType: hard + "@cosmjs/amino@npm:^0.32.3": version: 0.32.3 resolution: "@cosmjs/amino@npm:0.32.3" @@ -2215,6 +2989,54 @@ __metadata: languageName: node linkType: hard +"@cosmjs/crypto@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/crypto@npm:0.27.1" + dependencies: + "@cosmjs/encoding": 0.27.1 + "@cosmjs/math": 0.27.1 + "@cosmjs/utils": 0.27.1 + bip39: ^3.0.2 + bn.js: ^5.2.0 + elliptic: ^6.5.3 + js-sha3: ^0.8.0 + libsodium-wrappers: ^0.7.6 + ripemd160: ^2.0.2 + sha.js: ^2.4.11 + checksum: d1773147a4f57da572483d28286983cca4907e18071296c707581461b0fbe8a3bb6d1591a81dc724c19b2ca3c728726a1f7309a74bf9536a261f4cf1098d1508 + languageName: node + linkType: hard + +"@cosmjs/crypto@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/crypto@npm:0.30.1" + dependencies: + "@cosmjs/encoding": ^0.30.1 + "@cosmjs/math": ^0.30.1 + "@cosmjs/utils": ^0.30.1 + "@noble/hashes": ^1 + bn.js: ^5.2.0 + elliptic: ^6.5.4 + libsodium-wrappers: ^0.7.6 + checksum: f1989a5cab92de4ad8c4fef65554b1f65e6c3e8b9ef0d550fa84e5f1aa13286b96a5310a374bcea7d0ebd6b9c46ea69a8469d06275b317a09b9ec7e0a3a07f0e + languageName: node + linkType: hard + +"@cosmjs/crypto@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/crypto@npm:0.31.3" + dependencies: + "@cosmjs/encoding": ^0.31.3 + "@cosmjs/math": ^0.31.3 + "@cosmjs/utils": ^0.31.3 + "@noble/hashes": ^1 + bn.js: ^5.2.0 + elliptic: ^6.5.4 + libsodium-wrappers-sumo: ^0.7.11 + checksum: e562bbcb7cce2c2992aa7fc808fb2b9bcc6d6a27b2567323f41349e7e1aca1b8a4e5b6e0442512cdd7e2bbe54f4b6a0b7ccf71eb574522d0bc405e609dcece8c + languageName: node + linkType: hard + "@cosmjs/crypto@npm:^0.32.3": version: 0.32.3 resolution: "@cosmjs/crypto@npm:0.32.3" @@ -2230,36 +3052,170 @@ __metadata: languageName: node linkType: hard -"@cosmjs/encoding@npm:^0.32.3": - version: 0.32.3 - resolution: "@cosmjs/encoding@npm:0.32.3" +"@cosmjs/encoding@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/encoding@npm:0.27.1" dependencies: base64-js: ^1.3.0 bech32: ^1.1.4 readonly-date: ^1.0.0 - checksum: ea3bc8f8a1728b51d24ebdc298012520a27f0f593839d77af581f245e08eb74f5d172788c4372221863b9dc18aa7e544bda2495f3263a604a6bbbe9308a5650e + checksum: 34dad88ee64b6d3b920daa5e605dafb2722d2f9cf9c44da8e652ebf24d5f76557cdd422be3ea5252186b8ea19d172819f8053749c3e81232a7c2bbff5f24fa81 languageName: node linkType: hard -"@cosmjs/json-rpc@npm:^0.32.3": - version: 0.32.3 - resolution: "@cosmjs/json-rpc@npm:0.32.3" +"@cosmjs/encoding@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/encoding@npm:0.30.1" dependencies: - "@cosmjs/stream": ^0.32.3 - xstream: ^11.14.0 - checksum: fc574f8863e7696fa07be162e6cbdfe51d720a0a8b433441152f4f6983596c7acf1f2461d58048e35306221228e2a6199b095d9bd2ee7c8c3ab27b592e3a267a + base64-js: ^1.3.0 + bech32: ^1.1.4 + readonly-date: ^1.0.0 + checksum: bd1932fafecbf9876ad97dee8133cc955f52d2fd9b6040d8c991b40ba4195c02cb4dc3c4beec7c237217ba96db78cd914840b2b895348482190d459a21c2b6dd languageName: node linkType: hard -"@cosmjs/math@npm:^0.32.3": - version: 0.32.3 - resolution: "@cosmjs/math@npm:0.32.3" +"@cosmjs/encoding@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/encoding@npm:0.31.3" dependencies: - bn.js: ^5.2.0 + base64-js: ^1.3.0 + bech32: ^1.1.4 + readonly-date: ^1.0.0 + checksum: dadef0579828299be20a64edf820ac8770c0cc47a842594bc9b494f160a347b745941d795360755ccbe385b9d0912aa54753479d1a70ff762d2d334693952ff9 + languageName: node + linkType: hard + +"@cosmjs/encoding@npm:^0.32.3": + version: 0.32.3 + resolution: "@cosmjs/encoding@npm:0.32.3" + dependencies: + base64-js: ^1.3.0 + bech32: ^1.1.4 + readonly-date: ^1.0.0 + checksum: ea3bc8f8a1728b51d24ebdc298012520a27f0f593839d77af581f245e08eb74f5d172788c4372221863b9dc18aa7e544bda2495f3263a604a6bbbe9308a5650e + languageName: node + linkType: hard + +"@cosmjs/json-rpc@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/json-rpc@npm:0.27.1" + dependencies: + "@cosmjs/stream": 0.27.1 + xstream: ^11.14.0 + checksum: 344a18682995982ae3c6e52c90d5e080a1f5049135ac417e51bb54a0611738a26b7b9eb751d28d8f5b6cffa631932ed32912d6cb8566b798885896475324bb88 + languageName: node + linkType: hard + +"@cosmjs/json-rpc@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/json-rpc@npm:0.30.1" + dependencies: + "@cosmjs/stream": ^0.30.1 + xstream: ^11.14.0 + checksum: 750686d53cd4ee239fd24a41d556ab08307f099c9f7bb633a566af417b0baad0ff954498272b6bdb02d4cad596c7ac8f24e38f0cf25c7fbe6200b539c2f56266 + languageName: node + linkType: hard + +"@cosmjs/json-rpc@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/json-rpc@npm:0.31.3" + dependencies: + "@cosmjs/stream": ^0.31.3 + xstream: ^11.14.0 + checksum: 6f050cf0d02f2a4f9df5391cc77e661684e5c7cc1df0fb71ae903984cb4f10cc765c08e866e417323910cbc63b91e30c38b7f2585ef5e473a8b086cddacc882a + languageName: node + linkType: hard + +"@cosmjs/json-rpc@npm:^0.32.3": + version: 0.32.3 + resolution: "@cosmjs/json-rpc@npm:0.32.3" + dependencies: + "@cosmjs/stream": ^0.32.3 + xstream: ^11.14.0 + checksum: fc574f8863e7696fa07be162e6cbdfe51d720a0a8b433441152f4f6983596c7acf1f2461d58048e35306221228e2a6199b095d9bd2ee7c8c3ab27b592e3a267a + languageName: node + linkType: hard + +"@cosmjs/math@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/math@npm:0.27.1" + dependencies: + bn.js: ^5.2.0 + checksum: 0b1d91eb7c3269636bf0f884220ff1c53ba0c7ca4e80826b382d71a51abc853e845e10651b1bcffd377557d4879dddd7835729e30a4fa824b09ad24cd6ce1ca2 + languageName: node + linkType: hard + +"@cosmjs/math@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/math@npm:0.30.1" + dependencies: + bn.js: ^5.2.0 + checksum: c13d2a89348407bcc0f737f989fc1eb850b81d1f0ae06f1cc656b9a3194bf9ee048ce2e5c948f6ada61e95f5bfa324fad43dc531ade7538bcf993ba2085cb5fe + languageName: node + linkType: hard + +"@cosmjs/math@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/math@npm:0.31.3" + dependencies: + bn.js: ^5.2.0 + checksum: 1685ad41ed78e78854649ca933817c56d39f4b36bba59b5dbdb1728048f431da5531265f4d77bfc9280cdea6c368817109b9f4540d5cfc2093f6ea6ff9e9a8d2 + languageName: node + linkType: hard + +"@cosmjs/math@npm:^0.32.3": + version: 0.32.3 + resolution: "@cosmjs/math@npm:0.32.3" + dependencies: + bn.js: ^5.2.0 checksum: 71b91e7af91a86d06014719547fec7c419523bfa42f0d62ccb2ca68263a90fe8fe0e6a35449e7528f40064888945d864520fbc760d62ebd8b0fe73913ac0f52f languageName: node linkType: hard +"@cosmjs/proto-signing@npm:0.27.1, @cosmjs/proto-signing@npm:^0.27.1": + version: 0.27.1 + resolution: "@cosmjs/proto-signing@npm:0.27.1" + dependencies: + "@cosmjs/amino": 0.27.1 + "@cosmjs/crypto": 0.27.1 + "@cosmjs/math": 0.27.1 + cosmjs-types: ^0.4.0 + long: ^4.0.0 + protobufjs: ~6.10.2 + checksum: 2b54e1196120e5a3e8b58e640e70c07ffa931e216b2b8a59cde4f11f8a9f25336ac6b530475dfdcf6b94713276b1b1941096d844e7cb7f150e9b438636e0a7ee + languageName: node + linkType: hard + +"@cosmjs/proto-signing@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/proto-signing@npm:0.30.1" + dependencies: + "@cosmjs/amino": ^0.30.1 + "@cosmjs/crypto": ^0.30.1 + "@cosmjs/encoding": ^0.30.1 + "@cosmjs/math": ^0.30.1 + "@cosmjs/utils": ^0.30.1 + cosmjs-types: ^0.7.1 + long: ^4.0.0 + checksum: 15e13e33976c0a52e2ef93aec6171e3934543d116a3247d9b51ed495aa9da68dbb13a93a37808c02e4378be20d8ca326902ca721de6d2c9af470d6aa057019f5 + languageName: node + linkType: hard + +"@cosmjs/proto-signing@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/proto-signing@npm:0.31.3" + dependencies: + "@cosmjs/amino": ^0.31.3 + "@cosmjs/crypto": ^0.31.3 + "@cosmjs/encoding": ^0.31.3 + "@cosmjs/math": ^0.31.3 + "@cosmjs/utils": ^0.31.3 + cosmjs-types: ^0.8.0 + long: ^4.0.0 + checksum: c27c4d921c99f5c06ac92ebba59e78c53b7c115334932dd1365263b98c1a67c7323e3a69ae933babf5a36682c019bbc7da3c9597ca1bf1a4858546bdd681453a + languageName: node + linkType: hard + "@cosmjs/proto-signing@npm:^0.32.3": version: 0.32.3 resolution: "@cosmjs/proto-signing@npm:0.32.3" @@ -2274,6 +3230,42 @@ __metadata: languageName: node linkType: hard +"@cosmjs/socket@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/socket@npm:0.27.1" + dependencies: + "@cosmjs/stream": 0.27.1 + isomorphic-ws: ^4.0.1 + ws: ^7 + xstream: ^11.14.0 + checksum: 82d4dff828b6f24e92dfdc28c521628700c10e087e2bd1084532bab9c16bbc90d8717b727d9659b7383152bb05491c3bd16f348e2172fce400729bb7afa39649 + languageName: node + linkType: hard + +"@cosmjs/socket@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/socket@npm:0.30.1" + dependencies: + "@cosmjs/stream": ^0.30.1 + isomorphic-ws: ^4.0.1 + ws: ^7 + xstream: ^11.14.0 + checksum: ef5e5d7bbcd89b5bfbd6fa4039133e15e5db848e6b0bc812b89872d28d9ced73d8a12fbf6581e6b0b08de28f2c1a9c7b05825804be65eb07d2f3d3532babea91 + languageName: node + linkType: hard + +"@cosmjs/socket@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/socket@npm:0.31.3" + dependencies: + "@cosmjs/stream": ^0.31.3 + isomorphic-ws: ^4.0.1 + ws: ^7 + xstream: ^11.14.0 + checksum: 29cc5120732a3badd0d3e4358aa645aa6ad50fedf4a619e2a99a2ec85274bc6df9791f0fb9674417b6eca72762916e8f25277fafb318f3e0a77effa2c52da16b + languageName: node + linkType: hard + "@cosmjs/socket@npm:^0.32.3": version: 0.32.3 resolution: "@cosmjs/socket@npm:0.32.3" @@ -2286,6 +3278,66 @@ __metadata: languageName: node linkType: hard +"@cosmjs/stargate@npm:^0.27.1": + version: 0.27.1 + resolution: "@cosmjs/stargate@npm:0.27.1" + dependencies: + "@confio/ics23": ^0.6.3 + "@cosmjs/amino": 0.27.1 + "@cosmjs/encoding": 0.27.1 + "@cosmjs/math": 0.27.1 + "@cosmjs/proto-signing": 0.27.1 + "@cosmjs/stream": 0.27.1 + "@cosmjs/tendermint-rpc": 0.27.1 + "@cosmjs/utils": 0.27.1 + cosmjs-types: ^0.4.0 + long: ^4.0.0 + protobufjs: ~6.10.2 + xstream: ^11.14.0 + checksum: a4a200e695b8b91a0251ccf6a20991b42311cc42a8e01014b28a8a975b03922d114fdc153cd15d8a575e941bfc3361c60676eba6a1fff85f811537d86a72c896 + languageName: node + linkType: hard + +"@cosmjs/stargate@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/stargate@npm:0.30.1" + dependencies: + "@confio/ics23": ^0.6.8 + "@cosmjs/amino": ^0.30.1 + "@cosmjs/encoding": ^0.30.1 + "@cosmjs/math": ^0.30.1 + "@cosmjs/proto-signing": ^0.30.1 + "@cosmjs/stream": ^0.30.1 + "@cosmjs/tendermint-rpc": ^0.30.1 + "@cosmjs/utils": ^0.30.1 + cosmjs-types: ^0.7.1 + long: ^4.0.0 + protobufjs: ~6.11.3 + xstream: ^11.14.0 + checksum: 2eb089c4a7f995b787702d52f22e1c808704cd02c29ec4feee57897d350d9dbde645785e89bf34181da7acd67547dc2b0f17f9f49cfbb0272d70cb7f553a8644 + languageName: node + linkType: hard + +"@cosmjs/stargate@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/stargate@npm:0.31.3" + dependencies: + "@confio/ics23": ^0.6.8 + "@cosmjs/amino": ^0.31.3 + "@cosmjs/encoding": ^0.31.3 + "@cosmjs/math": ^0.31.3 + "@cosmjs/proto-signing": ^0.31.3 + "@cosmjs/stream": ^0.31.3 + "@cosmjs/tendermint-rpc": ^0.31.3 + "@cosmjs/utils": ^0.31.3 + cosmjs-types: ^0.8.0 + long: ^4.0.0 + protobufjs: ~6.11.3 + xstream: ^11.14.0 + checksum: 9b680d50f0818e3cfaffccd022d6034c283c1e350a1b8d8f74ffa22352e342ce1cb00533007ba7b5a6a1c1bc30fe327bd09c23ac8b7486691ad127a34c47690c + languageName: node + linkType: hard + "@cosmjs/stargate@npm:^0.32.3": version: 0.32.3 resolution: "@cosmjs/stargate@npm:0.32.3" @@ -2304,6 +3356,33 @@ __metadata: languageName: node linkType: hard +"@cosmjs/stream@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/stream@npm:0.27.1" + dependencies: + xstream: ^11.14.0 + checksum: cb476adb6881a6c8953187b994aa4a1b10426a2983b6b6c7b31041facf0e89a84d3a71889faca6cb7eca19211e53761a69d90b338373a0b1c415010cfd19d197 + languageName: node + linkType: hard + +"@cosmjs/stream@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/stream@npm:0.30.1" + dependencies: + xstream: ^11.14.0 + checksum: f9e48a8377c2d3cfbf288fcf4fad745905c042dabc442d2cbb93d4280033e3c8e493a3328f58c0b645b60f9c2188d14603b2bb37a174bc0619686c5e70b13dca + languageName: node + linkType: hard + +"@cosmjs/stream@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/stream@npm:0.31.3" + dependencies: + xstream: ^11.14.0 + checksum: 0d273604af4d7093b877582e223eedbcce4a1a4d7d9f80a4f5e215fd8be42ea6546f3778cc918cb0cdb144de52e7d8d4c476b9b4c6f678cebe914224f54d19ad + languageName: node + linkType: hard + "@cosmjs/stream@npm:^0.32.3": version: 0.32.3 resolution: "@cosmjs/stream@npm:0.32.3" @@ -2313,6 +3392,59 @@ __metadata: languageName: node linkType: hard +"@cosmjs/tendermint-rpc@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/tendermint-rpc@npm:0.27.1" + dependencies: + "@cosmjs/crypto": 0.27.1 + "@cosmjs/encoding": 0.27.1 + "@cosmjs/json-rpc": 0.27.1 + "@cosmjs/math": 0.27.1 + "@cosmjs/socket": 0.27.1 + "@cosmjs/stream": 0.27.1 + axios: ^0.21.2 + readonly-date: ^1.0.0 + xstream: ^11.14.0 + checksum: 90748e3ac6fad5e4984dda42c811aa1b9b12a4c2aae78e3022ac95b182b6c66c4764351d6adea81d16af5c3c01d84e0121cbc32683d0f383db542f67e441ceb8 + languageName: node + linkType: hard + +"@cosmjs/tendermint-rpc@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/tendermint-rpc@npm:0.30.1" + dependencies: + "@cosmjs/crypto": ^0.30.1 + "@cosmjs/encoding": ^0.30.1 + "@cosmjs/json-rpc": ^0.30.1 + "@cosmjs/math": ^0.30.1 + "@cosmjs/socket": ^0.30.1 + "@cosmjs/stream": ^0.30.1 + "@cosmjs/utils": ^0.30.1 + axios: ^0.21.2 + readonly-date: ^1.0.0 + xstream: ^11.14.0 + checksum: 6900711886d2d9b02dd9ec17d341a174d7d2a20c432618e96d7f33fa6732dcb77fe21f37c67d452c09095f099260a679a4ac5de0caeec376cd683d3d12790ed8 + languageName: node + linkType: hard + +"@cosmjs/tendermint-rpc@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/tendermint-rpc@npm:0.31.3" + dependencies: + "@cosmjs/crypto": ^0.31.3 + "@cosmjs/encoding": ^0.31.3 + "@cosmjs/json-rpc": ^0.31.3 + "@cosmjs/math": ^0.31.3 + "@cosmjs/socket": ^0.31.3 + "@cosmjs/stream": ^0.31.3 + "@cosmjs/utils": ^0.31.3 + axios: ^0.21.2 + readonly-date: ^1.0.0 + xstream: ^11.14.0 + checksum: 403e220ee4aeb65977a4416d48930d7381e3d4c10bf300fa6f07698c72b85a55f2314ba1a3d45849ce8549de2ff2005988188fc5fe60ac09188edbb89692115d + languageName: node + linkType: hard + "@cosmjs/tendermint-rpc@npm:^0.32.3": version: 0.32.3 resolution: "@cosmjs/tendermint-rpc@npm:0.32.3" @@ -2331,6 +3463,27 @@ __metadata: languageName: node linkType: hard +"@cosmjs/utils@npm:0.27.1": + version: 0.27.1 + resolution: "@cosmjs/utils@npm:0.27.1" + checksum: b48466efd7ec714520fe684e028754a6b5ca5b686d117b2078cac7ed824dd953fac09a9efc2bc5805fa270c151f5a53baa181cfb9f498697152d522d27565205 + languageName: node + linkType: hard + +"@cosmjs/utils@npm:^0.30.1": + version: 0.30.1 + resolution: "@cosmjs/utils@npm:0.30.1" + checksum: 64ea16cdeba64d2b346a0b45ca47059ab4297fdf5c4e5fd89ec262eec488807f49f94dcdc294628142015ce4669c4eaf7426d1f8a6538146da5601dcc484cb19 + languageName: node + linkType: hard + +"@cosmjs/utils@npm:^0.31.3": + version: 0.31.3 + resolution: "@cosmjs/utils@npm:0.31.3" + checksum: 2ff2b270954ab00cc5ae8f23625b562676d0a061c8076905509a5f0701e302e46d24a51a0c3283072e0ce01fbd860baceb25e62303ff17826672fe5f8674b00d + languageName: node + linkType: hard + "@cosmjs/utils@npm:^0.32.3": version: 0.32.3 resolution: "@cosmjs/utils@npm:0.32.3" @@ -2362,6 +3515,13 @@ __metadata: languageName: node linkType: hard +"@cosmostation/extension-client@npm:^0.0.6": + version: 0.0.6 + resolution: "@cosmostation/extension-client@npm:0.0.6" + checksum: 2b6535242cb7f6e9c6358ca0d7d0d8e128815b4437a3c72bfbf1238b0340f8f8ea9bb9599503f6bdc50ba71e395a498be7372bef4a226c0b974d45e3677002a4 + languageName: node + linkType: hard + "@cosmwasm/ts-codegen@npm:0.34.0": version: 0.34.0 resolution: "@cosmwasm/ts-codegen@npm:0.34.0" @@ -2487,132 +3647,534 @@ __metadata: languageName: node linkType: hard -"@geut/chan-core@npm:^3.2.7": - version: 3.2.7 - resolution: "@geut/chan-core@npm:3.2.7" +"@ethersproject/abi@npm:5.7.0, @ethersproject/abi@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/abi@npm:5.7.0" dependencies: - "@geut/chan-stringify": ^3.2.7 - "@geut/chast": ^3.2.6 - "@geut/remark-chan": ^3.2.6 - remark-parse: ^9.0.0 - semver: ^7.3.5 - unified: ^9.2.1 - unist-util-remove-position: ^4.0.0 - unist-util-select: ^4.0.0 - checksum: 1fe156481bf60efe17167ad47138d65929f73731271f192a30c111878065c83c3f101182af0f635bdcd36ee197f6c69c5d1659dc692f48f13cb93b040742a8bc + "@ethersproject/address": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/hash": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + checksum: bc6962bb6cb854e4d2a4d65b2c49c716477675b131b1363312234bdbb7e19badb7d9ce66f4ca2a70ae2ea84f7123dbc4e300a1bfe5d58864a7eafabc1466627e languageName: node linkType: hard -"@geut/chan-stringify@npm:^3.2.7": - version: 3.2.7 - resolution: "@geut/chan-stringify@npm:3.2.7" +"@ethersproject/abstract-provider@npm:5.7.0, @ethersproject/abstract-provider@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/abstract-provider@npm:5.7.0" dependencies: - mdast-util-to-markdown: ^0.6.5 - remark-parse: ^9.0.0 - remark-stringify: ^9.0.0 - unified: ^9.2.0 - unist-builder: ^1.0.3 - unist-util-remove-position: ^1.1.2 - checksum: bf2ea0fcce0db48f197eabff9166e71e6aebd7689fecce56a03cd1ba60ddb687987eb37946bc2f990da4f5c21a5f9f94de01d285e7ec05e4eb0e1cc934a2f761 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/networks": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/transactions": ^5.7.0 + "@ethersproject/web": ^5.7.0 + checksum: 74cf4696245cf03bb7cc5b6cbf7b4b89dd9a79a1c4688126d214153a938126d4972d42c93182198653ce1de35f2a2cad68be40337d4774b3698a39b28f0228a8 languageName: node linkType: hard -"@geut/chan@npm:^3.2.9": - version: 3.2.9 - resolution: "@geut/chan@npm:3.2.9" +"@ethersproject/abstract-signer@npm:5.7.0, @ethersproject/abstract-signer@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/abstract-signer@npm:5.7.0" dependencies: - "@actions/github": ^5.0.0 - "@geut/chan-core": ^3.2.7 - "@geut/git-url-parse": ^3.2.6 - boxen: ^5.0.1 - editor: ^1.0.0 - find-up: ^5.0.0 - new-github-release-url: ^1.0.0 - open: ^8.2.0 - semver: ^7.3.5 - signale: ^1.4.0 - tempfile: ^4.0.0 - to-vfile: ^6.1.0 - yargs: ^17.0.1 - bin: - chan: bin/chan.js - checksum: d5f2ba90978a40955b86ced28d1db50fe604854ab543da71c87697f392fd03d9ed194002e69d389b0e5380e9e2ebd48912da1749f6195388c73c2512bb3d5019 + "@ethersproject/abstract-provider": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + checksum: a823dac9cfb761e009851050ebebd5b229d1b1cc4a75b125c2da130ff37e8218208f7f9d1386f77407705b889b23d4a230ad67185f8872f083143e0073cbfbe3 languageName: node linkType: hard -"@geut/chast@npm:^3.2.6": - version: 3.2.6 - resolution: "@geut/chast@npm:3.2.6" +"@ethersproject/address@npm:5.7.0, @ethersproject/address@npm:^5.6.0, @ethersproject/address@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/address@npm:5.7.0" dependencies: - semver: ^7.3.5 - unist-builder: ^3.0.0 - checksum: 95159a5b971f929263bbb510d7d67a86a2d011120efe5041661befbae23bb786dfb19a950370f8a80923efaa1965767225e6247c9d1c72d5265232d3f79dee96 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/rlp": ^5.7.0 + checksum: 64ea5ebea9cc0e845c413e6cb1e54e157dd9fc0dffb98e239d3a3efc8177f2ff798cd4e3206cf3660ee8faeb7bef1a47dc0ebef0d7b132c32e61e550c7d4c843 languageName: node linkType: hard -"@geut/git-url-parse@npm:^3.2.6": - version: 3.2.6 - resolution: "@geut/git-url-parse@npm:3.2.6" +"@ethersproject/base64@npm:5.7.0, @ethersproject/base64@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/base64@npm:5.7.0" dependencies: - find-up: ^5.0.0 - git-url-parse: ^11.1.2 - gitconfiglocal: ^2.0.2 - checksum: a1a4ff7f34b517e47ce1e63f73785d574934107e8bc1ca73600d97840ed0b2f9612b56fb9b289f4d5af59f7930c2c7cce1393824cefee93da23c452ca52c8714 + "@ethersproject/bytes": ^5.7.0 + checksum: 7dd5d734d623582f08f665434f53685041a3d3b334a0e96c0c8afa8bbcaab934d50e5b6b980e826a8fde8d353e0b18f11e61faf17468177274b8e7c69cd9742b languageName: node linkType: hard -"@geut/remark-chan@npm:^3.2.6": - version: 3.2.6 - resolution: "@geut/remark-chan@npm:3.2.6" +"@ethersproject/basex@npm:5.7.0, @ethersproject/basex@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/basex@npm:5.7.0" dependencies: - "@geut/chast": ^3.2.6 - unist-util-remove-position: ^4.0.0 - unist-util-select: ^4.0.0 - checksum: d4522f3773a0c7eb3afb1956ac6b61751025eb4d07e3ae7e63f35d9dbbd0a2b63b2f0754171534d0730347119ce70409644415ab8ccf6d67ea2685bb3e3f9e82 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + checksum: 326087b7e1f3787b5fe6cd1cf2b4b5abfafbc355a45e88e22e5e9d6c845b613ffc5301d629b28d5c4d5e2bfe9ec424e6782c804956dff79be05f0098cb5817de languageName: node linkType: hard -"@graphql-typed-document-node/core@npm:^3.0.0, @graphql-typed-document-node/core@npm:^3.1.1": - version: 3.2.0 - resolution: "@graphql-typed-document-node/core@npm:3.2.0" - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: fa44443accd28c8cf4cb96aaaf39d144a22e8b091b13366843f4e97d19c7bfeaf609ce3c7603a4aeffe385081eaf8ea245d078633a7324c11c5ec4b2011bb76d +"@ethersproject/bignumber@npm:5.7.0, @ethersproject/bignumber@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/bignumber@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + bn.js: ^5.2.1 + checksum: 8c9a134b76f3feb4ec26a5a27379efb4e156b8fb2de0678a67788a91c7f4e30abe9d948638458e4b20f2e42380da0adacc7c9389d05fce070692edc6ae9b4904 languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.11.11": - version: 0.11.11 - resolution: "@humanwhocodes/config-array@npm:0.11.11" +"@ethersproject/bytes@npm:5.7.0, @ethersproject/bytes@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/bytes@npm:5.7.0" dependencies: - "@humanwhocodes/object-schema": ^1.2.1 - debug: ^4.1.1 - minimatch: ^3.0.5 - checksum: db84507375ab77b8ffdd24f498a5b49ad6b64391d30dd2ac56885501d03964d29637e05b1ed5aefa09d57ac667e28028bc22d2da872bfcd619652fbdb5f4ca19 + "@ethersproject/logger": ^5.7.0 + checksum: 66ad365ceaab5da1b23b72225c71dce472cf37737af5118181fa8ab7447d696bea15ca22e3a0e8836fdd8cfac161afe321a7c67d0dde96f9f645ddd759676621 languageName: node linkType: hard -"@humanwhocodes/module-importer@npm:^1.0.1": - version: 1.0.1 - resolution: "@humanwhocodes/module-importer@npm:1.0.1" - checksum: 0fd22007db8034a2cdf2c764b140d37d9020bbfce8a49d3ec5c05290e77d4b0263b1b972b752df8c89e5eaa94073408f2b7d977aed131faf6cf396ebb5d7fb61 +"@ethersproject/constants@npm:5.7.0, @ethersproject/constants@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/constants@npm:5.7.0" + dependencies: + "@ethersproject/bignumber": ^5.7.0 + checksum: 6d4b1355747cce837b3e76ec3bde70e4732736f23b04f196f706ebfa5d4d9c2be50904a390d4d40ce77803b98d03d16a9b6898418e04ba63491933ce08c4ba8a languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^1.2.1": - version: 1.2.1 - resolution: "@humanwhocodes/object-schema@npm:1.2.1" - checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 +"@ethersproject/contracts@npm:5.7.0": + version: 5.7.0 + resolution: "@ethersproject/contracts@npm:5.7.0" + dependencies: + "@ethersproject/abi": ^5.7.0 + "@ethersproject/abstract-provider": ^5.7.0 + "@ethersproject/abstract-signer": ^5.7.0 + "@ethersproject/address": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/transactions": ^5.7.0 + checksum: 6ccf1121cba01b31e02f8c507cb971ab6bfed85706484a9ec09878ef1594a62215f43c4fdef8f4a4875b99c4a800bc95e3be69b1803f8ce479e07634b5a740c0 languageName: node linkType: hard -"@ipld/dag-cbor@npm:^6.0.3": - version: 6.0.15 - resolution: "@ipld/dag-cbor@npm:6.0.15" +"@ethersproject/hash@npm:5.7.0, @ethersproject/hash@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/hash@npm:5.7.0" dependencies: - cborg: ^1.5.4 - multiformats: ^9.5.4 - checksum: c4ac8d7d271b9dd093c43495b1f24c3cdb7f10487aac529c2010c53a3320439ac9b17f53f02177e022735a1aae3d921f359c7020f765b72f94799ec3ff8e7207 + "@ethersproject/abstract-signer": ^5.7.0 + "@ethersproject/address": ^5.7.0 + "@ethersproject/base64": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + checksum: 6e9fa8d14eb08171cd32f17f98cc108ec2aeca74a427655f0d689c550fee0b22a83b3b400fad7fb3f41cf14d4111f87f170aa7905bcbcd1173a55f21b06262ef + languageName: node + linkType: hard + +"@ethersproject/hdnode@npm:5.7.0, @ethersproject/hdnode@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/hdnode@npm:5.7.0" + dependencies: + "@ethersproject/abstract-signer": ^5.7.0 + "@ethersproject/basex": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/pbkdf2": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/sha2": ^5.7.0 + "@ethersproject/signing-key": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + "@ethersproject/transactions": ^5.7.0 + "@ethersproject/wordlists": ^5.7.0 + checksum: bfe5ca2d89a42de73655f853170ef4766b933c5f481cddad709b3aca18823275b096e572f92d1602a052f80b426edde44ad6b9d028799775a7dad4a5bbed2133 + languageName: node + linkType: hard + +"@ethersproject/json-wallets@npm:5.7.0, @ethersproject/json-wallets@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/json-wallets@npm:5.7.0" + dependencies: + "@ethersproject/abstract-signer": ^5.7.0 + "@ethersproject/address": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/hdnode": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/pbkdf2": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/random": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + "@ethersproject/transactions": ^5.7.0 + aes-js: 3.0.0 + scrypt-js: 3.0.1 + checksum: f583458d22db62efaaf94d38dd243482776a45bf90f9f3882fbad5aa0b8fd288b41eb7c1ff8ec0b99c9b751088e43d6173530db64dd33c59f9d8daa8d7ad5aa2 + languageName: node + linkType: hard + +"@ethersproject/keccak256@npm:5.7.0, @ethersproject/keccak256@npm:^5.5.0, @ethersproject/keccak256@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/keccak256@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + js-sha3: 0.8.0 + checksum: ff70950d82203aab29ccda2553422cbac2e7a0c15c986bd20a69b13606ed8bb6e4fdd7b67b8d3b27d4f841e8222cbaccd33ed34be29f866fec7308f96ed244c6 + languageName: node + linkType: hard + +"@ethersproject/logger@npm:5.7.0, @ethersproject/logger@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/logger@npm:5.7.0" + checksum: 075ab2f605f1fd0813f2e39c3308f77b44a67732b36e712d9bc085f22a84aac4da4f71b39bee50fe78da3e1c812673fadc41180c9970fe5e486e91ea17befe0d + languageName: node + linkType: hard + +"@ethersproject/networks@npm:5.7.1, @ethersproject/networks@npm:^5.7.0": + version: 5.7.1 + resolution: "@ethersproject/networks@npm:5.7.1" + dependencies: + "@ethersproject/logger": ^5.7.0 + checksum: 0339f312304c17d9a0adce550edb825d4d2c8c9468c1634c44172c67a9ed256f594da62c4cda5c3837a0f28b7fabc03aca9b492f68ff1fdad337ee861b27bd5d + languageName: node + linkType: hard + +"@ethersproject/pbkdf2@npm:5.7.0, @ethersproject/pbkdf2@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/pbkdf2@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/sha2": ^5.7.0 + checksum: b895adb9e35a8a127e794f7aadc31a2424ef355a70e51cde10d457e3e888bb8102373199a540cf61f2d6b9a32e47358f9c65b47d559f42bf8e596b5fd67901e9 + languageName: node + linkType: hard + +"@ethersproject/properties@npm:5.7.0, @ethersproject/properties@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/properties@npm:5.7.0" + dependencies: + "@ethersproject/logger": ^5.7.0 + checksum: 6ab0ccf0c3aadc9221e0cdc5306ce6cd0df7f89f77d77bccdd1277182c9ead0202cd7521329ba3acde130820bf8af299e17cf567d0d497c736ee918207bbf59f + languageName: node + linkType: hard + +"@ethersproject/providers@npm:5.7.2": + version: 5.7.2 + resolution: "@ethersproject/providers@npm:5.7.2" + dependencies: + "@ethersproject/abstract-provider": ^5.7.0 + "@ethersproject/abstract-signer": ^5.7.0 + "@ethersproject/address": ^5.7.0 + "@ethersproject/base64": ^5.7.0 + "@ethersproject/basex": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/hash": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/networks": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/random": ^5.7.0 + "@ethersproject/rlp": ^5.7.0 + "@ethersproject/sha2": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + "@ethersproject/transactions": ^5.7.0 + "@ethersproject/web": ^5.7.0 + bech32: 1.1.4 + ws: 7.4.6 + checksum: 1754c731a5ca6782ae9677f4a9cd8b6246c4ef21a966c9a01b133750f3c578431ec43ec254e699969c4a0f87e84463ded50f96b415600aabd37d2056aee58c19 + languageName: node + linkType: hard + +"@ethersproject/random@npm:5.7.0, @ethersproject/random@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/random@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + checksum: 017829c91cff6c76470852855108115b0b52c611b6be817ed1948d56ba42d6677803ec2012aa5ae298a7660024156a64c11fcf544e235e239ab3f89f0fff7345 + languageName: node + linkType: hard + +"@ethersproject/rlp@npm:5.7.0, @ethersproject/rlp@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/rlp@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + checksum: bce165b0f7e68e4d091c9d3cf47b247cac33252df77a095ca4281d32d5eeaaa3695d9bc06b2b057c5015353a68df89f13a4a54a72e888e4beeabbe56b15dda6e + languageName: node + linkType: hard + +"@ethersproject/sha2@npm:5.7.0, @ethersproject/sha2@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/sha2@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + hash.js: 1.1.7 + checksum: 09321057c022effbff4cc2d9b9558228690b5dd916329d75c4b1ffe32ba3d24b480a367a7cc92d0f0c0b1c896814d03351ae4630e2f1f7160be2bcfbde435dbc + languageName: node + linkType: hard + +"@ethersproject/signing-key@npm:5.7.0, @ethersproject/signing-key@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/signing-key@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + bn.js: ^5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + checksum: 8f8de09b0aac709683bbb49339bc0a4cd2f95598f3546436c65d6f3c3a847ffa98e06d35e9ed2b17d8030bd2f02db9b7bd2e11c5cf8a71aad4537487ab4cf03a + languageName: node + linkType: hard + +"@ethersproject/solidity@npm:5.7.0": + version: 5.7.0 + resolution: "@ethersproject/solidity@npm:5.7.0" + dependencies: + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/sha2": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + checksum: 9a02f37f801c96068c3e7721f83719d060175bc4e80439fe060e92bd7acfcb6ac1330c7e71c49f4c2535ca1308f2acdcb01e00133129aac00581724c2d6293f3 + languageName: node + linkType: hard + +"@ethersproject/strings@npm:5.7.0, @ethersproject/strings@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/strings@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + checksum: 5ff78693ae3fdf3cf23e1f6dc047a61e44c8197d2408c42719fef8cb7b7b3613a4eec88ac0ed1f9f5558c74fe0de7ae3195a29ca91a239c74b9f444d8e8b50df + languageName: node + linkType: hard + +"@ethersproject/transactions@npm:5.7.0, @ethersproject/transactions@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/transactions@npm:5.7.0" + dependencies: + "@ethersproject/address": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/rlp": ^5.7.0 + "@ethersproject/signing-key": ^5.7.0 + checksum: a31b71996d2b283f68486241bff0d3ea3f1ba0e8f1322a8fffc239ccc4f4a7eb2ea9994b8fd2f093283fd75f87bae68171e01b6265261f821369aca319884a79 + languageName: node + linkType: hard + +"@ethersproject/units@npm:5.7.0": + version: 5.7.0 + resolution: "@ethersproject/units@npm:5.7.0" + dependencies: + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/constants": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + checksum: 304714f848cd32e57df31bf545f7ad35c2a72adae957198b28cbc62166daa929322a07bff6e9c9ac4577ab6aa0de0546b065ed1b2d20b19e25748b7d475cb0fc + languageName: node + linkType: hard + +"@ethersproject/wallet@npm:5.7.0": + version: 5.7.0 + resolution: "@ethersproject/wallet@npm:5.7.0" + dependencies: + "@ethersproject/abstract-provider": ^5.7.0 + "@ethersproject/abstract-signer": ^5.7.0 + "@ethersproject/address": ^5.7.0 + "@ethersproject/bignumber": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/hash": ^5.7.0 + "@ethersproject/hdnode": ^5.7.0 + "@ethersproject/json-wallets": ^5.7.0 + "@ethersproject/keccak256": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/random": ^5.7.0 + "@ethersproject/signing-key": ^5.7.0 + "@ethersproject/transactions": ^5.7.0 + "@ethersproject/wordlists": ^5.7.0 + checksum: a4009bf7331eddab38e3015b5e9101ef92de7f705b00a6196b997db0e5635b6d83561674d46c90c6f77b87c0500fe4a6b0183ba13749efc22db59c99deb82fbd + languageName: node + linkType: hard + +"@ethersproject/web@npm:5.7.1, @ethersproject/web@npm:^5.7.0": + version: 5.7.1 + resolution: "@ethersproject/web@npm:5.7.1" + dependencies: + "@ethersproject/base64": ^5.7.0 + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + checksum: 7028c47103f82fd2e2c197ce0eecfacaa9180ffeec7de7845b1f4f9b19d84081b7a48227aaddde05a4aaa526af574a9a0ce01cc0fc75e3e371f84b38b5b16b2b + languageName: node + linkType: hard + +"@ethersproject/wordlists@npm:5.7.0, @ethersproject/wordlists@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/wordlists@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/hash": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + "@ethersproject/properties": ^5.7.0 + "@ethersproject/strings": ^5.7.0 + checksum: 30eb6eb0731f9ef5faa44bf9c0c6e950bcaaef61e4d2d9ce0ae6d341f4e2d6d1f4ab4f8880bfce03b7aac4b862fb740e1421170cfbf8e2aafc359277d49e6e97 + languageName: node + linkType: hard + +"@geut/chan-core@npm:^3.2.7": + version: 3.2.7 + resolution: "@geut/chan-core@npm:3.2.7" + dependencies: + "@geut/chan-stringify": ^3.2.7 + "@geut/chast": ^3.2.6 + "@geut/remark-chan": ^3.2.6 + remark-parse: ^9.0.0 + semver: ^7.3.5 + unified: ^9.2.1 + unist-util-remove-position: ^4.0.0 + unist-util-select: ^4.0.0 + checksum: 1fe156481bf60efe17167ad47138d65929f73731271f192a30c111878065c83c3f101182af0f635bdcd36ee197f6c69c5d1659dc692f48f13cb93b040742a8bc + languageName: node + linkType: hard + +"@geut/chan-stringify@npm:^3.2.7": + version: 3.2.7 + resolution: "@geut/chan-stringify@npm:3.2.7" + dependencies: + mdast-util-to-markdown: ^0.6.5 + remark-parse: ^9.0.0 + remark-stringify: ^9.0.0 + unified: ^9.2.0 + unist-builder: ^1.0.3 + unist-util-remove-position: ^1.1.2 + checksum: bf2ea0fcce0db48f197eabff9166e71e6aebd7689fecce56a03cd1ba60ddb687987eb37946bc2f990da4f5c21a5f9f94de01d285e7ec05e4eb0e1cc934a2f761 + languageName: node + linkType: hard + +"@geut/chan@npm:^3.2.9": + version: 3.2.9 + resolution: "@geut/chan@npm:3.2.9" + dependencies: + "@actions/github": ^5.0.0 + "@geut/chan-core": ^3.2.7 + "@geut/git-url-parse": ^3.2.6 + boxen: ^5.0.1 + editor: ^1.0.0 + find-up: ^5.0.0 + new-github-release-url: ^1.0.0 + open: ^8.2.0 + semver: ^7.3.5 + signale: ^1.4.0 + tempfile: ^4.0.0 + to-vfile: ^6.1.0 + yargs: ^17.0.1 + bin: + chan: bin/chan.js + checksum: d5f2ba90978a40955b86ced28d1db50fe604854ab543da71c87697f392fd03d9ed194002e69d389b0e5380e9e2ebd48912da1749f6195388c73c2512bb3d5019 + languageName: node + linkType: hard + +"@geut/chast@npm:^3.2.6": + version: 3.2.6 + resolution: "@geut/chast@npm:3.2.6" + dependencies: + semver: ^7.3.5 + unist-builder: ^3.0.0 + checksum: 95159a5b971f929263bbb510d7d67a86a2d011120efe5041661befbae23bb786dfb19a950370f8a80923efaa1965767225e6247c9d1c72d5265232d3f79dee96 + languageName: node + linkType: hard + +"@geut/git-url-parse@npm:^3.2.6": + version: 3.2.6 + resolution: "@geut/git-url-parse@npm:3.2.6" + dependencies: + find-up: ^5.0.0 + git-url-parse: ^11.1.2 + gitconfiglocal: ^2.0.2 + checksum: a1a4ff7f34b517e47ce1e63f73785d574934107e8bc1ca73600d97840ed0b2f9612b56fb9b289f4d5af59f7930c2c7cce1393824cefee93da23c452ca52c8714 + languageName: node + linkType: hard + +"@geut/remark-chan@npm:^3.2.6": + version: 3.2.6 + resolution: "@geut/remark-chan@npm:3.2.6" + dependencies: + "@geut/chast": ^3.2.6 + unist-util-remove-position: ^4.0.0 + unist-util-select: ^4.0.0 + checksum: d4522f3773a0c7eb3afb1956ac6b61751025eb4d07e3ae7e63f35d9dbbd0a2b63b2f0754171534d0730347119ce70409644415ab8ccf6d67ea2685bb3e3f9e82 + languageName: node + linkType: hard + +"@graphql-typed-document-node/core@npm:^3.0.0, @graphql-typed-document-node/core@npm:^3.1.1": + version: 3.2.0 + resolution: "@graphql-typed-document-node/core@npm:3.2.0" + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: fa44443accd28c8cf4cb96aaaf39d144a22e8b091b13366843f4e97d19c7bfeaf609ce3c7603a4aeffe385081eaf8ea245d078633a7324c11c5ec4b2011bb76d + languageName: node + linkType: hard + +"@humanwhocodes/config-array@npm:^0.11.11": + version: 0.11.11 + resolution: "@humanwhocodes/config-array@npm:0.11.11" + dependencies: + "@humanwhocodes/object-schema": ^1.2.1 + debug: ^4.1.1 + minimatch: ^3.0.5 + checksum: db84507375ab77b8ffdd24f498a5b49ad6b64391d30dd2ac56885501d03964d29637e05b1ed5aefa09d57ac667e28028bc22d2da872bfcd619652fbdb5f4ca19 + languageName: node + linkType: hard + +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: 0fd22007db8034a2cdf2c764b140d37d9020bbfce8a49d3ec5c05290e77d4b0263b1b972b752df8c89e5eaa94073408f2b7d977aed131faf6cf396ebb5d7fb61 + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^1.2.1": + version: 1.2.1 + resolution: "@humanwhocodes/object-schema@npm:1.2.1" + checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 + languageName: node + linkType: hard + +"@ipld/dag-cbor@npm:^6.0.3": + version: 6.0.15 + resolution: "@ipld/dag-cbor@npm:6.0.15" + dependencies: + cborg: ^1.5.4 + multiformats: ^9.5.4 + checksum: c4ac8d7d271b9dd093c43495b1f24c3cdb7f10487aac529c2010c53a3320439ac9b17f53f02177e022735a1aae3d921f359c7020f765b72f94799ec3ff8e7207 languageName: node linkType: hard @@ -3024,59 +4586,317 @@ __metadata: languageName: node linkType: hard -"@lukeed/csprng@npm:^1.0.0": - version: 1.1.0 - resolution: "@lukeed/csprng@npm:1.1.0" - checksum: 926f5f7fc629470ca9a8af355bfcd0271d34535f7be3890f69902432bddc3262029bb5dbe9025542cf6c9883d878692eef2815fc2f3ba5b92e9da1f9eba2e51b +"@keplr-wallet/common@npm:0.11.64": + version: 0.11.64 + resolution: "@keplr-wallet/common@npm:0.11.64" + dependencies: + "@keplr-wallet/crypto": 0.11.64 + buffer: ^6.0.3 + delay: ^4.4.0 + checksum: 418b7e1469c7e023f2ad8adf8f0925949b0fdac10da9bbdb4ff96a43f4054e877e7088bf876f6bdb2713656551e3d5d21038691d38f925d5321f8088bc580802 languageName: node linkType: hard -"@nestjs/common@npm:^9.4.0": - version: 9.4.3 - resolution: "@nestjs/common@npm:9.4.3" +"@keplr-wallet/common@npm:0.12.79": + version: 0.12.79 + resolution: "@keplr-wallet/common@npm:0.12.79" dependencies: - iterare: 1.2.1 - tslib: 2.5.3 - uid: 2.0.2 - peerDependencies: - cache-manager: <=5 - class-transformer: "*" - class-validator: "*" - reflect-metadata: ^0.1.12 - rxjs: ^7.1.0 - peerDependenciesMeta: - cache-manager: - optional: true - class-transformer: - optional: true - class-validator: - optional: true - checksum: 45ccb5acac2521a05576f37b37ab94c63a83aefb1839ed670635090bb934c1bd532852cb7be9863ee3b9d1ad80aa84e0602be023c626623f9233257dcb754914 + "@keplr-wallet/crypto": 0.12.79 + "@keplr-wallet/types": 0.12.79 + buffer: ^6.0.3 + delay: ^4.4.0 + mobx: ^6.1.7 + checksum: 13c42500f27b4d033f157c8775ed49d819a86a71947f268ef59184f3f729a9e5f0b94bcef90d70f7330a4fbf407051131646d499b1983c56bae9edce451d817b languageName: node linkType: hard -"@nestjs/core@npm:^9.4.0": - version: 9.4.3 - resolution: "@nestjs/core@npm:9.4.3" +"@keplr-wallet/cosmos@npm:^0.11.38": + version: 0.11.64 + resolution: "@keplr-wallet/cosmos@npm:0.11.64" dependencies: - "@nuxtjs/opencollective": 0.3.2 - fast-safe-stringify: 2.1.1 - iterare: 1.2.1 - path-to-regexp: 3.2.0 - tslib: 2.5.3 - uid: 2.0.2 - peerDependencies: - "@nestjs/common": ^9.0.0 - "@nestjs/microservices": ^9.0.0 - "@nestjs/platform-express": ^9.0.0 - "@nestjs/websockets": ^9.0.0 - reflect-metadata: ^0.1.12 - rxjs: ^7.1.0 - peerDependenciesMeta: - "@nestjs/microservices": - optional: true - "@nestjs/platform-express": - optional: true + "@ethersproject/address": ^5.6.0 + "@keplr-wallet/common": 0.11.64 + "@keplr-wallet/crypto": 0.11.64 + "@keplr-wallet/proto-types": 0.11.64 + "@keplr-wallet/types": 0.11.64 + "@keplr-wallet/unit": 0.11.64 + axios: ^0.27.2 + bech32: ^1.1.4 + buffer: ^6.0.3 + long: ^4.0.0 + protobufjs: ^6.11.2 + checksum: dd8b6d9823e7899987061e6adaf5e9bd87e57304df02cfe94d359c559069557e135639a7f950ee8e390886f37571daa7a41534d8bb6a3604f686f424458431b6 + languageName: node + linkType: hard + +"@keplr-wallet/cosmos@npm:^0.12.44": + version: 0.12.79 + resolution: "@keplr-wallet/cosmos@npm:0.12.79" + dependencies: + "@ethersproject/address": ^5.6.0 + "@keplr-wallet/common": 0.12.79 + "@keplr-wallet/crypto": 0.12.79 + "@keplr-wallet/proto-types": 0.12.79 + "@keplr-wallet/simple-fetch": 0.12.79 + "@keplr-wallet/types": 0.12.79 + "@keplr-wallet/unit": 0.12.79 + bech32: ^1.1.4 + buffer: ^6.0.3 + long: ^4.0.0 + protobufjs: ^6.11.2 + checksum: d1b6a24469d693faf457bc8078e28922bf8cc8ad765c66a05424e0cee9c68bdb7171333684ef94cb439f79577a4713acfa1ef2a520933cc6ef2f7342d3525bf6 + languageName: node + linkType: hard + +"@keplr-wallet/crypto@npm:0.11.64": + version: 0.11.64 + resolution: "@keplr-wallet/crypto@npm:0.11.64" + dependencies: + "@ethersproject/keccak256": ^5.5.0 + bip32: ^2.0.6 + bip39: ^3.0.3 + bs58check: ^2.1.2 + buffer: ^6.0.3 + crypto-js: ^4.0.0 + elliptic: ^6.5.3 + sha.js: ^2.4.11 + checksum: 803a60b674fe29c0f35f8e1a8d4424237f33e3fe31a25c77c9e4854764b4e4c6e2cace284f0858c26f3b966f96fd15b89d145a8d16896731b2a3443de1b8794a + languageName: node + linkType: hard + +"@keplr-wallet/crypto@npm:0.12.79": + version: 0.12.79 + resolution: "@keplr-wallet/crypto@npm:0.12.79" + dependencies: + "@ethersproject/keccak256": ^5.5.0 + bip32: ^2.0.6 + bip39: ^3.0.3 + bs58check: ^2.1.2 + buffer: ^6.0.3 + crypto-js: ^4.0.0 + elliptic: ^6.5.3 + sha.js: ^2.4.11 + checksum: f61d5ae2d1c00b74210d9abcfbe43f5e704604d8a1c63e577c34d1cbad6135d3c2978bf93419c0a0fa9546bdedf1f31ecd76a2860c9cf40eb0a2429b9358839e + languageName: node + linkType: hard + +"@keplr-wallet/proto-types@npm:0.11.64": + version: 0.11.64 + resolution: "@keplr-wallet/proto-types@npm:0.11.64" + dependencies: + long: ^4.0.0 + protobufjs: ^6.11.2 + checksum: 9d27ce358abdab95cc041a570c45b0e8d9ee8d31c9d2497d17bda18089e62685315bcf414a7ae91746eed68ab8dfb38d4684c112165a7c03118997eeedfc87f1 + languageName: node + linkType: hard + +"@keplr-wallet/proto-types@npm:0.12.79": + version: 0.12.79 + resolution: "@keplr-wallet/proto-types@npm:0.12.79" + dependencies: + long: ^4.0.0 + protobufjs: ^6.11.2 + checksum: 82afa9b34e2ff6e7e7d39ae399edb248f45c57c7dac08c8ce51907530e8eeebc8702e26d983e5d309213dca71da93aee570c86f8275bb00f8debb767f71fb705 + languageName: node + linkType: hard + +"@keplr-wallet/simple-fetch@npm:0.12.79": + version: 0.12.79 + resolution: "@keplr-wallet/simple-fetch@npm:0.12.79" + checksum: 087cb394994feb2a6d6a127e803c7d334c143cb18fd0ed4ddd933c3033d0896513e77992f0d5a59a9a64c690b1fce21ea4a19d621d15681a0400031fecb01dde + languageName: node + linkType: hard + +"@keplr-wallet/types@npm:0.11.64": + version: 0.11.64 + resolution: "@keplr-wallet/types@npm:0.11.64" + dependencies: + axios: ^0.27.2 + long: ^4.0.0 + checksum: d1d281cdb4c2f61ad46cad158559746927a65a4274170208c3ed712dd550bd623c058fea5cd08d0c1f7806c9856f3c901807f8946cd6cbc99f871b4ce03f94a9 + languageName: node + linkType: hard + +"@keplr-wallet/types@npm:0.12.79": + version: 0.12.79 + resolution: "@keplr-wallet/types@npm:0.12.79" + dependencies: + long: ^4.0.0 + checksum: a29a987f51fdc4fa1bfa133bac517cc42ecfed6c7c714667a39d6c45c6858726ac27bd5c5b71701d8d89ede268048fe7b0fde312abec15a6c12ed46cf1c8e832 + languageName: node + linkType: hard + +"@keplr-wallet/unit@npm:0.11.64": + version: 0.11.64 + resolution: "@keplr-wallet/unit@npm:0.11.64" + dependencies: + "@keplr-wallet/types": 0.11.64 + big-integer: ^1.6.48 + utility-types: ^3.10.0 + checksum: 073cac40bdee5296dca04edd80eb49c6eed56f21912f063377763ffe6601befb54536765549bd4c36cd38c1ae25ee276845447858f209912fca3feb025053d8a + languageName: node + linkType: hard + +"@keplr-wallet/unit@npm:0.12.79": + version: 0.12.79 + resolution: "@keplr-wallet/unit@npm:0.12.79" + dependencies: + "@keplr-wallet/types": 0.12.79 + big-integer: ^1.6.48 + utility-types: ^3.10.0 + checksum: 41e37c5576f9d9ec9f70a086eb4b9c7590f320948d233e1df13b535d166b200687968642a751a1f823036aa12840bb5434014c54b9480677bb4f6ae88a42fd30 + languageName: node + linkType: hard + +"@kyvejs/protocol@npm:^1.0.12": + version: 1.0.12 + resolution: "@kyvejs/protocol@npm:1.0.12" + dependencies: + "@aws-sdk/client-s3": ^3.370.0 + "@bundlr-network/client": ^0.8.9 + "@cosmjs/proto-signing": ^0.27.1 + "@cosmjs/stargate": ^0.27.1 + "@kyvejs/sdk": 1.0.5 + "@kyvejs/types": 1.0.3 + "@types/cli-progress": ^3.9.2 + "@types/jsonfile": ^6.0.1 + arweave: ^1.10.17 + axios: ^0.24.0 + bignumber.js: ^9.0.1 + clone: ^2.1.2 + commander: ^9.4.1 + fs-extra: ^10.0.1 + jsonfile: ^6.1.0 + level: ^8.0.0 + prando: ^6.0.1 + prom-client: ^14.1.0 + protobufjs: ^6.11.2 + seedrandom: ^3.0.5 + semver: ^7.5.3 + tslog: ^3.2.2 + unique-names-generator: ^4.6.0 + uuid: ^9.0.0 + checksum: 1af880bb76394b6d43908103037a66819188592211a8ea0c0c3d770955eddf5b1457d663c1c5f5ba25e31009a14fea6e135f2cae7b79c7d2a47546272814af2e + languageName: node + linkType: hard + +"@kyvejs/sdk@npm:1.0.5": + version: 1.0.5 + resolution: "@kyvejs/sdk@npm:1.0.5" + dependencies: + "@cosmjs/amino": ^0.30.1 + "@cosmjs/crypto": ^0.30.1 + "@cosmjs/encoding": ^0.30.1 + "@cosmjs/proto-signing": ^0.30.1 + "@cosmjs/stargate": ^0.30.1 + "@cosmjs/tendermint-rpc": ^0.30.1 + "@cosmostation/extension-client": ^0.0.6 + "@keplr-wallet/cosmos": ^0.11.38 + "@kyvejs/types": 1.0.3 + axios: 0.25.0 + bech32: 2.0.0 + bignumber.js: 9.0.2 + humanize-number: 0.0.2 + qs: ^6.10.5 + checksum: f2aa5472b2e14192af6fd65fba7d418009ac563e0335f4eb1930b3b7af59bcb863b82e1d59bd651fe9266604c5c66426e97b217b889edc93f09d661b65bcdfab + languageName: node + linkType: hard + +"@kyvejs/sdk@npm:^1.1.1": + version: 1.1.1 + resolution: "@kyvejs/sdk@npm:1.1.1" + dependencies: + "@cosmjs/amino": ^0.31.3 + "@cosmjs/crypto": ^0.31.3 + "@cosmjs/encoding": ^0.31.3 + "@cosmjs/proto-signing": ^0.31.3 + "@cosmjs/stargate": ^0.31.3 + "@cosmjs/tendermint-rpc": ^0.31.3 + "@cosmostation/extension-client": ^0.0.6 + "@keplr-wallet/cosmos": ^0.12.44 + "@kyvejs/types": 1.2.0 + axios: ^0.27.2 + bech32: 2.0.0 + bignumber.js: 9.1.2 + humanize-number: 0.0.2 + qs: ^6.10.5 + checksum: 04dc44f4a70fbde5bc87d1c337ee9b029943289d21563173aaeb0e16d8fd69f50dd688f12d15f01c3c04b9a9dcbeff82a5262e99ded8d131cfec380ca8a23ab5 + languageName: node + linkType: hard + +"@kyvejs/types@npm:1.0.3": + version: 1.0.3 + resolution: "@kyvejs/types@npm:1.0.3" + dependencies: + "@protobufs/cosmos": ^0.0.11 + "@protobufs/gogoproto": ^0.0.10 + "@protobufs/google": ^0.0.10 + nx: ^14.4.3 + ts-proto: ^1.115.4 + checksum: 74e973f8f5a6b6de3766f62316425cd0fe85b1dccfcc6d2652b9f49737278caba1564a9ca08a5e1b709f50813659f1f2255004d1cd63a1c33b253a0274a293b7 + languageName: node + linkType: hard + +"@kyvejs/types@npm:1.2.0": + version: 1.2.0 + resolution: "@kyvejs/types@npm:1.2.0" + checksum: 4c5cf8261d8ca68b864013b9aca743faae6a8fe63a352d81bb8684baff031e56b1a3d6e252b5c5557a3704d19d728dc0600b95f7bbd592a728496f6d3f8df27d + languageName: node + linkType: hard + +"@lukeed/csprng@npm:^1.0.0": + version: 1.1.0 + resolution: "@lukeed/csprng@npm:1.1.0" + checksum: 926f5f7fc629470ca9a8af355bfcd0271d34535f7be3890f69902432bddc3262029bb5dbe9025542cf6c9883d878692eef2815fc2f3ba5b92e9da1f9eba2e51b + languageName: node + linkType: hard + +"@nestjs/common@npm:^9.4.0": + version: 9.4.3 + resolution: "@nestjs/common@npm:9.4.3" + dependencies: + iterare: 1.2.1 + tslib: 2.5.3 + uid: 2.0.2 + peerDependencies: + cache-manager: <=5 + class-transformer: "*" + class-validator: "*" + reflect-metadata: ^0.1.12 + rxjs: ^7.1.0 + peerDependenciesMeta: + cache-manager: + optional: true + class-transformer: + optional: true + class-validator: + optional: true + checksum: 45ccb5acac2521a05576f37b37ab94c63a83aefb1839ed670635090bb934c1bd532852cb7be9863ee3b9d1ad80aa84e0602be023c626623f9233257dcb754914 + languageName: node + linkType: hard + +"@nestjs/core@npm:^9.4.0": + version: 9.4.3 + resolution: "@nestjs/core@npm:9.4.3" + dependencies: + "@nuxtjs/opencollective": 0.3.2 + fast-safe-stringify: 2.1.1 + iterare: 1.2.1 + path-to-regexp: 3.2.0 + tslib: 2.5.3 + uid: 2.0.2 + peerDependencies: + "@nestjs/common": ^9.0.0 + "@nestjs/microservices": ^9.0.0 + "@nestjs/platform-express": ^9.0.0 + "@nestjs/websockets": ^9.0.0 + reflect-metadata: ^0.1.12 + rxjs: ^7.1.0 + peerDependenciesMeta: + "@nestjs/microservices": + optional: true + "@nestjs/platform-express": + optional: true "@nestjs/websockets": optional: true checksum: 5c556c43fc4bce5001c9fa1190630031e60db5678d47c1266f6aca957d862fc8aa7168414cf7938852976ee52086395bd05d4a4daaa0915d12e47c4f644dc263 @@ -3168,6 +4988,13 @@ __metadata: languageName: node linkType: hard +"@noble/ed25519@npm:^1.6.1": + version: 1.7.3 + resolution: "@noble/ed25519@npm:1.7.3" + checksum: 45169927d51de513e47bbeebff3a603433c4ac7579e1b8c5034c380a0afedbe85e6959be3d69584a7a5ed6828d638f8f28879003b9bb2fb5f22d8aa2d88fd5fe + languageName: node + linkType: hard + "@noble/hashes@npm:1.3.2, @noble/hashes@npm:^1, @noble/hashes@npm:^1.0.0, @noble/hashes@npm:^1.3.2": version: 1.3.2 resolution: "@noble/hashes@npm:1.3.2" @@ -3175,6 +5002,13 @@ __metadata: languageName: node linkType: hard +"@noble/hashes@npm:^1.2.0, @noble/hashes@npm:^1.3.3": + version: 1.4.0 + resolution: "@noble/hashes@npm:1.4.0" + checksum: 8ba816ae26c90764b8c42493eea383716396096c5f7ba6bea559993194f49d80a73c081f315f4c367e51bd2d5891700bcdfa816b421d24ab45b41cb03e4f3342 + languageName: node + linkType: hard + "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -3211,6 +5045,26 @@ __metadata: languageName: node linkType: hard +"@nrwl/cli@npm:14.8.9": + version: 14.8.9 + resolution: "@nrwl/cli@npm:14.8.9" + dependencies: + nx: 14.8.9 + checksum: 32e4953121622526636fd76f673eb07197528e7c8927e046f3c157e46edeac5ecdad2182c168d18cc2cc887ab16c74ff94e57194a3df581a0c5b05fffa157d78 + languageName: node + linkType: hard + +"@nrwl/tao@npm:14.8.9": + version: 14.8.9 + resolution: "@nrwl/tao@npm:14.8.9" + dependencies: + nx: 14.8.9 + bin: + tao: index.js + checksum: f299e6f04c8d3ee8aa2ca5143dc4f1a7f1ab3cf2ba398ec65ad34feeb29ad6fa37087f56db5acbe9168d4bdc4a95e607964cc274720075aeb8badec8e5c3038b + languageName: node + linkType: hard + "@nuxtjs/opencollective@npm:0.3.2": version: 0.3.2 resolution: "@nuxtjs/opencollective@npm:0.3.2" @@ -3334,6 +5188,17 @@ __metadata: languageName: node linkType: hard +"@parcel/watcher@npm:2.0.4": + version: 2.0.4 + resolution: "@parcel/watcher@npm:2.0.4" + dependencies: + node-addon-api: ^3.2.1 + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: 890bdc69a52942791b276caa2cd65ef816576d6b5ada91aa28cf302b35d567c801dafe167f2525dcb313f5b420986ea11bd56228dd7ddde1116944d8f924a0a1 + languageName: node + linkType: hard + "@pkgjs/parseargs@npm:^0.11.0": version: 0.11.0 resolution: "@pkgjs/parseargs@npm:0.11.0" @@ -3608,6 +5473,18 @@ __metadata: languageName: node linkType: hard +"@protobufs/cosmos@npm:^0.0.11": + version: 0.0.11 + resolution: "@protobufs/cosmos@npm:0.0.11" + dependencies: + "@protobufs/cosmos_proto": ^0.0.10 + "@protobufs/gogoproto": ^0.0.10 + "@protobufs/google": ^0.0.10 + "@protobufs/tendermint": ^0.0.10 + checksum: a7e737d265cee053aa0ecb4abf7608b07eaac4f6f7344e082824a39b4f78b2de31fb48edbcfa176b743fe8d4c5686015fa6e7fe5899b9d2efc402f66093f5454 + languageName: node + linkType: hard + "@protobufs/cosmos@npm:^0.1.0": version: 0.1.0 resolution: "@protobufs/cosmos@npm:0.1.0" @@ -3717,6 +5594,22 @@ __metadata: languageName: node linkType: hard +"@randlabs/communication-bridge@npm:1.0.1": + version: 1.0.1 + resolution: "@randlabs/communication-bridge@npm:1.0.1" + checksum: 9573e7f848c23c2b600e87b2b6a819894ad69ee0019da72b6ee3da086e52deb5a5055cb001d8f2fc014528b24c5dc476479ddb3ecf70e94abec07c80d0c771ed + languageName: node + linkType: hard + +"@randlabs/myalgo-connect@npm:^1.1.2": + version: 1.4.2 + resolution: "@randlabs/myalgo-connect@npm:1.4.2" + dependencies: + "@randlabs/communication-bridge": 1.0.1 + checksum: 2328adc8f4badae43fce9a29c0de00bc7dd56baee326eb7ed0f8eac69bfdd6e11ef3bb41cb452bad5e340f5edc8a5e5b7233b163f93aaeb80c20a57164a94fe3 + languageName: node + linkType: hard + "@scure/base@npm:^1.1.3": version: 1.1.3 resolution: "@scure/base@npm:1.1.3" @@ -3731,35 +5624,655 @@ __metadata: languageName: node linkType: hard -"@sinclair/typebox@npm:^0.27.8": - version: 0.27.8 - resolution: "@sinclair/typebox@npm:0.27.8" - checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 +"@sinclair/typebox@npm:^0.27.8": + version: 0.27.8 + resolution: "@sinclair/typebox@npm:0.27.8" + checksum: 00bd7362a3439021aa1ea51b0e0d0a0e8ca1351a3d54c606b115fdcc49b51b16db6e5f43b4fe7a28c38688523e22a94d49dd31168868b655f0d4d50f032d07a1 + languageName: node + linkType: hard + +"@sindresorhus/is@npm:^0.14.0": + version: 0.14.0 + resolution: "@sindresorhus/is@npm:0.14.0" + checksum: 971e0441dd44ba3909b467219a5e242da0fc584048db5324cfb8048148fa8dcc9d44d71e3948972c4f6121d24e5da402ef191420d1266a95f713bb6d6e59c98a + languageName: node + linkType: hard + +"@sinonjs/commons@npm:^3.0.0": + version: 3.0.1 + resolution: "@sinonjs/commons@npm:3.0.1" + dependencies: + type-detect: 4.0.8 + checksum: a7c3e7cc612352f4004873747d9d8b2d4d90b13a6d483f685598c945a70e734e255f1ca5dc49702515533c403b32725defff148177453b3f3915bcb60e9d4601 + languageName: node + linkType: hard + +"@sinonjs/fake-timers@npm:^10.0.2": + version: 10.3.0 + resolution: "@sinonjs/fake-timers@npm:10.3.0" + dependencies: + "@sinonjs/commons": ^3.0.0 + checksum: 614d30cb4d5201550c940945d44c9e0b6d64a888ff2cd5b357f95ad6721070d6b8839cd10e15b76bf5e14af0bcc1d8f9ec00d49a46318f1f669a4bec1d7f3148 + languageName: node + linkType: hard + +"@smithy/abort-controller@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/abort-controller@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: d0d7fcaa7b67b04c9ad825017110cc294ff06af07f8054ac3b75d8de88ff5fbef1d08f5c1ae672db1839d14ce25f277c459d2b7b7263cbe9e6c3d4518a19230e + languageName: node + linkType: hard + +"@smithy/chunked-blob-reader-native@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/chunked-blob-reader-native@npm:2.2.0" + dependencies: + "@smithy/util-base64": ^2.3.0 + tslib: ^2.6.2 + checksum: ac619f18844e8a8288672c40b8967a82b78f5398119638b3e4fcadf451a3356139307c2d9f24c8c041530238f1ce6e0f90ce82adfcb050d08afefa2f0541c2d0 + languageName: node + linkType: hard + +"@smithy/chunked-blob-reader@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/chunked-blob-reader@npm:2.2.0" + dependencies: + tslib: ^2.6.2 + checksum: f5acb1e812f97d7c233ccf955557ac10c7e94c8c9610d2fad715d1010fe30ee686a93a5d6e589ce8ae4eb7cf201d5eab61cee5e8646bbebdfa8a5f23693d7a5a + languageName: node + linkType: hard + +"@smithy/config-resolver@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/config-resolver@npm:2.2.0" + dependencies: + "@smithy/node-config-provider": ^2.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-config-provider": ^2.3.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: dcb15d40faf46c370cd83dfbf1e632fae29c64c500b33b53850a520cfb02c9fa6f7e239c07824793b47645462567d51cb1554c02f9ec4531bd51bc759aede2ed + languageName: node + linkType: hard + +"@smithy/core@npm:^1.4.2": + version: 1.4.2 + resolution: "@smithy/core@npm:1.4.2" + dependencies: + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-retry": ^2.3.1 + "@smithy/middleware-serde": ^2.3.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: 414ec1c392ab5346f2b833f310078d7e850df8b9e5db6fedbce65116146c2fda116d56db841401ba05b5e7399a5f5c426870d324bf6fd060143ce66e2f3eafbb + languageName: node + linkType: hard + +"@smithy/credential-provider-imds@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/credential-provider-imds@npm:2.3.0" + dependencies: + "@smithy/node-config-provider": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + tslib: ^2.6.2 + checksum: dd57e09e60bd51ed103f7a5363a43e1373470ea3cee04ace66f5bbaafab005355ffbfa3e137e2ecac34aa28911fb5b6ecac60845846c6a4a5432f3e57a74b837 + languageName: node + linkType: hard + +"@smithy/eventstream-codec@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-codec@npm:2.2.0" + dependencies: + "@aws-crypto/crc32": 3.0.0 + "@smithy/types": ^2.12.0 + "@smithy/util-hex-encoding": ^2.2.0 + tslib: ^2.6.2 + checksum: ae59067964e19c6728b1be74a6e19793e4d3decdcbcea546bd40f77c3cc1eacc48c30272ef68927ba477c2b6450d023474f2dec516dfd93e204150ba18cab697 + languageName: node + linkType: hard + +"@smithy/eventstream-serde-browser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-serde-browser@npm:2.2.0" + dependencies: + "@smithy/eventstream-serde-universal": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: c00bd592365f42ddafcad83f06d3c85ce8ee21bd806de903043ef132de9acca8bf1592ed811b11daba1742332928fc73a66c9032b06df2f6526da0339918f8d5 + languageName: node + linkType: hard + +"@smithy/eventstream-serde-config-resolver@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-serde-config-resolver@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: a35dbcbc14ad1825ce22a9e7daac93067d8ade6173a3ce33b819eed61390f8d93ea63b70945f6d1bced175fad58def3d09a14ee3043c63a798ecef407b2d1701 + languageName: node + linkType: hard + +"@smithy/eventstream-serde-node@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-serde-node@npm:2.2.0" + dependencies: + "@smithy/eventstream-serde-universal": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 1d4971b99654c4672716608a63e668ccefd78cc1806c0ea4df5c3cc0ca0208b7647f7914d2c77a37d0a29b31b66cff660ce2ab2f46f56d997c9a58ea6b6241b2 + languageName: node + linkType: hard + +"@smithy/eventstream-serde-universal@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/eventstream-serde-universal@npm:2.2.0" + dependencies: + "@smithy/eventstream-codec": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: c28038c2f57deed7b5e0e5f8ab8150d4a7947f2971241da96ef1d53b45d83dfa661717065f059099c420ee66ae2455818ae124bb8601b609558040d4a7509227 + languageName: node + linkType: hard + +"@smithy/fetch-http-handler@npm:^2.5.0": + version: 2.5.0 + resolution: "@smithy/fetch-http-handler@npm:2.5.0" + dependencies: + "@smithy/protocol-http": ^3.3.0 + "@smithy/querystring-builder": ^2.2.0 + "@smithy/types": ^2.12.0 + "@smithy/util-base64": ^2.3.0 + tslib: ^2.6.2 + checksum: 91a58ac32c6b4afc6d7fb2b9ac3e3b817171f76e09b013a6506308b044455054444a92e1acbd8f98bdd159b15fdd44b1e3fb52c21cbb2e69be8e3698d2206021 + languageName: node + linkType: hard + +"@smithy/hash-blob-browser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/hash-blob-browser@npm:2.2.0" + dependencies: + "@smithy/chunked-blob-reader": ^2.2.0 + "@smithy/chunked-blob-reader-native": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 1b748b4449ccee723c8b47a412491283fa7b5a2a6c27b0b73e03d905c2af70b56b74d63a658d8ef0bd330cc4617bc11431c86e24a4932b4722aad08e1b25e576 + languageName: node + linkType: hard + +"@smithy/hash-node@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/hash-node@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + "@smithy/util-buffer-from": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 3305b5778fa99558375b16629ad98fd00a1fb33ea905037977b0a7c93d92c8de1481756ef7dbc004e45210b23f983dec04bcd13d43c98f36a5f47291cbed9d89 + languageName: node + linkType: hard + +"@smithy/hash-stream-node@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/hash-stream-node@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 191d76fd1df705c32d24463794f8b8b391061c7ca7265591cd4f070259fa80395c2f115fd3d37f6bb3a4a2303b3811a31509ea767d0c3d0a9644789ae8283118 + languageName: node + linkType: hard + +"@smithy/invalid-dependency@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/invalid-dependency@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: ed17980ccdf4c564cfcb517f3959dfeb7c7dbddd76eaf2c9e10031ebd19e78e56609df3377626215e51a6c4b98db03cfa88ad46f15ba26bb55c34351f3182a98 + languageName: node + linkType: hard + +"@smithy/is-array-buffer@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/is-array-buffer@npm:2.2.0" + dependencies: + tslib: ^2.6.2 + checksum: cd12c2e27884fec89ca8966d33c9dc34d3234efe89b33a9b309c61ebcde463e6f15f6a02d31d4fddbfd6e5904743524ca5b95021b517b98fe10957c2da0cd5fc + languageName: node + linkType: hard + +"@smithy/md5-js@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/md5-js@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: ae343c198a8d8c6689bcb1d7f766e29578d370e8d79180db9b6183b5c74ac091829e8abe3053df0589f53324c01a79c7f9e889e5cd92094e3b5c4be96fb7b970 + languageName: node + linkType: hard + +"@smithy/middleware-content-length@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/middleware-content-length@npm:2.2.0" + dependencies: + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 1eae8d2b6f432ce9a849e741d4f2426baee8a51f22a5262c11802e125078ee33d9d8f4183fb142043ba9d1371adad9c835c784333a394d865fb248339f7482e6 + languageName: node + linkType: hard + +"@smithy/middleware-endpoint@npm:^2.5.1": + version: 2.5.1 + resolution: "@smithy/middleware-endpoint@npm:2.5.1" + dependencies: + "@smithy/middleware-serde": ^2.3.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + "@smithy/url-parser": ^2.2.0 + "@smithy/util-middleware": ^2.2.0 + tslib: ^2.6.2 + checksum: 7ac2a35a6f52c33d868fc4b73330ae34fecfc43c59b8d501ee9fb81924c6747494700b55b3025b83fe7bea3d4e323c8853ec5b117c17cccf06cc27bbc4f492b2 + languageName: node + linkType: hard + +"@smithy/middleware-retry@npm:^2.3.1": + version: 2.3.1 + resolution: "@smithy/middleware-retry@npm:2.3.1" + dependencies: + "@smithy/node-config-provider": ^2.3.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/service-error-classification": ^2.1.5 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-retry": ^2.2.0 + tslib: ^2.6.2 + uuid: ^9.0.1 + checksum: 5eebf9d26fccc6c8c517924463e93d244edebe52d120b28d5d705904f83773da1734296b8d57b4f30a15cbf36690e508f5946dfd56749cbcda501d08cb778933 + languageName: node + linkType: hard + +"@smithy/middleware-serde@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/middleware-serde@npm:2.3.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 5393370c0f8a820d8ca36eccecff5b6434c4f81fbaad8800088fb4c8dad5312bf3eb47f67533784de959807bbb3379c23d81a1bcbaf8824254034dd2b83fd76b + languageName: node + linkType: hard + +"@smithy/middleware-stack@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/middleware-stack@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 293d76764e327a5ada4ea7de268f451e62a6a56983ba7dcdbc63fdbb0427c01071a9a81d7807b16586977df829ce5d9587facbd9367b089841bbc9fc329ce6af + languageName: node + linkType: hard + +"@smithy/node-config-provider@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/node-config-provider@npm:2.3.0" + dependencies: + "@smithy/property-provider": ^2.2.0 + "@smithy/shared-ini-file-loader": ^2.4.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 9c1dc6d97e0379d947498e7d64e593ea183d5f2c89dace4561c1c613850bf264581b597105c15d64ceabdea954e57ad8e6bf9e42642ddc3f737464f350ffbb5b + languageName: node + linkType: hard + +"@smithy/node-http-handler@npm:^2.5.0": + version: 2.5.0 + resolution: "@smithy/node-http-handler@npm:2.5.0" + dependencies: + "@smithy/abort-controller": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/querystring-builder": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 2e63fafdac5bef62181994af2ec065b0f7f04eaed88fb2990a21a9925226fead5013cf4f232b527f3f4d9ffb68ccbe8cd263ad22a7351d36b0dc23e975929a0c + languageName: node + linkType: hard + +"@smithy/property-provider@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/property-provider@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 8d257cbc5222baf6706e288c3b51196588f135878141f8af76fcb3f0abafc027ed46cf4bb938266d1906111175082ee85f73806d5a2b1c929aee16ec8b5283e6 + languageName: node + linkType: hard + +"@smithy/protocol-http@npm:^3.3.0": + version: 3.3.0 + resolution: "@smithy/protocol-http@npm:3.3.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 6c1aaaee9f6ecfb841766938312268f30cbda253f172de7467463aae7d7bfea19a801ab570f3737334e992d2d0ee7446e6af6a6fd82b08533790c489289dff76 + languageName: node + linkType: hard + +"@smithy/querystring-builder@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/querystring-builder@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + "@smithy/util-uri-escape": ^2.2.0 + tslib: ^2.6.2 + checksum: db492903302a694a0e982c37b9a74314160c5ee485742f24f8b6d0da66f121e7ff8588742a3a1964f6b983c15cacd52b883c5efa714882a754f575da7a7e014d + languageName: node + linkType: hard + +"@smithy/querystring-parser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/querystring-parser@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 9b27751c329fecc84bdfe7f128ab766c7e5f1d4bdda6184699a0df8999e95aef21fafc6179d6c693e519c78874e738fd9afb5ac4679901cb68d092a86a612419 + languageName: node + linkType: hard + +"@smithy/service-error-classification@npm:^2.1.5": + version: 2.1.5 + resolution: "@smithy/service-error-classification@npm:2.1.5" + dependencies: + "@smithy/types": ^2.12.0 + checksum: 00ac54110a258c7a47c62d4f655d4998bd40e5adb47e10281b28df7a585f2f1e960dc35325eac006636280e7fb2b81dbeb32b89e08bac87acc136c4d29a4dc53 + languageName: node + linkType: hard + +"@smithy/shared-ini-file-loader@npm:^2.4.0": + version: 2.4.0 + resolution: "@smithy/shared-ini-file-loader@npm:2.4.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: b0c9e045bfe2150e07f4b31ae7d69d3646679337df9fec1e1201b845cc64ea2250c37db8e8d0e7573fc3c11188164adba43bbaf32275fa8a9f70e8bbc77146bf + languageName: node + linkType: hard + +"@smithy/signature-v4@npm:^2.2.1": + version: 2.3.0 + resolution: "@smithy/signature-v4@npm:2.3.0" + dependencies: + "@smithy/is-array-buffer": ^2.2.0 + "@smithy/types": ^2.12.0 + "@smithy/util-hex-encoding": ^2.2.0 + "@smithy/util-middleware": ^2.2.0 + "@smithy/util-uri-escape": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 96050956b86876d0137af9b003d0a30005766bffc730495d7c106bd2eb05c8ada2da23ceac51d56e04f98b304e0ea55d698e1a10c99cda3ade44b3ac30166a00 + languageName: node + linkType: hard + +"@smithy/smithy-client@npm:^2.5.1": + version: 2.5.1 + resolution: "@smithy/smithy-client@npm:2.5.1" + dependencies: + "@smithy/middleware-endpoint": ^2.5.1 + "@smithy/middleware-stack": ^2.2.0 + "@smithy/protocol-http": ^3.3.0 + "@smithy/types": ^2.12.0 + "@smithy/util-stream": ^2.2.0 + tslib: ^2.6.2 + checksum: 10d51793aab8f6e0ba0890a2a101216ffc3a1c43664f8ed9688dcbc174ca0f83f2d1c8d7af484c84491174067af3d6b235b765a58b12f2308a6bfe42b1d74f59 + languageName: node + linkType: hard + +"@smithy/types@npm:^2.12.0": + version: 2.12.0 + resolution: "@smithy/types@npm:2.12.0" + dependencies: + tslib: ^2.6.2 + checksum: 2dd93746624d87afbf51c22116fc69f82e95004b78cf681c4a283d908155c22a2b7a3afbd64a3aff7deefb6619276f186e212422ad200df3b42c32ef5330374e + languageName: node + linkType: hard + +"@smithy/url-parser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/url-parser@npm:2.2.0" + dependencies: + "@smithy/querystring-parser": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: f21f1e44bc2a4634220465990651f5ee0708cb6759b3685b8a8c00cc2cd64bbbc7807f66cd79ec6e654f7245867d4fb4ced406ad5c14612ebc47eae3f34e63c5 + languageName: node + linkType: hard + +"@smithy/util-base64@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/util-base64@npm:2.3.0" + dependencies: + "@smithy/util-buffer-from": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: 2ce995c5d12037e9518bb2732f24090bc493d48118dfd6519faa41e19cd91863895bc0b5958b790d2cdeb919a8c410790dcffa3a452d560f0eeab73dc0c92cbd + languageName: node + linkType: hard + +"@smithy/util-body-length-browser@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-body-length-browser@npm:2.2.0" + dependencies: + tslib: ^2.6.2 + checksum: e9c1d16b3b95d529011476e6154eaf282d3a983204b29dcf1e7ef04a9f5c2deae30167e06190f315771c813c768f19f486d3139fe9fcaf34d12c2333350f3412 + languageName: node + linkType: hard + +"@smithy/util-body-length-node@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/util-body-length-node@npm:2.3.0" + dependencies: + tslib: ^2.6.2 + checksum: 5d5c31b071e0b3222dcfe863ea2d179253f0dfaa30d03f40ebfa352ed292e00a451053cc523e27527e61094d5ed475069d2287ef19a857c6da0364ca71cfdf3c + languageName: node + linkType: hard + +"@smithy/util-buffer-from@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-buffer-from@npm:2.2.0" + dependencies: + "@smithy/is-array-buffer": ^2.2.0 + tslib: ^2.6.2 + checksum: 424c5b7368ae5880a8f2732e298d17879a19ca925f24ca45e1c6c005f717bb15b76eb28174d308d81631ad457ea0088aab0fd3255dd42f45a535c81944ad64d3 + languageName: node + linkType: hard + +"@smithy/util-config-provider@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/util-config-provider@npm:2.3.0" + dependencies: + tslib: ^2.6.2 + checksum: 0f3f113c2658bd5a79f98dc28d53ca9c0adf8ec3c8c86c7dd91d2cd37149b4cf83d85cc89d5fe67ffe5cd319ec85f139ef229844eb039017193b307a4c315399 + languageName: node + linkType: hard + +"@smithy/util-defaults-mode-browser@npm:^2.2.1": + version: 2.2.1 + resolution: "@smithy/util-defaults-mode-browser@npm:2.2.1" + dependencies: + "@smithy/property-provider": ^2.2.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + bowser: ^2.11.0 + tslib: ^2.6.2 + checksum: 286337d9165181e1df3d28d348210e88f20662ec63a9d6c1bcfce3342003de130a218dab42ce64aa4399ef345e2528414f73f399f8f4c8e9a6fcbc8e48250f98 + languageName: node + linkType: hard + +"@smithy/util-defaults-mode-node@npm:^2.3.1": + version: 2.3.1 + resolution: "@smithy/util-defaults-mode-node@npm:2.3.1" + dependencies: + "@smithy/config-resolver": ^2.2.0 + "@smithy/credential-provider-imds": ^2.3.0 + "@smithy/node-config-provider": ^2.3.0 + "@smithy/property-provider": ^2.2.0 + "@smithy/smithy-client": ^2.5.1 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 7fb9d0ac8b5919955399284c1801f49a1f5275f6cf240894ba0a91a8825248bb167938647a983d89905d6bfa7b226789781e85d2ff7f27c58cdd32c2e68600ae + languageName: node + linkType: hard + +"@smithy/util-endpoints@npm:^1.2.0": + version: 1.2.0 + resolution: "@smithy/util-endpoints@npm:1.2.0" + dependencies: + "@smithy/node-config-provider": ^2.3.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 19a59b1c9b214457371d4d7109b190c237de5ebd06f5b4f3665dddc5fe0879dbb19bcdc5dec23d1825cd04388b7f9bf7fddf354e1a23e84d9c690ad21e71cb86 + languageName: node + linkType: hard + +"@smithy/util-hex-encoding@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-hex-encoding@npm:2.2.0" + dependencies: + tslib: ^2.6.2 + checksum: 7d14589bc4a44eebf878595290c53ee4d90cc6b5445b5fe130608d6dea477c292730b85e4e08190a1555ef7664214f0f00dc478ba725516787a49fff658e725e + languageName: node + linkType: hard + +"@smithy/util-middleware@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-middleware@npm:2.2.0" + dependencies: + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 312dc86e5415a12e2580a02311750b350aec8fb9da5a60c3010c10694990ded869b7ca5b87aa20e5facbacdd233e928e418b7765d7797019cd48177052aedd03 + languageName: node + linkType: hard + +"@smithy/util-retry@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-retry@npm:2.2.0" + dependencies: + "@smithy/service-error-classification": ^2.1.5 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 1a8071c8ac5a2646b3d3894e3bd9c36a9db045f52eadb194f32b02d2fdedd69fb267a2b02bcef9f91d0f8f3fe061754ac075d07ac166d90894acb27d68c62a41 + languageName: node + linkType: hard + +"@smithy/util-stream@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-stream@npm:2.2.0" + dependencies: + "@smithy/fetch-http-handler": ^2.5.0 + "@smithy/node-http-handler": ^2.5.0 + "@smithy/types": ^2.12.0 + "@smithy/util-base64": ^2.3.0 + "@smithy/util-buffer-from": ^2.2.0 + "@smithy/util-hex-encoding": ^2.2.0 + "@smithy/util-utf8": ^2.3.0 + tslib: ^2.6.2 + checksum: f0febd1a7558201d9178c0018478f89729800e9b8962dc735ec99f41ce01d1128373e3bd6008f0b4ff79b25ee4476db4fd5fa18d6feeb8b5b715d416da7027c3 + languageName: node + linkType: hard + +"@smithy/util-uri-escape@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-uri-escape@npm:2.2.0" + dependencies: + tslib: ^2.6.2 + checksum: bade35312d75d1c84226f2a81b70dfef91766c02ecb6c6854b6f920cddb423e01963f7d0c183d523b5991f8e7ca93bcf73f8b3c6923979152b8350c9f3c24fd6 + languageName: node + linkType: hard + +"@smithy/util-utf8@npm:^2.3.0": + version: 2.3.0 + resolution: "@smithy/util-utf8@npm:2.3.0" + dependencies: + "@smithy/util-buffer-from": ^2.2.0 + tslib: ^2.6.2 + checksum: 00e55d4b4e37d48be0eef3599082402b933c52a1407fed7e8e8ad76d94d81a0b30b8bfaf2047c59d9c3af31e5f20e7a8c959cb7ae270f894255e05a2229964f0 + languageName: node + linkType: hard + +"@smithy/util-waiter@npm:^2.2.0": + version: 2.2.0 + resolution: "@smithy/util-waiter@npm:2.2.0" + dependencies: + "@smithy/abort-controller": ^2.2.0 + "@smithy/types": ^2.12.0 + tslib: ^2.6.2 + checksum: 303f56beb9ba4afada862eff4950a17d904a4fdfc01bd8acb932b0457e457730981162777004414252e700014c554d894a1ce9d32e0bad75e1a4a2ca6492429e languageName: node linkType: hard -"@sindresorhus/is@npm:^0.14.0": - version: 0.14.0 - resolution: "@sindresorhus/is@npm:0.14.0" - checksum: 971e0441dd44ba3909b467219a5e242da0fc584048db5324cfb8048148fa8dcc9d44d71e3948972c4f6121d24e5da402ef191420d1266a95f713bb6d6e59c98a +"@solana/buffer-layout@npm:^4.0.1": + version: 4.0.1 + resolution: "@solana/buffer-layout@npm:4.0.1" + dependencies: + buffer: ~6.0.3 + checksum: bf846888e813187243d4008a7a9f58b49d16cbd995b9d7f1b72898aa510ed77b1ce5e8468e7b2fd26dd81e557a4e74a666e21fccb95f123c1f740d41138bbacd languageName: node linkType: hard -"@sinonjs/commons@npm:^3.0.0": - version: 3.0.1 - resolution: "@sinonjs/commons@npm:3.0.1" +"@solana/wallet-adapter-base@npm:^0.9.2": + version: 0.9.23 + resolution: "@solana/wallet-adapter-base@npm:0.9.23" dependencies: - type-detect: 4.0.8 - checksum: a7c3e7cc612352f4004873747d9d8b2d4d90b13a6d483f685598c945a70e734e255f1ca5dc49702515533c403b32725defff148177453b3f3915bcb60e9d4601 + "@solana/wallet-standard-features": ^1.1.0 + "@wallet-standard/base": ^1.0.1 + "@wallet-standard/features": ^1.0.3 + eventemitter3: ^4.0.7 + peerDependencies: + "@solana/web3.js": ^1.77.3 + checksum: bd2fc54ae3d82758378c3eb92ab47b976335376082323d3e954e1c18dd35db1fa503eb8d2dd1dd6f6d7936cedfc02ff5db7a5e2f8fc00f6c7d37cf131df906cc languageName: node linkType: hard -"@sinonjs/fake-timers@npm:^10.0.2": - version: 10.3.0 - resolution: "@sinonjs/fake-timers@npm:10.3.0" +"@solana/wallet-standard-features@npm:^1.1.0": + version: 1.2.0 + resolution: "@solana/wallet-standard-features@npm:1.2.0" dependencies: - "@sinonjs/commons": ^3.0.0 - checksum: 614d30cb4d5201550c940945d44c9e0b6d64a888ff2cd5b357f95ad6721070d6b8839cd10e15b76bf5e14af0bcc1d8f9ec00d49a46318f1f669a4bec1d7f3148 + "@wallet-standard/base": ^1.0.1 + "@wallet-standard/features": ^1.0.3 + checksum: 03ec568f9a4a945970dda57abed4c5a9f669798b272bd7c2d6c135c8baeba8fd78a5fd6d850364dba8257eaf84b7bf8578ba039666f377206c2fd89f6093fca3 + languageName: node + linkType: hard + +"@solana/web3.js@npm:^1.36.0": + version: 1.91.4 + resolution: "@solana/web3.js@npm:1.91.4" + dependencies: + "@babel/runtime": ^7.23.4 + "@noble/curves": ^1.2.0 + "@noble/hashes": ^1.3.3 + "@solana/buffer-layout": ^4.0.1 + agentkeepalive: ^4.5.0 + bigint-buffer: ^1.1.5 + bn.js: ^5.2.1 + borsh: ^0.7.0 + bs58: ^4.0.1 + buffer: 6.0.3 + fast-stable-stringify: ^1.0.0 + jayson: ^4.1.0 + node-fetch: ^2.7.0 + rpc-websockets: ^7.5.1 + superstruct: ^0.14.2 + checksum: 9f6ac2f64ac05043cb367c09d5b4f4b859060618dbffc7a27da35fccdac0be9bd84b83899c9547efedc061fa7e20af283a9bacff01972bd047089809facfbdfe languageName: node linkType: hard @@ -3855,6 +6368,8 @@ __metadata: "@cosmjs/cosmwasm-stargate": ^0.32.3 "@cosmjs/proto-signing": ^0.32.3 "@cosmjs/stargate": ^0.32.3 + "@kyvejs/protocol": ^1.0.12 + "@kyvejs/sdk": ^1.1.1 "@nestjs/common": ^9.4.0 "@nestjs/core": ^9.4.0 "@nestjs/event-emitter": ^2.0.0 @@ -4094,6 +6609,13 @@ __metadata: languageName: node linkType: hard +"@supercharge/promise-pool@npm:^2.1.0": + version: 2.4.0 + resolution: "@supercharge/promise-pool@npm:2.4.0" + checksum: d21223256ba05c34a29742172e2b625627038e731f511de0b728c638531096ce12d1a4156fd04e3b34eec980ce8445a66a9d8d070fde7886c9b33a0d759ab2e9 + languageName: node + linkType: hard + "@szmarczak/http-timer@npm:^1.1.2": version: 1.1.2 resolution: "@szmarczak/http-timer@npm:1.1.2" @@ -4207,6 +6729,15 @@ __metadata: languageName: node linkType: hard +"@types/cli-progress@npm:^3.9.2": + version: 3.11.5 + resolution: "@types/cli-progress@npm:3.11.5" + dependencies: + "@types/node": "*" + checksum: 571fb3b11646415ac49c90e8003b82f3ac58d75fde5952caf40b4a079517b6e25e79ab0a7455d0ab0398d0b2de062646dba075d3d1f8d147eed2ab4d41abbf64 + languageName: node + linkType: hard + "@types/connect@npm:*": version: 3.4.36 resolution: "@types/connect@npm:3.4.36" @@ -4216,6 +6747,15 @@ __metadata: languageName: node linkType: hard +"@types/connect@npm:^3.4.33": + version: 3.4.38 + resolution: "@types/connect@npm:3.4.38" + dependencies: + "@types/node": "*" + checksum: 7eb1bc5342a9604facd57598a6c62621e244822442976c443efb84ff745246b10d06e8b309b6e80130026a396f19bf6793b7cecd7380169f369dac3bfc46fb99 + languageName: node + linkType: hard + "@types/cron-converter@npm:^1": version: 1.0.1 resolution: "@types/cron-converter@npm:1.0.1" @@ -4376,6 +6916,15 @@ __metadata: languageName: node linkType: hard +"@types/jsonfile@npm:^6.0.1": + version: 6.1.4 + resolution: "@types/jsonfile@npm:6.1.4" + dependencies: + "@types/node": "*" + checksum: 309fda20eb5f1cf68f2df28931afdf189c5e7e6bec64ac783ce737bb98908d57f6f58757ad5da9be37b815645a6f914e2d4f3ac66c574b8fe1ba6616284d0e97 + languageName: node + linkType: hard + "@types/keyv@npm:^3.1.1": version: 3.1.4 resolution: "@types/keyv@npm:3.1.4" @@ -4467,6 +7016,34 @@ __metadata: languageName: node linkType: hard +"@types/node@npm:10.12.18": + version: 10.12.18 + resolution: "@types/node@npm:10.12.18" + checksum: 333cedae77961347d44329d4042ab0b04569366c4659923bbc3434252d01d63a660375b4e64681336e1caf805d2ab141f08ced39b9bd2d01e30608385f46d8c1 + languageName: node + linkType: hard + +"@types/node@npm:11.11.6": + version: 11.11.6 + resolution: "@types/node@npm:11.11.6" + checksum: 075f1c011cf568e49701419acbcb55c24906b3bb5a34d9412a3b88f228a7a78401a5ad4d3e1cd6855c99aaea5ef96e37fc86ca097e50f06da92cf822befc1fff + languageName: node + linkType: hard + +"@types/node@npm:^12.12.54": + version: 12.20.55 + resolution: "@types/node@npm:12.20.55" + checksum: e4f86785f4092706e0d3b0edff8dca5a13b45627e4b36700acd8dfe6ad53db71928c8dee914d4276c7fd3b6ccd829aa919811c9eb708a2c8e4c6eb3701178c37 + languageName: node + linkType: hard + +"@types/node@npm:^13.7.0": + version: 13.13.52 + resolution: "@types/node@npm:13.13.52" + checksum: 8f1afff497ebeba209e2dc340d823284e087a47632afe99a7daa30eaff80893e520f222ad400cd1f2d3b8288e93cf3eaded52a8e64eaefb8aacfe6c35de98f42 + languageName: node + linkType: hard + "@types/node@npm:^18.16.10": version: 18.17.17 resolution: "@types/node@npm:18.17.17" @@ -4611,6 +7188,15 @@ __metadata: languageName: node linkType: hard +"@types/ws@npm:^7.4.4": + version: 7.4.7 + resolution: "@types/ws@npm:7.4.7" + dependencies: + "@types/node": "*" + checksum: b4c9b8ad209620c9b21e78314ce4ff07515c0cadab9af101c1651e7bfb992d7fd933bd8b9c99d110738fd6db523ed15f82f29f50b45510288da72e964dedb1a3 + languageName: node + linkType: hard + "@types/yargs-parser@npm:*": version: 21.0.0 resolution: "@types/yargs-parser@npm:21.0.0" @@ -4757,6 +7343,22 @@ __metadata: languageName: node linkType: hard +"@wallet-standard/base@npm:^1.0.1": + version: 1.0.1 + resolution: "@wallet-standard/base@npm:1.0.1" + checksum: 8f40bee1c69d2c3c0a4c317b3069301406025f8dc1a794b4b4b6d36d2e8e1e38193e6db1c3ac729c773d380f4e2c3a7454bfd3e138708aa6821b6e2029063590 + languageName: node + linkType: hard + +"@wallet-standard/features@npm:^1.0.3": + version: 1.0.3 + resolution: "@wallet-standard/features@npm:1.0.3" + dependencies: + "@wallet-standard/base": ^1.0.1 + checksum: 000a4087d6fd70aaed7f66b118c85097f1d75aa29b962467ee7dee179d01ce009ee685552f53caaef67fdfab63d452073f6fb3bcc0471e3c88fc7e742d2c4e05 + languageName: node + linkType: hard + "@willsoto/nestjs-prometheus@npm:^5.4.0": version: 5.5.0 resolution: "@willsoto/nestjs-prometheus@npm:5.5.0" @@ -4837,6 +7439,39 @@ __metadata: languageName: node linkType: hard +"@yarnpkg/parsers@npm:^3.0.0-rc.18": + version: 3.0.0 + resolution: "@yarnpkg/parsers@npm:3.0.0" + dependencies: + js-yaml: ^3.10.0 + tslib: ^2.4.0 + checksum: fefe5ecafb5bfa2b678ac9ba9259810fdda40142afd9d0b7e0e5cc1cce1fd824dffc52217c5e429807481d8fd18ead074bd317e64fd626335d3c9f1a320bade2 + languageName: node + linkType: hard + +"@zkochan/js-yaml@npm:0.0.6": + version: 0.0.6 + resolution: "@zkochan/js-yaml@npm:0.0.6" + dependencies: + argparse: ^2.0.1 + bin: + js-yaml: bin/js-yaml.js + checksum: 51b81597a1d1d79c778b8fae48317eaad78d75223d0b7477ad2b35f47cf63b19504da430bb7a03b326e668b282874242cc123e323e57293be038684cb5e755f8 + languageName: node + linkType: hard + +"JSONStream@npm:^1.3.5": + version: 1.3.5 + resolution: "JSONStream@npm:1.3.5" + dependencies: + jsonparse: ^1.2.0 + through: ">=2.2.7 <3" + bin: + JSONStream: ./bin.js + checksum: 2605fa124260c61bad38bb65eba30d2f72216a78e94d0ab19b11b4e0327d572b8d530c0c9cc3b0764f727ad26d39e00bf7ebad57781ca6368394d73169c59e46 + languageName: node + linkType: hard + "abbrev@npm:1, abbrev@npm:^1.0.0": version: 1.1.1 resolution: "abbrev@npm:1.1.1" @@ -4844,6 +7479,21 @@ __metadata: languageName: node linkType: hard +"abstract-level@npm:^1.0.2, abstract-level@npm:^1.0.4": + version: 1.0.4 + resolution: "abstract-level@npm:1.0.4" + dependencies: + buffer: ^6.0.3 + catering: ^2.1.0 + is-buffer: ^2.0.5 + level-supports: ^4.0.0 + level-transcoder: ^1.0.1 + module-error: ^1.0.1 + queue-microtask: ^1.2.3 + checksum: 5b70d08926f5234c3c23ffca848542af4def780dc96d6ca35a81659af80e6439c46f5106bd14a5ea37465173d7dcc8294317048b0194fdf6480103edc4aa9e63 + languageName: node + linkType: hard + "accepts@npm:~1.3.8": version: 1.3.8 resolution: "accepts@npm:1.3.8" @@ -4886,6 +7536,13 @@ __metadata: languageName: node linkType: hard +"aes-js@npm:3.0.0": + version: 3.0.0 + resolution: "aes-js@npm:3.0.0" + checksum: 251e26d533cd1a915b44896b17d5ed68c24a02484cfdd2e74ec700a309267db96651ea4eb657bf20aac32a3baa61f6e34edf8e2fec2de440a655da9942d334b8 + languageName: node + linkType: hard + "agent-base@npm:6, agent-base@npm:^6.0.2": version: 6.0.2 resolution: "agent-base@npm:6.0.2" @@ -4895,7 +7552,7 @@ __metadata: languageName: node linkType: hard -"agentkeepalive@npm:^4.2.1": +"agentkeepalive@npm:^4.2.1, agentkeepalive@npm:^4.5.0": version: 4.5.0 resolution: "agentkeepalive@npm:4.5.0" dependencies: @@ -4952,6 +7609,31 @@ __metadata: languageName: node linkType: hard +"algo-msgpack-with-bigint@npm:^2.1.1": + version: 2.1.1 + resolution: "algo-msgpack-with-bigint@npm:2.1.1" + checksum: 81645fc1248f42b048713f2218a7e108711da34cd229b7a58d18af8c041ea1f72051437afb4fcca2d78e6960094b8a88a2e6a45b6d48bca176b5cad24703a976 + languageName: node + linkType: hard + +"algosdk@npm:^1.13.1": + version: 1.24.1 + resolution: "algosdk@npm:1.24.1" + dependencies: + algo-msgpack-with-bigint: ^2.1.1 + buffer: ^6.0.2 + cross-fetch: ^3.1.5 + hi-base32: ^0.5.1 + js-sha256: ^0.9.0 + js-sha3: ^0.8.0 + js-sha512: ^0.8.0 + json-bigint: ^1.0.0 + tweetnacl: ^1.0.3 + vlq: ^2.0.4 + checksum: 3b6960dddec3d7d37a1505dcb3c6997740c5b02fa076a140efcf51eaddd83b7a7c8f56bab3001ec0ac7b1ccdd264e5a41d051b8bf5b9b72762e338c704547203 + languageName: node + linkType: hard + "ansi-align@npm:^3.0.0": version: 3.0.1 resolution: "ansi-align@npm:3.0.1" @@ -4961,6 +7643,13 @@ __metadata: languageName: node linkType: hard +"ansi-colors@npm:^4.1.1": + version: 4.1.3 + resolution: "ansi-colors@npm:4.1.3" + checksum: a9c2ec842038a1fabc7db9ece7d3177e2fe1c5dc6f0c51ecfbf5f39911427b89c00b5dc6b8bd95f82a26e9b16aaae2e83d45f060e98070ce4d1333038edceb0e + languageName: node + linkType: hard + "ansi-escapes@npm:^2.0.0": version: 2.0.0 resolution: "ansi-escapes@npm:2.0.0" @@ -5096,6 +7785,39 @@ __metadata: languageName: node linkType: hard +"arbundles@npm:^0.6.21": + version: 0.6.23 + resolution: "arbundles@npm:0.6.23" + dependencies: + "@noble/ed25519": ^1.6.1 + "@randlabs/myalgo-connect": ^1.1.2 + "@solana/wallet-adapter-base": ^0.9.2 + algosdk: ^1.13.1 + arweave: ^1.11.4 + arweave-stream-tx: ^1.1.0 + avsc: "https://github.com/Irys-xyz/avsc#csp-fixes" + axios: ^0.21.3 + base64url: ^3.0.1 + bs58: ^4.0.1 + ethers: ^5.5.1 + keccak: ^3.0.2 + multistream: ^4.1.0 + process: ^0.11.10 + secp256k1: ^4.0.2 + tmp-promise: ^3.0.2 + checksum: 7968b998df35b12e84297310c7941665bb4be55ecc059b1f797ebe6cc90da129e20d87fda7aaa007cfe0416173a33d014aff3abf8710ec065a2f4f19f04e9a36 + languageName: node + linkType: hard + +"arconnect@npm:^0.4.2": + version: 0.4.2 + resolution: "arconnect@npm:0.4.2" + dependencies: + arweave: ^1.10.13 + checksum: 5b2f262a93a3a25d4bd6f72eb3afe4b13d0e94ed12f88b7bcf3501d25839e74c2882fa1a1a9b527ac9c6da22ca2f407c07fc49e3d898a4f24b5d66a1901173f8 + languageName: node + linkType: hard + "are-we-there-yet@npm:^3.0.0": version: 3.0.1 resolution: "are-we-there-yet@npm:3.0.1" @@ -5232,6 +7954,41 @@ __metadata: languageName: node linkType: hard +"arweave-stream-tx@npm:^1.1.0": + version: 1.2.2 + resolution: "arweave-stream-tx@npm:1.2.2" + dependencies: + exponential-backoff: ^3.1.0 + peerDependencies: + arweave: ^1.10.0 + checksum: 7db2ef3078f28d25e9be096b7680da08b6d9a3b8f44216770a2c08be90ae192569ab948fc9904b930b61f8e0fef8a4e7f77165c2e18b68f3d586274034540c5c + languageName: node + linkType: hard + +"arweave@npm:^1.10.13, arweave@npm:^1.10.17, arweave@npm:^1.11.4": + version: 1.15.0 + resolution: "arweave@npm:1.15.0" + dependencies: + arconnect: ^0.4.2 + asn1.js: ^5.4.1 + base64-js: ^1.5.1 + bignumber.js: ^9.0.2 + checksum: 05530b30a77ac16b60285d7856553d97a6e0192139cfd9fb63246160aa6179fc20e603d024a080ddb77acd1669688d098cb9f6b6d6ed9a43aa04fdce3e382144 + languageName: node + linkType: hard + +"asn1.js@npm:^5.4.1": + version: 5.4.1 + resolution: "asn1.js@npm:5.4.1" + dependencies: + bn.js: ^4.0.0 + inherits: ^2.0.1 + minimalistic-assert: ^1.0.0 + safer-buffer: ^2.1.0 + checksum: 3786a101ac6f304bd4e9a7df79549a7561950a13d4bcaec0c7790d44c80d147c1a94ba3d4e663673406064642a40b23fcd6c82a9952468e386c1a1376d747f9a + languageName: node + linkType: hard + "ast-stringify@npm:0.1.0": version: 0.1.0 resolution: "ast-stringify@npm:0.1.0" @@ -5264,6 +8021,15 @@ __metadata: languageName: node linkType: hard +"async-retry@npm:^1.3.3": + version: 1.3.3 + resolution: "async-retry@npm:1.3.3" + dependencies: + retry: 0.13.1 + checksum: 38a7152ff7265a9321ea214b9c69e8224ab1febbdec98efbbde6e562f17ff68405569b796b1c5271f354aef8783665d29953f051f68c1fc45306e61aec82fdc4 + languageName: node + linkType: hard + "async@npm:^3.2.3": version: 3.2.4 resolution: "async@npm:3.2.4" @@ -5299,6 +8065,50 @@ __metadata: languageName: node linkType: hard +"avsc@https://github.com/Irys-xyz/avsc#csp-fixes": + version: 5.4.7 + resolution: "avsc@https://github.com/Irys-xyz/avsc.git#commit=a730cc8018b79e114b6a3381bbb57760a24c6cef" + checksum: 94d2b1b20c51fecb11a2e596d042c057055c11d9275e8718b090b81a90e82134571553f2c250001770f5a92cfed4e8687fdd77b138c120eaa424db8335d4a1a9 + languageName: node + linkType: hard + +"axios@npm:0.25.0, axios@npm:^0.25.0": + version: 0.25.0 + resolution: "axios@npm:0.25.0" + dependencies: + follow-redirects: ^1.14.7 + checksum: 2a8a3787c05f2a0c9c3878f49782357e2a9f38945b93018fb0c4fd788171c43dceefbb577988628e09fea53952744d1ecebde234b561f1e703aa43e0a598a3ad + languageName: node + linkType: hard + +"axios@npm:^0.21.2, axios@npm:^0.21.3": + version: 0.21.4 + resolution: "axios@npm:0.21.4" + dependencies: + follow-redirects: ^1.14.0 + checksum: 44245f24ac971e7458f3120c92f9d66d1fc695e8b97019139de5b0cc65d9b8104647db01e5f46917728edfc0cfd88eb30fc4c55e6053eef4ace76768ce95ff3c + languageName: node + linkType: hard + +"axios@npm:^0.24.0": + version: 0.24.0 + resolution: "axios@npm:0.24.0" + dependencies: + follow-redirects: ^1.14.4 + checksum: 468cf496c08a6aadfb7e699bebdac02851e3043d4e7d282350804ea8900e30d368daa6e3cd4ab83b8ddb5a3b1e17a5a21ada13fc9cebd27b74828f47a4236316 + languageName: node + linkType: hard + +"axios@npm:^0.27.2": + version: 0.27.2 + resolution: "axios@npm:0.27.2" + dependencies: + follow-redirects: ^1.14.9 + form-data: ^4.0.0 + checksum: 38cb7540465fe8c4102850c4368053c21683af85c5fdf0ea619f9628abbcb59415d1e22ebc8a6390d2bbc9b58a9806c874f139767389c862ec9b772235f06854 + languageName: node + linkType: hard + "axios@npm:^0.28.0": version: 0.28.0 resolution: "axios@npm:0.28.0" @@ -5310,7 +8120,7 @@ __metadata: languageName: node linkType: hard -"axios@npm:^1.6.0": +"axios@npm:^1.0.0, axios@npm:^1.6.0": version: 1.6.8 resolution: "axios@npm:1.6.8" dependencies: @@ -5483,20 +8293,43 @@ __metadata: languageName: node linkType: hard -"base64-js@npm:^1.3.0, base64-js@npm:^1.3.1": +"base-x@npm:^3.0.2": + version: 3.0.9 + resolution: "base-x@npm:3.0.9" + dependencies: + safe-buffer: ^5.0.1 + checksum: 957101d6fd09e1903e846fd8f69fd7e5e3e50254383e61ab667c725866bec54e5ece5ba49ce385128ae48f9ec93a26567d1d5ebb91f4d56ef4a9cc0d5a5481e8 + languageName: node + linkType: hard + +"base64-js@npm:^1.3.0, base64-js@npm:^1.3.1, base64-js@npm:^1.5.1": version: 1.5.1 resolution: "base64-js@npm:1.5.1" checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005 languageName: node linkType: hard -"bech32@npm:^1.1.4": +"base64url@npm:^3.0.1": + version: 3.0.1 + resolution: "base64url@npm:3.0.1" + checksum: a77b2a3a526b3343e25be424de3ae0aa937d78f6af7c813ef9020ef98001c0f4e2323afcd7d8b2d2978996bf8c42445c3e9f60c218c622593e5fdfd54a3d6e18 + languageName: node + linkType: hard + +"bech32@npm:1.1.4, bech32@npm:^1.1.4": version: 1.1.4 resolution: "bech32@npm:1.1.4" checksum: 0e98db619191548390d6f09ff68b0253ba7ae6a55db93dfdbb070ba234c1fd3308c0606fbcc95fad50437227b10011e2698b89f0181f6e7f845c499bd14d0f4b languageName: node linkType: hard +"bech32@npm:2.0.0": + version: 2.0.0 + resolution: "bech32@npm:2.0.0" + checksum: fa15acb270b59aa496734a01f9155677b478987b773bf701f465858bf1606c6a970085babd43d71ce61895f1baa594cb41a2cd1394bd2c6698f03cc2d811300e + languageName: node + linkType: hard + "before-after-hook@npm:^2.2.0": version: 2.2.3 resolution: "before-after-hook@npm:2.2.3" @@ -5504,6 +8337,37 @@ __metadata: languageName: node linkType: hard +"big-integer@npm:^1.6.48": + version: 1.6.52 + resolution: "big-integer@npm:1.6.52" + checksum: 6e86885787a20fed96521958ae9086960e4e4b5e74d04f3ef7513d4d0ad631a9f3bde2730fc8aaa4b00419fc865f6ec573e5320234531ef37505da7da192c40b + languageName: node + linkType: hard + +"bigint-buffer@npm:^1.1.5": + version: 1.1.5 + resolution: "bigint-buffer@npm:1.1.5" + dependencies: + bindings: ^1.3.0 + node-gyp: latest + checksum: d010c9f57758bcdaccb435d88b483ffcc95fe8bbc6e7fb3a44fb5221f29c894ffaf4a3c5a4a530e0e7d6608203c2cde9b79ee4f2386cd6d4462d1070bc8c9f4e + languageName: node + linkType: hard + +"bignumber.js@npm:9.0.2": + version: 9.0.2 + resolution: "bignumber.js@npm:9.0.2" + checksum: 8637b71d0a99104b20413c47578953970006fec6b4df796b9dcfd9835ea9c402ea0e727eba9a5ca9f9a393c1d88b6168c5bbe0887598b708d4f8b4870ad62e1f + languageName: node + linkType: hard + +"bignumber.js@npm:9.1.2, bignumber.js@npm:^9.0.0, bignumber.js@npm:^9.0.1, bignumber.js@npm:^9.0.2": + version: 9.1.2 + resolution: "bignumber.js@npm:9.1.2" + checksum: 582c03af77ec9cb0ebd682a373ee6c66475db94a4325f92299621d544aa4bd45cb45fd60001610e94aef8ae98a0905fa538241d9638d4422d57abbeeac6fadaf + languageName: node + linkType: hard + "binary-extensions@npm:^2.0.0": version: 2.2.0 resolution: "binary-extensions@npm:2.2.0" @@ -5511,6 +8375,15 @@ __metadata: languageName: node linkType: hard +"bindings@npm:^1.3.0": + version: 1.5.0 + resolution: "bindings@npm:1.5.0" + dependencies: + file-uri-to-path: 1.0.0 + checksum: 65b6b48095717c2e6105a021a7da4ea435aa8d3d3cd085cb9e85bcb6e5773cf318c4745c3f7c504412855940b585bdf9b918236612a1c7a7942491de176f1ae7 + languageName: node + linkType: hard + "bintrees@npm:1.0.2": version: 1.0.2 resolution: "bintrees@npm:1.0.2" @@ -5518,7 +8391,53 @@ __metadata: languageName: node linkType: hard -"bl@npm:^4.1.0": +"bip32@npm:^2.0.6": + version: 2.0.6 + resolution: "bip32@npm:2.0.6" + dependencies: + "@types/node": 10.12.18 + bs58check: ^2.1.1 + create-hash: ^1.2.0 + create-hmac: ^1.1.7 + tiny-secp256k1: ^1.1.3 + typeforce: ^1.11.5 + wif: ^2.0.6 + checksum: 1c654a93836d8ed0bf5aa18a9b7b8dc3fe65e6a607a736d2acdb7927276c03db4bf8068324b9907e362759f9307d8b2b61c2547c282a2bc5198305f5654ed554 + languageName: node + linkType: hard + +"bip39-light@npm:^1.0.7": + version: 1.0.7 + resolution: "bip39-light@npm:1.0.7" + dependencies: + create-hash: ^1.1.0 + pbkdf2: ^3.0.9 + checksum: 10ffceacc34e4d2c6449e2f45bba90a3e3455e63e51044da289f68e66cbc1727a9f489a76f199dd5ac50b6be50a7f075e546ed62ab236a50e215480a27567661 + languageName: node + linkType: hard + +"bip39@npm:3.0.2": + version: 3.0.2 + resolution: "bip39@npm:3.0.2" + dependencies: + "@types/node": 11.11.6 + create-hash: ^1.1.0 + pbkdf2: ^3.0.9 + randombytes: ^2.0.1 + checksum: 71798582b4d1cc7f20d11372413c4514f124d302e6b38e7f9126d4759fca3e9fbccb431429a6ab16130dd67193de3d781122fcd4bca0a653be654d4aa13490c5 + languageName: node + linkType: hard + +"bip39@npm:^3.0.2, bip39@npm:^3.0.3": + version: 3.1.0 + resolution: "bip39@npm:3.1.0" + dependencies: + "@noble/hashes": ^1.2.0 + checksum: 1224e763ffc6b097052ed8abd57f0e521ad6d31f1645be0d0a15f4417c13f8461f00e47e9cf7c8c784bd533f4fb1ee3ab020f258c7df45ee5dc722b4b0336cfc + languageName: node + linkType: hard + +"bl@npm:^4.0.3, bl@npm:^4.1.0": version: 4.1.0 resolution: "bl@npm:4.1.0" dependencies: @@ -5538,7 +8457,14 @@ __metadata: languageName: node linkType: hard -"bn.js@npm:^4.11.9": +"bn.js@npm:5.2.0": + version: 5.2.0 + resolution: "bn.js@npm:5.2.0" + checksum: 6117170393200f68b35a061ecbf55d01dd989302e7b3c798a3012354fa638d124f0b2f79e63f77be5556be80322a09c40339eda6413ba7468524c0b6d4b4cb7a + languageName: node + linkType: hard + +"bn.js@npm:^4.0.0, bn.js@npm:^4.11.8, bn.js@npm:^4.11.9": version: 4.12.0 resolution: "bn.js@npm:4.12.0" checksum: 39afb4f15f4ea537b55eaf1446c896af28ac948fdcf47171961475724d1bb65118cca49fa6e3d67706e4790955ec0e74de584e45c8f1ef89f46c812bee5b5a12 @@ -5599,6 +8525,35 @@ __metadata: languageName: node linkType: hard +"borsh@npm:^0.6.0": + version: 0.6.0 + resolution: "borsh@npm:0.6.0" + dependencies: + bn.js: ^5.2.0 + bs58: ^4.0.0 + text-encoding-utf-8: ^1.0.2 + checksum: 633986769e931dd9d156c0d52a315cd3bb0546c24df84e28fa04859cccbebd9107f1621bd594d4a63ba23c7cda2931a8d97e54952ee766a097d3c2434f80b009 + languageName: node + linkType: hard + +"borsh@npm:^0.7.0": + version: 0.7.0 + resolution: "borsh@npm:0.7.0" + dependencies: + bn.js: ^5.2.0 + bs58: ^4.0.0 + text-encoding-utf-8: ^1.0.2 + checksum: e98bfb5f7cfb820819c2870b884dac58dd4b4ce6a86c286c8fbf5c9ca582e73a8c6094df67e81a28c418ff07a309c6b118b2e27fdfea83fd92b8100c741da0b5 + languageName: node + linkType: hard + +"bowser@npm:^2.11.0": + version: 2.11.0 + resolution: "bowser@npm:2.11.0" + checksum: 29c3f01f22e703fa6644fc3b684307442df4240b6e10f6cfe1b61c6ca5721073189ca97cdeedb376081148c8518e33b1d818a57f781d70b0b70e1f31fb48814f + languageName: node + linkType: hard + "boxen@npm:^5.0.0, boxen@npm:^5.0.1": version: 5.1.2 resolution: "boxen@npm:5.1.2" @@ -5650,6 +8605,18 @@ __metadata: languageName: node linkType: hard +"browser-level@npm:^1.0.1": + version: 1.0.1 + resolution: "browser-level@npm:1.0.1" + dependencies: + abstract-level: ^1.0.2 + catering: ^2.1.1 + module-error: ^1.0.2 + run-parallel-limit: ^1.1.0 + checksum: 67fbc77ce832940bfa25073eccff279f512ad56f545deb996a5b23b02316f5e76f4a79d381acc27eda983f5c9a2566aaf9c97e4fdd0748288c4407307537a29b + languageName: node + linkType: hard + "browser-readablestream-to-it@npm:^1.0.0, browser-readablestream-to-it@npm:^1.0.1, browser-readablestream-to-it@npm:^1.0.3": version: 1.0.3 resolution: "browser-readablestream-to-it@npm:1.0.3" @@ -5685,12 +8652,32 @@ __metadata: languageName: node linkType: hard -"bs-logger@npm:0.x": - version: 0.2.6 - resolution: "bs-logger@npm:0.2.6" +"bs-logger@npm:0.x": + version: 0.2.6 + resolution: "bs-logger@npm:0.2.6" + dependencies: + fast-json-stable-stringify: 2.x + checksum: d34bdaf68c64bd099ab97c3ea608c9ae7d3f5faa1178b3f3f345acd94e852e608b2d4f9103fb2e503f5e69780e98293df41691b84be909b41cf5045374d54606 + languageName: node + linkType: hard + +"bs58@npm:^4.0.0, bs58@npm:^4.0.1": + version: 4.0.1 + resolution: "bs58@npm:4.0.1" + dependencies: + base-x: ^3.0.2 + checksum: b3c5365bb9e0c561e1a82f1a2d809a1a692059fae016be233a6127ad2f50a6b986467c3a50669ce4c18929dcccb297c5909314dd347a25a68c21b68eb3e95ac2 + languageName: node + linkType: hard + +"bs58check@npm:<3.0.0, bs58check@npm:^2.1.1, bs58check@npm:^2.1.2": + version: 2.1.2 + resolution: "bs58check@npm:2.1.2" dependencies: - fast-json-stable-stringify: 2.x - checksum: d34bdaf68c64bd099ab97c3ea608c9ae7d3f5faa1178b3f3f345acd94e852e608b2d4f9103fb2e503f5e69780e98293df41691b84be909b41cf5045374d54606 + bs58: ^4.0.0 + create-hash: ^1.1.0 + safe-buffer: ^5.1.2 + checksum: 43bdf08a5dd04581b78f040bc4169480e17008da482ffe2a6507327bbc4fc5c28de0501f7faf22901cfe57fbca79cbb202ca529003fedb4cb8dccd265b38e54d languageName: node linkType: hard @@ -5717,6 +8704,16 @@ __metadata: languageName: node linkType: hard +"buffer@npm:6.0.3, buffer@npm:^6.0.1, buffer@npm:^6.0.2, buffer@npm:^6.0.3, buffer@npm:~6.0.3": + version: 6.0.3 + resolution: "buffer@npm:6.0.3" + dependencies: + base64-js: ^1.3.1 + ieee754: ^1.2.1 + checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9 + languageName: node + linkType: hard + "buffer@npm:^5.5.0": version: 5.7.1 resolution: "buffer@npm:5.7.1" @@ -5727,13 +8724,13 @@ __metadata: languageName: node linkType: hard -"buffer@npm:^6.0.1, buffer@npm:^6.0.3": - version: 6.0.3 - resolution: "buffer@npm:6.0.3" +"bufferutil@npm:^4.0.1": + version: 4.0.8 + resolution: "bufferutil@npm:4.0.8" dependencies: - base64-js: ^1.3.1 - ieee754: ^1.2.1 - checksum: 5ad23293d9a731e4318e420025800b42bf0d264004c0286c8cc010af7a270c7a0f6522e84f54b9ad65cbd6db20b8badbfd8d2ebf4f80fa03dab093b89e68c3f9 + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: 7e9a46f1867dca72fda350966eb468eca77f4d623407b0650913fadf73d5750d883147d6e5e21c56f9d3b0bdc35d5474e80a600b9f31ec781315b4d2469ef087 languageName: node linkType: hard @@ -5809,6 +8806,19 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" + dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.1 + checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029 + languageName: node + linkType: hard + "call-me-maybe@npm:^1.0.1": version: 1.0.2 resolution: "call-me-maybe@npm:1.0.2" @@ -5851,6 +8861,20 @@ __metadata: languageName: node linkType: hard +"capability@npm:^0.2.5": + version: 0.2.5 + resolution: "capability@npm:0.2.5" + checksum: 59ce65958dc0f2e76e7007fe8d5a0a85801b950bb957779c11948776f0e7a1290b9638bfd2da92b4b8bebd7584f92a8c38d4e6613659c9637783a6993026b08b + languageName: node + linkType: hard + +"case-anything@npm:^2.1.13": + version: 2.1.13 + resolution: "case-anything@npm:2.1.13" + checksum: c39c69d7e418337b6006a9692f13c2b257e907e867149a102e9beb7e9d2d52da14e754da1f4e4ce82a866d86d93047e522f64360bda54e7d7c308f4cdd736c3d + languageName: node + linkType: hard + "case@npm:1.6.3": version: 1.6.3 resolution: "case@npm:1.6.3" @@ -5858,6 +8882,13 @@ __metadata: languageName: node linkType: hard +"catering@npm:^2.1.0, catering@npm:^2.1.1": + version: 2.1.1 + resolution: "catering@npm:2.1.1" + checksum: 205daefa69c935b0c19f3d8f2e0a520dd69aebe9bda55902958003f7c9cff8f967dfb90071b421bd6eb618576f657a89d2bc0986872c9bc04bbd66655e9d4bd6 + languageName: node + linkType: hard + "cborg@npm:^1.5.4, cborg@npm:^1.6.0": version: 1.10.2 resolution: "cborg@npm:1.10.2" @@ -5867,6 +8898,16 @@ __metadata: languageName: node linkType: hard +"chalk@npm:4.1.0": + version: 4.1.0 + resolution: "chalk@npm:4.1.0" + dependencies: + ansi-styles: ^4.1.0 + supports-color: ^7.1.0 + checksum: 5561c7b4c063badee3e16d04bce50bd033e1be1bf4c6948639275683ffa7a1993c44639b43c22b1c505f0f813a24b1889037eb182546b48946f9fe7cdd0e7d13 + languageName: node + linkType: hard + "chalk@npm:^1.0.0, chalk@npm:^1.1.3": version: 1.1.3 resolution: "chalk@npm:1.1.3" @@ -5901,7 +8942,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.2": +"chalk@npm:^4.0.0, chalk@npm:^4.0.2, chalk@npm:^4.1.0, chalk@npm:^4.1.1, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" dependencies: @@ -5953,6 +8994,25 @@ __metadata: languageName: node linkType: hard +"chokidar@npm:^3.5.1": + version: 3.6.0 + resolution: "chokidar@npm:3.6.0" + dependencies: + anymatch: ~3.1.2 + braces: ~3.0.2 + fsevents: ~2.3.2 + glob-parent: ~5.1.2 + is-binary-path: ~2.1.0 + is-glob: ~4.0.1 + normalize-path: ~3.0.0 + readdirp: ~3.6.0 + dependenciesMeta: + fsevents: + optional: true + checksum: d2f29f499705dcd4f6f3bbed79a9ce2388cf530460122eed3b9c48efeab7a4e28739c6551fd15bec9245c6b9eeca7a32baa64694d64d9b6faeb74ddb8c4a413d + languageName: node + linkType: hard + "chokidar@npm:^3.5.2": version: 3.5.3 resolution: "chokidar@npm:3.5.3" @@ -6000,6 +9060,16 @@ __metadata: languageName: node linkType: hard +"cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3": + version: 1.0.4 + resolution: "cipher-base@npm:1.0.4" + dependencies: + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + checksum: 47d3568dbc17431a339bad1fe7dff83ac0891be8206911ace3d3b818fc695f376df809bea406e759cdea07fff4b454fa25f1013e648851bec790c1d75763032e + languageName: node + linkType: hard + "cjs-module-lexer@npm:^1.0.0": version: 1.2.3 resolution: "cjs-module-lexer@npm:1.2.3" @@ -6025,6 +9095,20 @@ __metadata: languageName: node linkType: hard +"classic-level@npm:^1.2.0": + version: 1.4.1 + resolution: "classic-level@npm:1.4.1" + dependencies: + abstract-level: ^1.0.2 + catering: ^2.1.0 + module-error: ^1.0.1 + napi-macros: ^2.2.2 + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: 62e7e07297fcd656941eb88f92b91df0046ebb2b34987e98ec870cb736f096e212ef109a25541deba2f30866b9d5df550594ed04948614815dd5964933da50a9 + languageName: node + linkType: hard + "clean-stack@npm:^2.0.0": version: 2.2.0 resolution: "clean-stack@npm:2.2.0" @@ -6052,6 +9136,15 @@ __metadata: languageName: node linkType: hard +"cli-cursor@npm:3.1.0, cli-cursor@npm:^3.1.0": + version: 3.1.0 + resolution: "cli-cursor@npm:3.1.0" + dependencies: + restore-cursor: ^3.1.0 + checksum: 2692784c6cd2fd85cfdbd11f53aea73a463a6d64a77c3e098b2b4697a20443f430c220629e1ca3b195ea5ac4a97a74c2ee411f3807abf6df2b66211fec0c0a29 + languageName: node + linkType: hard + "cli-cursor@npm:^2.1.0": version: 2.1.0 resolution: "cli-cursor@npm:2.1.0" @@ -6061,12 +9154,10 @@ __metadata: languageName: node linkType: hard -"cli-cursor@npm:^3.1.0": - version: 3.1.0 - resolution: "cli-cursor@npm:3.1.0" - dependencies: - restore-cursor: ^3.1.0 - checksum: 2692784c6cd2fd85cfdbd11f53aea73a463a6d64a77c3e098b2b4697a20443f430c220629e1ca3b195ea5ac4a97a74c2ee411f3807abf6df2b66211fec0c0a29 +"cli-spinners@npm:2.6.1": + version: 2.6.1 + resolution: "cli-spinners@npm:2.6.1" + checksum: 423409baaa7a58e5104b46ca1745fbfc5888bbd0b0c5a626e052ae1387060839c8efd512fb127e25769b3dc9562db1dc1b5add6e0b93b7ef64f477feb6416a45 languageName: node linkType: hard @@ -6104,6 +9195,13 @@ __metadata: languageName: node linkType: hard +"cli-width@npm:^3.0.0": + version: 3.0.0 + resolution: "cli-width@npm:3.0.0" + checksum: 4c94af3769367a70e11ed69aa6095f1c600c0ff510f3921ab4045af961820d57c0233acfa8b6396037391f31b4c397e1f614d234294f979ff61430a6c166c3f6 + languageName: node + linkType: hard + "cliui@npm:^7.0.2": version: 7.0.4 resolution: "cliui@npm:7.0.4" @@ -6142,6 +9240,13 @@ __metadata: languageName: node linkType: hard +"clone@npm:^2.1.2": + version: 2.1.2 + resolution: "clone@npm:2.1.2" + checksum: aaf106e9bc025b21333e2f4c12da539b568db4925c0501a1bf4070836c9e848c892fa22c35548ce0d1132b08bbbfa17a00144fe58fccdab6fa900fec4250f67d + languageName: node + linkType: hard + "co@npm:^4.6.0": version: 4.6.0 resolution: "co@npm:4.6.0" @@ -6220,7 +9325,21 @@ __metadata: languageName: node linkType: hard -"commander@npm:^9.3.0": +"commander@npm:^2.20.3": + version: 2.20.3 + resolution: "commander@npm:2.20.3" + checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e + languageName: node + linkType: hard + +"commander@npm:^8.2.0": + version: 8.3.0 + resolution: "commander@npm:8.3.0" + checksum: 0f82321821fc27b83bd409510bb9deeebcfa799ff0bf5d102128b500b7af22872c0c92cb6a0ebc5a4cf19c6b550fba9cedfa7329d18c6442a625f851377bacf0 + languageName: node + linkType: hard + +"commander@npm:^9.3.0, commander@npm:^9.4.1": version: 9.5.0 resolution: "commander@npm:9.5.0" checksum: c7a3e27aa59e913b54a1bafd366b88650bc41d6651f0cbe258d4ff09d43d6a7394232a4dadd0bf518b3e696fdf595db1028a0d82c785b88bd61f8a440cecfade @@ -6344,6 +9463,36 @@ __metadata: languageName: node linkType: hard +"cosmjs-types@npm:^0.4.0": + version: 0.4.1 + resolution: "cosmjs-types@npm:0.4.1" + dependencies: + long: ^4.0.0 + protobufjs: ~6.11.2 + checksum: 7921026bb7f1fef70a6d3c3cbfc71d6af21616d532e5cd9f2af15b94c53f98f8d76da65a8fd60f930df2a9ff4eebed1bb3f49baa3eac7117981fbc8f45259005 + languageName: node + linkType: hard + +"cosmjs-types@npm:^0.7.1": + version: 0.7.2 + resolution: "cosmjs-types@npm:0.7.2" + dependencies: + long: ^4.0.0 + protobufjs: ~6.11.2 + checksum: 4a0b730a7f1ae8efa8bd044f9ebdd7921f26319ff2abf36ac7e2f93ef6f3e73d90c1775ce2325611d47c4ccc72a708a63e31e89d9d80ad75c1107c7228e09bc8 + languageName: node + linkType: hard + +"cosmjs-types@npm:^0.8.0": + version: 0.8.0 + resolution: "cosmjs-types@npm:0.8.0" + dependencies: + long: ^4.0.0 + protobufjs: ~6.11.2 + checksum: 99714ec956d2cb2e521d39896c9c9a24cf9df0d370265c203646ea015b51e86472efc0cb11f67a80f0649d178b0bcff77ac659e67fdfc8b2437cd7a42018577f + languageName: node + linkType: hard + "cosmjs-types@npm:^0.9.0": version: 0.9.0 resolution: "cosmjs-types@npm:0.9.0" @@ -6351,6 +9500,33 @@ __metadata: languageName: node linkType: hard +"create-hash@npm:^1.1.0, create-hash@npm:^1.1.2, create-hash@npm:^1.2.0": + version: 1.2.0 + resolution: "create-hash@npm:1.2.0" + dependencies: + cipher-base: ^1.0.1 + inherits: ^2.0.1 + md5.js: ^1.3.4 + ripemd160: ^2.0.1 + sha.js: ^2.4.0 + checksum: 02a6ae3bb9cd4afee3fabd846c1d8426a0e6b495560a977ba46120c473cb283be6aa1cace76b5f927cf4e499c6146fb798253e48e83d522feba807d6b722eaa9 + languageName: node + linkType: hard + +"create-hmac@npm:1.1.7, create-hmac@npm:^1.1.4, create-hmac@npm:^1.1.7": + version: 1.1.7 + resolution: "create-hmac@npm:1.1.7" + dependencies: + cipher-base: ^1.0.3 + create-hash: ^1.1.0 + inherits: ^2.0.1 + ripemd160: ^2.0.0 + safe-buffer: ^5.0.1 + sha.js: ^2.4.8 + checksum: ba12bb2257b585a0396108c72830e85f882ab659c3320c83584b1037f8ab72415095167ced80dc4ce8e446a8ecc4b2acf36d87befe0707d73b26cf9dc77440ed + languageName: node + linkType: hard + "create-jest@npm:^29.7.0": version: 29.7.0 resolution: "create-jest@npm:29.7.0" @@ -6394,7 +9570,7 @@ __metadata: languageName: node linkType: hard -"cross-fetch@npm:^3.1.6": +"cross-fetch@npm:^3.1.5, cross-fetch@npm:^3.1.6": version: 3.1.8 resolution: "cross-fetch@npm:3.1.8" dependencies: @@ -6414,6 +9590,13 @@ __metadata: languageName: node linkType: hard +"crypto-js@npm:^4.0.0": + version: 4.2.0 + resolution: "crypto-js@npm:4.2.0" + checksum: f051666dbc077c8324777f44fbd3aaea2986f198fe85092535130d17026c7c2ccf2d23ee5b29b36f7a4a07312db2fae23c9094b644cc35f7858b1b4fcaf27774 + languageName: node + linkType: hard + "crypto-random-string@npm:^2.0.0": version: 2.0.0 resolution: "crypto-random-string@npm:2.0.0" @@ -6428,6 +9611,20 @@ __metadata: languageName: node linkType: hard +"csv-generate@npm:^4.4.0": + version: 4.4.0 + resolution: "csv-generate@npm:4.4.0" + checksum: 03312747cda31a9805cc528b7d14265e1ced6bb86857d0c32b741755fbf8d4d6ea72c47e9f2d5a08033b17f5854e975ef4580f9839a1544525a6fe85f41bd8ba + languageName: node + linkType: hard + +"csv-parse@npm:^5.5.5": + version: 5.5.5 + resolution: "csv-parse@npm:5.5.5" + checksum: 9e76b3dc3dbbf0a9b1c3529843e3891f0da23d094bdb0540a3d8f4083d00110dd545399f9cf510498def6c1fc7012cc6bc00046d281f16d705add64099467973 + languageName: node + linkType: hard + "csv-stringify@npm:^6.4.5": version: 6.4.5 resolution: "csv-stringify@npm:6.4.5" @@ -6435,6 +9632,25 @@ __metadata: languageName: node linkType: hard +"csv-stringify@npm:^6.4.6": + version: 6.4.6 + resolution: "csv-stringify@npm:6.4.6" + checksum: cacf20b3c2e0d68272e81e8b757fbc60a546e9e7b04916019af02326eadd42c163edb9f8f52bbc2dbe5d457282d560d6954fb2ef9848a96e2e5b3241a44be8a1 + languageName: node + linkType: hard + +"csv@npm:^6.0.5": + version: 6.3.8 + resolution: "csv@npm:6.3.8" + dependencies: + csv-generate: ^4.4.0 + csv-parse: ^5.5.5 + csv-stringify: ^6.4.6 + stream-transform: ^3.3.1 + checksum: 96981b97bea35796a22af029070ea18025e362ea568bb1e931d8edd03c77d9d7d5cbcdaabad57456d9b37ce11311653dd4ae77ef016dfdb57384608f43fb010b + languageName: node + linkType: hard + "d@npm:1, d@npm:^1.0.1": version: 1.0.1 resolution: "d@npm:1.0.1" @@ -6593,6 +9809,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + gopd: ^1.0.1 + checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b + languageName: node + linkType: hard + "define-lazy-prop@npm:^2.0.0": version: 2.0.0 resolution: "define-lazy-prop@npm:2.0.0" @@ -6611,6 +9838,20 @@ __metadata: languageName: node linkType: hard +"delay@npm:^4.4.0": + version: 4.4.1 + resolution: "delay@npm:4.4.1" + checksum: 97b001126a3979a398b6c5f33e437d78acda3b19731d9e6f991a05e2e09e7a410d655b8fdcaedc05743928bb533c0ac9401826cccb2af71c81d2cab50e199351 + languageName: node + linkType: hard + +"delay@npm:^5.0.0": + version: 5.0.0 + resolution: "delay@npm:5.0.0" + checksum: 62f151151ecfde0d9afbb8a6be37a6d103c4cb24f35a20ef3fe56f920b0d0d0bb02bc9c0a3084d0179ef669ca332b91155f2ee4d9854622cd2cdba5fc95285f9 + languageName: node + linkType: hard + "delayed-stream@npm:~1.0.0": version: 1.0.0 resolution: "delayed-stream@npm:1.0.0" @@ -6625,13 +9866,20 @@ __metadata: languageName: node linkType: hard -"depd@npm:2.0.0": +"depd@npm:2.0.0, depd@npm:^2.0.0": version: 2.0.0 resolution: "depd@npm:2.0.0" checksum: abbe19c768c97ee2eed6282d8ce3031126662252c58d711f646921c9623f9052e3e1906443066beec1095832f534e57c523b7333f8e7e0d93051ab6baef5ab3a languageName: node linkType: hard +"depd@npm:~1.1.2": + version: 1.1.2 + resolution: "depd@npm:1.1.2" + checksum: 6b406620d269619852885ce15965272b829df6f409724415e0002c8632ab6a8c0a08ec1f0bd2add05dc7bd7507606f7e2cc034fa24224ab829580040b835ecd9 + languageName: node + linkType: hard + "deprecation@npm:^2.0.0, deprecation@npm:^2.3.1": version: 2.3.1 resolution: "deprecation@npm:2.3.1" @@ -6646,6 +9894,15 @@ __metadata: languageName: node linkType: hard +"detect-libc@npm:^1.0.3": + version: 1.0.3 + resolution: "detect-libc@npm:1.0.3" + bin: + detect-libc: ./bin/detect-libc.js + checksum: daaaed925ffa7889bd91d56e9624e6c8033911bb60f3a50a74a87500680652969dbaab9526d1e200a4c94acf80fc862a22131841145a0a8482d60a99c24f4a3e + languageName: node + linkType: hard + "detect-newline@npm:^3.0.0": version: 3.1.0 resolution: "detect-newline@npm:3.1.0" @@ -6741,6 +9998,13 @@ __metadata: languageName: node linkType: hard +"dotenv@npm:~10.0.0": + version: 10.0.0 + resolution: "dotenv@npm:10.0.0" + checksum: f412c5fe8c24fbe313d302d2500e247ba8a1946492db405a4de4d30dd0eb186a88a43f13c958c5a7de303938949c4231c56994f97d05c4bc1f22478d631b4005 + languageName: node + linkType: hard + "dottie@npm:^2.0.2": version: 2.0.6 resolution: "dottie@npm:2.0.6" @@ -6755,6 +10019,15 @@ __metadata: languageName: node linkType: hard +"dprint-node@npm:^1.0.8": + version: 1.0.8 + resolution: "dprint-node@npm:1.0.8" + dependencies: + detect-libc: ^1.0.3 + checksum: ac53b71296d155664319877f0e8c9fe94e084457ce9aae68081b9dd7165916f2829222923c59b1399d95680362f18a8da5994e7f76a8f52035e02bbd14ba76bc + languageName: node + linkType: hard + "duplexer3@npm:^0.1.4": version: 0.1.5 resolution: "duplexer3@npm:0.1.5" @@ -6762,6 +10035,13 @@ __metadata: languageName: node linkType: hard +"duplexer@npm:^0.1.1": + version: 0.1.2 + resolution: "duplexer@npm:0.1.2" + checksum: 62ba61a830c56801db28ff6305c7d289b6dc9f859054e8c982abd8ee0b0a14d2e9a8e7d086ffee12e868d43e2bbe8a964be55ddbd8c8957714c87373c7a4f9b0 + languageName: node + linkType: hard + "eastasianwidth@npm:^0.2.0": version: 0.2.0 resolution: "eastasianwidth@npm:0.2.0" @@ -6817,7 +10097,7 @@ __metadata: languageName: node linkType: hard -"elliptic@npm:^6.5.4": +"elliptic@npm:6.5.4, elliptic@npm:^6.5.4": version: 6.5.4 resolution: "elliptic@npm:6.5.4" dependencies: @@ -6832,6 +10112,21 @@ __metadata: languageName: node linkType: hard +"elliptic@npm:^6.4.0, elliptic@npm:^6.5.3": + version: 6.5.5 + resolution: "elliptic@npm:6.5.5" + dependencies: + bn.js: ^4.11.9 + brorand: ^1.1.0 + hash.js: ^1.0.0 + hmac-drbg: ^1.0.1 + inherits: ^2.0.4 + minimalistic-assert: ^1.0.1 + minimalistic-crypto-utils: ^1.0.1 + checksum: ec9105e4469eb3b32b0ee2579756c888ddf3f99d259aa0d65fccb906ee877768aaf8880caae73e3e669c9a4adeb3eb1945703aa974ec5000d2d33a239f4567eb + languageName: node + linkType: hard + "emittery@npm:^0.13.1": version: 0.13.1 resolution: "emittery@npm:0.13.1" @@ -6869,7 +10164,7 @@ __metadata: languageName: node linkType: hard -"end-of-stream@npm:^1.1.0": +"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": version: 1.4.4 resolution: "end-of-stream@npm:1.4.4" dependencies: @@ -6888,6 +10183,15 @@ __metadata: languageName: node linkType: hard +"enquirer@npm:~2.3.6": + version: 2.3.6 + resolution: "enquirer@npm:2.3.6" + dependencies: + ansi-colors: ^4.1.1 + checksum: 1c0911e14a6f8d26721c91e01db06092a5f7675159f0261d69c403396a385afd13dd76825e7678f66daffa930cfaa8d45f506fb35f818a2788463d022af1b884 + languageName: node + linkType: hard + "env-paths@npm:^2.2.0": version: 2.2.1 resolution: "env-paths@npm:2.2.1" @@ -6918,6 +10222,17 @@ __metadata: languageName: node linkType: hard +"error-polyfill@npm:^0.1.3": + version: 0.1.3 + resolution: "error-polyfill@npm:0.1.3" + dependencies: + capability: ^0.2.5 + o3: ^1.0.3 + u3: ^0.1.1 + checksum: 1aee485841310e1f4d10cde0a5c8ac840311c94914bb1aed8fd71826be84dd5dba3d4ab937f39c0b970edb3d0a76cfb5d001ec979db6c68858b5f75c1f504c52 + languageName: node + linkType: hard + "es-abstract@npm:^1.22.1": version: 1.22.2 resolution: "es-abstract@npm:1.22.2" @@ -6965,6 +10280,22 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: ^1.2.4 + checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + "es-set-tostringtag@npm:^2.0.1": version: 2.0.1 resolution: "es-set-tostringtag@npm:2.0.1" @@ -7019,6 +10350,22 @@ __metadata: languageName: node linkType: hard +"es6-promise@npm:^4.0.3": + version: 4.2.8 + resolution: "es6-promise@npm:4.2.8" + checksum: 95614a88873611cb9165a85d36afa7268af5c03a378b35ca7bda9508e1d4f1f6f19a788d4bc755b3fd37c8ebba40782018e02034564ff24c9d6fa37e959ad57d + languageName: node + linkType: hard + +"es6-promisify@npm:^5.0.0": + version: 5.0.0 + resolution: "es6-promisify@npm:5.0.0" + dependencies: + es6-promise: ^4.0.3 + checksum: fbed9d791598831413be84a5374eca8c24800ec71a16c1c528c43a98e2dadfb99331483d83ae6094ddb9b87e6f799a15d1553cebf756047e0865c753bc346b92 + languageName: node + linkType: hard + "es6-symbol@npm:^3.1.1, es6-symbol@npm:^3.1.3": version: 3.1.3 resolution: "es6-symbol@npm:3.1.3" @@ -7350,6 +10697,44 @@ __metadata: languageName: node linkType: hard +"ethers@npm:^5.5.1": + version: 5.7.2 + resolution: "ethers@npm:5.7.2" + dependencies: + "@ethersproject/abi": 5.7.0 + "@ethersproject/abstract-provider": 5.7.0 + "@ethersproject/abstract-signer": 5.7.0 + "@ethersproject/address": 5.7.0 + "@ethersproject/base64": 5.7.0 + "@ethersproject/basex": 5.7.0 + "@ethersproject/bignumber": 5.7.0 + "@ethersproject/bytes": 5.7.0 + "@ethersproject/constants": 5.7.0 + "@ethersproject/contracts": 5.7.0 + "@ethersproject/hash": 5.7.0 + "@ethersproject/hdnode": 5.7.0 + "@ethersproject/json-wallets": 5.7.0 + "@ethersproject/keccak256": 5.7.0 + "@ethersproject/logger": 5.7.0 + "@ethersproject/networks": 5.7.1 + "@ethersproject/pbkdf2": 5.7.0 + "@ethersproject/properties": 5.7.0 + "@ethersproject/providers": 5.7.2 + "@ethersproject/random": 5.7.0 + "@ethersproject/rlp": 5.7.0 + "@ethersproject/sha2": 5.7.0 + "@ethersproject/signing-key": 5.7.0 + "@ethersproject/solidity": 5.7.0 + "@ethersproject/strings": 5.7.0 + "@ethersproject/transactions": 5.7.0 + "@ethersproject/units": 5.7.0 + "@ethersproject/wallet": 5.7.0 + "@ethersproject/web": 5.7.1 + "@ethersproject/wordlists": 5.7.0 + checksum: b7c08cf3e257185a7946117dbbf764433b7ba0e77c27298dec6088b3bc871aff711462b0621930c56880ff0a7ceb8b1d3a361ffa259f93377b48e34107f62553 + languageName: node + linkType: hard + "event-emitter@npm:^0.3.5": version: 0.3.5 resolution: "event-emitter@npm:0.3.5" @@ -7367,6 +10752,13 @@ __metadata: languageName: node linkType: hard +"eventemitter3@npm:^4.0.7": + version: 4.0.7 + resolution: "eventemitter3@npm:4.0.7" + checksum: 1875311c42fcfe9c707b2712c32664a245629b42bb0a5a84439762dd0fd637fc54d078155ea83c2af9e0323c9ac13687e03cfba79b03af9f40c89b4960099374 + languageName: node + linkType: hard + "execa@npm:^4.0.0": version: 4.1.0 resolution: "execa@npm:4.1.0" @@ -7421,7 +10813,7 @@ __metadata: languageName: node linkType: hard -"exponential-backoff@npm:^3.1.1": +"exponential-backoff@npm:^3.1.0, exponential-backoff@npm:^3.1.1": version: 3.1.1 resolution: "exponential-backoff@npm:3.1.1" checksum: 3d21519a4f8207c99f7457287291316306255a328770d320b401114ec8481986e4e467e854cb9914dd965e0a1ca810a23ccb559c642c88f4c7f55c55778a9b48 @@ -7505,6 +10897,13 @@ __metadata: languageName: node linkType: hard +"eyes@npm:^0.1.8": + version: 0.1.8 + resolution: "eyes@npm:0.1.8" + checksum: c31703a92bf36ba75ee8d379ee7985c24ee6149f3a6175f44cec7a05b178c38bce9836d3ca48c9acb0329a960ac2c4b2ead4e60cdd4fe6e8c92cad7cd6913687 + languageName: node + linkType: hard + "fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" @@ -7526,6 +10925,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:3.2.7": + version: 3.2.7 + resolution: "fast-glob@npm:3.2.7" + dependencies: + "@nodelib/fs.stat": ^2.0.2 + "@nodelib/fs.walk": ^1.2.3 + glob-parent: ^5.1.2 + merge2: ^1.3.0 + micromatch: ^4.0.4 + checksum: 2f4708ff112d2b451888129fdd9a0938db88b105b0ddfd043c064e3c4d3e20eed8d7c7615f7565fee660db34ddcf08a2db1bf0ab3c00b87608e4719694642d78 + languageName: node + linkType: hard + "fast-glob@npm:^3.2.9": version: 3.3.1 resolution: "fast-glob@npm:3.3.1" @@ -7567,6 +10979,24 @@ __metadata: languageName: node linkType: hard +"fast-stable-stringify@npm:^1.0.0": + version: 1.0.0 + resolution: "fast-stable-stringify@npm:1.0.0" + checksum: ef1203d246a7e8ac15e2bfbda0a89fa375947bccf9f7910be0ea759856dbe8ea5024a0d8cc2cceabe18a9cb67e95927b78bb6173a3ae37ec55a518cf36e5244b + languageName: node + linkType: hard + +"fast-xml-parser@npm:4.2.5": + version: 4.2.5 + resolution: "fast-xml-parser@npm:4.2.5" + dependencies: + strnum: ^1.0.5 + bin: + fxparser: src/cli/cli.js + checksum: d32b22005504eeb207249bf40dc82d0994b5bb9ca9dcc731d335a1f425e47fe085b3cace3cf9d32172dd1a5544193c49e8615ca95b4bf95a4a4920a226b06d80 + languageName: node + linkType: hard + "fastq@npm:^1.6.0": version: 1.15.0 resolution: "fastq@npm:1.15.0" @@ -7585,6 +11015,15 @@ __metadata: languageName: node linkType: hard +"figures@npm:3.2.0, figures@npm:^3.0.0": + version: 3.2.0 + resolution: "figures@npm:3.2.0" + dependencies: + escape-string-regexp: ^1.0.5 + checksum: 85a6ad29e9aca80b49b817e7c89ecc4716ff14e3779d9835af554db91bac41c0f289c418923519392a1e582b4d10482ad282021330cd045bb7b80c84152f2a2b + languageName: node + linkType: hard + "figures@npm:^2.0.0": version: 2.0.0 resolution: "figures@npm:2.0.0" @@ -7603,6 +11042,13 @@ __metadata: languageName: node linkType: hard +"file-uri-to-path@npm:1.0.0": + version: 1.0.0 + resolution: "file-uri-to-path@npm:1.0.0" + checksum: b648580bdd893a008c92c7ecc96c3ee57a5e7b6c4c18a9a09b44fb5d36d79146f8e442578bc0e173dc027adf3987e254ba1dfd6e3ec998b7c282873010502144 + languageName: node + linkType: hard + "filelist@npm:^1.0.4": version: 1.0.4 resolution: "filelist@npm:1.0.4" @@ -7692,6 +11138,15 @@ __metadata: languageName: node linkType: hard +"flat@npm:^5.0.2": + version: 5.0.2 + resolution: "flat@npm:5.0.2" + bin: + flat: cli.js + checksum: 12a1536ac746db74881316a181499a78ef953632ddd28050b7a3a43c62ef5462e3357c8c29d76072bb635f147f7a9a1f0c02efef6b4be28f8db62ceb3d5c7f5d + languageName: node + linkType: hard + "flatstr@npm:^1.0.12": version: 1.0.12 resolution: "flatstr@npm:1.0.12" @@ -7706,7 +11161,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.15.0, follow-redirects@npm:^1.15.6": +"follow-redirects@npm:^1.14.0, follow-redirects@npm:^1.14.4, follow-redirects@npm:^1.14.7, follow-redirects@npm:^1.14.9, follow-redirects@npm:^1.15.0, follow-redirects@npm:^1.15.6": version: 1.15.6 resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: @@ -7771,7 +11226,14 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^10.1.0": +"fs-constants@npm:^1.0.0": + version: 1.0.0 + resolution: "fs-constants@npm:1.0.0" + checksum: 18f5b718371816155849475ac36c7d0b24d39a11d91348cfcb308b4494824413e03572c403c86d3a260e049465518c4f0d5bd00f0371cdfcad6d4f30a85b350d + languageName: node + linkType: hard + +"fs-extra@npm:^10.0.1, fs-extra@npm:^10.1.0": version: 10.1.0 resolution: "fs-extra@npm:10.1.0" dependencies: @@ -7943,6 +11405,19 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" + dependencies: + es-errors: ^1.3.0 + function-bind: ^1.1.2 + has-proto: ^1.0.1 + has-symbols: ^1.0.3 + hasown: ^2.0.0 + checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951 + languageName: node + linkType: hard + "get-iterator@npm:^1.0.2": version: 1.0.2 resolution: "get-iterator@npm:1.0.2" @@ -8056,6 +11531,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:7.1.4": + version: 7.1.4 + resolution: "glob@npm:7.1.4" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^3.0.4 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: f52480fc82b1e66e52990f0f2e7306447d12294c83fbbee0395e761ad1178172012a7cc0673dbf4810baac400fc09bf34484c08b5778c216403fd823db281716 + languageName: node + linkType: hard + "glob@npm:8.0.3": version: 8.0.3 resolution: "glob@npm:8.0.3" @@ -8254,6 +11743,15 @@ __metadata: languageName: node linkType: hard +"has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: ^1.0.0 + checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3 + languageName: node + linkType: hard + "has-proto@npm:^1.0.1": version: 1.0.1 resolution: "has-proto@npm:1.0.1" @@ -8300,7 +11798,18 @@ __metadata: languageName: node linkType: hard -"hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": +"hash-base@npm:^3.0.0": + version: 3.1.0 + resolution: "hash-base@npm:3.1.0" + dependencies: + inherits: ^2.0.4 + readable-stream: ^3.6.0 + safe-buffer: ^5.2.0 + checksum: 26b7e97ac3de13cb23fc3145e7e3450b0530274a9562144fc2bf5c1e2983afd0e09ed7cc3b20974ba66039fad316db463da80eb452e7373e780cbee9a0d2f2dc + languageName: node + linkType: hard + +"hash.js@npm:1.1.7, hash.js@npm:^1.0.0, hash.js@npm:^1.0.3": version: 1.1.7 resolution: "hash.js@npm:1.1.7" dependencies: @@ -8319,6 +11828,13 @@ __metadata: languageName: node linkType: hard +"hi-base32@npm:^0.5.1": + version: 0.5.1 + resolution: "hi-base32@npm:0.5.1" + checksum: 6655682b5796d75ed3068071e61d05a490e2086c4908af3b94a730059147b8a4a5e8870e656b828d0550dcc9988d8748bda54a53e428cbce28e0d7a785b2ffde + languageName: node + linkType: hard + "hmac-drbg@npm:^1.0.1": version: 1.0.1 resolution: "hmac-drbg@npm:1.0.1" @@ -8366,6 +11882,19 @@ __metadata: languageName: node linkType: hard +"http-errors@npm:^1.7.2": + version: 1.8.1 + resolution: "http-errors@npm:1.8.1" + dependencies: + depd: ~1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: ">= 1.5.0 < 2" + toidentifier: 1.0.1 + checksum: d3c7e7e776fd51c0a812baff570bdf06fe49a5dc448b700ab6171b1250e4cf7db8b8f4c0b133e4bfe2451022a5790c1ca6c2cae4094dedd6ac8304a1267f91d2 + languageName: node + linkType: hard + "http-proxy-agent@npm:^5.0.0": version: 5.0.0 resolution: "http-proxy-agent@npm:5.0.0" @@ -8410,6 +11939,13 @@ __metadata: languageName: node linkType: hard +"humanize-number@npm:0.0.2": + version: 0.0.2 + resolution: "humanize-number@npm:0.0.2" + checksum: 9c98c9d06b0f3d801960be3957199232a5df52377e2502acae92e4f71de633fa62c315a83f24bf96bef76f47b2e3e0e1e4f4157c891e27074fd3272cad6724bb + languageName: node + linkType: hard + "husky@npm:^7.0.4": version: 7.0.4 resolution: "husky@npm:7.0.4" @@ -8451,6 +11987,13 @@ __metadata: languageName: node linkType: hard +"ignore@npm:^5.0.4": + version: 5.3.1 + resolution: "ignore@npm:5.3.1" + checksum: 71d7bb4c1dbe020f915fd881108cbe85a0db3d636a0ea3ba911393c53946711d13a9b1143c7e70db06d571a5822c0a324a6bcde5c9904e7ca5047f01f1bf8cd3 + languageName: node + linkType: hard + "ignore@npm:^5.1.4, ignore@npm:^5.2.0": version: 5.2.4 resolution: "ignore@npm:5.2.4" @@ -8518,7 +12061,7 @@ __metadata: languageName: node linkType: hard -"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": +"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3": version: 2.0.4 resolution: "inherits@npm:2.0.4" checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1 @@ -8604,6 +12147,29 @@ __metadata: languageName: node linkType: hard +"inquirer@npm:^8.2.0": + version: 8.2.6 + resolution: "inquirer@npm:8.2.6" + dependencies: + ansi-escapes: ^4.2.1 + chalk: ^4.1.1 + cli-cursor: ^3.1.0 + cli-width: ^3.0.0 + external-editor: ^3.0.3 + figures: ^3.0.0 + lodash: ^4.17.21 + mute-stream: 0.0.8 + ora: ^5.4.1 + run-async: ^2.4.0 + rxjs: ^7.5.5 + string-width: ^4.1.0 + strip-ansi: ^6.0.0 + through: ^2.3.6 + wrap-ansi: ^6.0.1 + checksum: 387ffb0a513559cc7414eb42c57556a60e302f820d6960e89d376d092e257a919961cd485a1b4de693dbb5c0de8bc58320bfd6247dfd827a873aa82a4215a240 + languageName: node + linkType: hard + "inquirerer@npm:0.1.3": version: 0.1.3 resolution: "inquirerer@npm:0.1.3" @@ -8836,7 +12402,7 @@ __metadata: languageName: node linkType: hard -"is-buffer@npm:^2.0.0": +"is-buffer@npm:^2.0.0, is-buffer@npm:^2.0.5": version: 2.0.5 resolution: "is-buffer@npm:2.0.5" checksum: 764c9ad8b523a9f5a32af29bdf772b08eb48c04d2ad0a7240916ac2688c983bf5f8504bf25b35e66240edeb9d9085461f9b5dae1f3d2861c6b06a65fe983de42 @@ -9347,6 +12913,28 @@ __metadata: languageName: node linkType: hard +"jayson@npm:^4.1.0": + version: 4.1.0 + resolution: "jayson@npm:4.1.0" + dependencies: + "@types/connect": ^3.4.33 + "@types/node": ^12.12.54 + "@types/ws": ^7.4.4 + JSONStream: ^1.3.5 + commander: ^2.20.3 + delay: ^5.0.0 + es6-promisify: ^5.0.0 + eyes: ^0.1.8 + isomorphic-ws: ^4.0.1 + json-stringify-safe: ^5.0.1 + uuid: ^8.3.2 + ws: ^7.4.5 + bin: + jayson: bin/jayson.js + checksum: 86464322fbdc6db65d2bb4fc278cb6c86fad5c2a506065490d39459f09ba0d30f2b4fb740b33828a1424791419b6c8bd295dc54d361a4ad959bf70cc62b1ca7e + languageName: node + linkType: hard + "jest-changed-files@npm:^29.7.0": version: 29.7.0 resolution: "jest-changed-files@npm:29.7.0" @@ -9872,13 +13460,27 @@ __metadata: languageName: node linkType: hard -"js-sha3@npm:^0.8.0": +"js-sha256@npm:^0.9.0": + version: 0.9.0 + resolution: "js-sha256@npm:0.9.0" + checksum: ffad54b3373f81581e245866abfda50a62c483803a28176dd5c28fd2d313e0bdf830e77dac7ff8afd193c53031618920f3d98daf21cbbe80082753ab639c0365 + languageName: node + linkType: hard + +"js-sha3@npm:0.8.0, js-sha3@npm:^0.8.0": version: 0.8.0 resolution: "js-sha3@npm:0.8.0" checksum: 75df77c1fc266973f06cce8309ce010e9e9f07ec35ab12022ed29b7f0d9c8757f5a73e1b35aa24840dced0dea7059085aa143d817aea9e188e2a80d569d9adce languageName: node linkType: hard +"js-sha512@npm:^0.8.0": + version: 0.8.0 + resolution: "js-sha512@npm:0.8.0" + checksum: 32ca371ebd14c6c5c83360fd8b036cad2211537bef546b199ac8b901917299cab4c68f7f7c26ae72f836bbce0349cb463df9a62cdb4c90e38090fdb4db89ee87 + languageName: node + linkType: hard + "js-tokens@npm:^3.0.0 || ^4.0.0, js-tokens@npm:^4.0.0": version: 4.0.0 resolution: "js-tokens@npm:4.0.0" @@ -9886,26 +13488,26 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^3.13.1": - version: 3.14.1 - resolution: "js-yaml@npm:3.14.1" +"js-yaml@npm:4.1.0, js-yaml@npm:^4.1.0": + version: 4.1.0 + resolution: "js-yaml@npm:4.1.0" dependencies: - argparse: ^1.0.7 - esprima: ^4.0.0 + argparse: ^2.0.1 bin: js-yaml: bin/js-yaml.js - checksum: bef146085f472d44dee30ec34e5cf36bf89164f5d585435a3d3da89e52622dff0b188a580e4ad091c3341889e14cb88cac6e4deb16dc5b1e9623bb0601fc255c + checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a languageName: node linkType: hard -"js-yaml@npm:^4.1.0": - version: 4.1.0 - resolution: "js-yaml@npm:4.1.0" +"js-yaml@npm:^3.10.0, js-yaml@npm:^3.13.1": + version: 3.14.1 + resolution: "js-yaml@npm:3.14.1" dependencies: - argparse: ^2.0.1 + argparse: ^1.0.7 + esprima: ^4.0.0 bin: js-yaml: bin/js-yaml.js - checksum: c7830dfd456c3ef2c6e355cc5a92e6700ceafa1d14bba54497b34a99f0376cecbb3e9ac14d3e5849b426d5a5140709a66237a8c991c675431271c4ce5504151a + checksum: bef146085f472d44dee30ec34e5cf36bf89164f5d585435a3d3da89e52622dff0b188a580e4ad091c3341889e14cb88cac6e4deb16dc5b1e9623bb0601fc255c languageName: node linkType: hard @@ -9927,6 +13529,15 @@ __metadata: languageName: node linkType: hard +"json-bigint@npm:^1.0.0": + version: 1.0.0 + resolution: "json-bigint@npm:1.0.0" + dependencies: + bignumber.js: ^9.0.0 + checksum: c67bb93ccb3c291e60eb4b62931403e378906aab113ec1c2a8dd0f9a7f065ad6fd9713d627b732abefae2e244ac9ce1721c7a3142b2979532f12b258634ce6f6 + languageName: node + linkType: hard + "json-buffer@npm:3.0.0": version: 3.0.0 resolution: "json-buffer@npm:3.0.0" @@ -9988,6 +13599,13 @@ __metadata: languageName: node linkType: hard +"json-stringify-safe@npm:^5.0.1": + version: 5.0.1 + resolution: "json-stringify-safe@npm:5.0.1" + checksum: 48ec0adad5280b8a96bb93f4563aa1667fd7a36334f79149abd42446d0989f2ddc58274b479f4819f1f00617957e6344c886c55d05a4e15ebb4ab931e4a6a8ee + languageName: node + linkType: hard + "json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" @@ -10015,7 +13633,7 @@ __metadata: languageName: node linkType: hard -"jsonfile@npm:^6.0.1": +"jsonfile@npm:^6.0.1, jsonfile@npm:^6.1.0": version: 6.1.0 resolution: "jsonfile@npm:6.1.0" dependencies: @@ -10035,6 +13653,25 @@ __metadata: languageName: node linkType: hard +"jsonparse@npm:^1.2.0": + version: 1.3.1 + resolution: "jsonparse@npm:1.3.1" + checksum: 6514a7be4674ebf407afca0eda3ba284b69b07f9958a8d3113ef1005f7ec610860c312be067e450c569aab8b89635e332cee3696789c750692bb60daba627f4d + languageName: node + linkType: hard + +"keccak@npm:^3.0.2": + version: 3.0.4 + resolution: "keccak@npm:3.0.4" + dependencies: + node-addon-api: ^2.0.0 + node-gyp: latest + node-gyp-build: ^4.2.0 + readable-stream: ^3.6.0 + checksum: 2bf27b97b2f24225b1b44027de62be547f5c7326d87d249605665abd0c8c599d774671c35504c62c9b922cae02758504c6f76a73a84234d23af8a2211afaaa11 + languageName: node + linkType: hard + "keyv@npm:^3.0.0": version: 3.1.0 resolution: "keyv@npm:3.1.0" @@ -10078,6 +13715,34 @@ __metadata: languageName: node linkType: hard +"level-supports@npm:^4.0.0": + version: 4.0.1 + resolution: "level-supports@npm:4.0.1" + checksum: d4552b42bb8cdeada07b0f6356c7a90fefe76279147331f291aceae26e3e56d5f927b09ce921647c0230bfe03ddfbdcef332be921e5c2194421ae2bfa3cf6368 + languageName: node + linkType: hard + +"level-transcoder@npm:^1.0.1": + version: 1.0.1 + resolution: "level-transcoder@npm:1.0.1" + dependencies: + buffer: ^6.0.3 + module-error: ^1.0.1 + checksum: 304f08d802faf3491a533b6d87ad8be3cabfd27f2713bbe9d4c633bf50fcb9460eab5a6776bf015e101ead7ba1c1853e05e7f341112f17a9d0cb37ee5a421a25 + languageName: node + linkType: hard + +"level@npm:^8.0.0": + version: 8.0.1 + resolution: "level@npm:8.0.1" + dependencies: + abstract-level: ^1.0.4 + browser-level: ^1.0.1 + classic-level: ^1.2.0 + checksum: c5641cbba666ef9eb0292aad01d86a4f1af18e637d1fc097c65bf0109ab8d7e6fba8c8faf6c74ae4e48edac4310f7dd87def26ffeebfe395c7afd9bd2461ab97 + languageName: node + linkType: hard + "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -10118,6 +13783,22 @@ __metadata: languageName: node linkType: hard +"libsodium-wrappers@npm:^0.7.6": + version: 0.7.13 + resolution: "libsodium-wrappers@npm:0.7.13" + dependencies: + libsodium: ^0.7.13 + checksum: d184395f7c33023414b191ef9ea2171eb1a5cb061503e886ea877590cb7adc3a4feaf794b9b08731a20515518fa23dbf1c1bfcd376e5ab01728e95cf1cb7525a + languageName: node + linkType: hard + +"libsodium@npm:^0.7.13": + version: 0.7.13 + resolution: "libsodium@npm:0.7.13" + checksum: 75a5f70e84c197d54d9b67dcbd852abbd41cca8facd510767c7c8400a52a23da293e83eebf1693831b2c0c0498f266bd9350a8c27ec66f46a055890dff758d38 + languageName: node + linkType: hard + "lilconfig@npm:2.0.5": version: 2.0.5 resolution: "lilconfig@npm:2.0.5" @@ -10274,7 +13955,7 @@ __metadata: languageName: node linkType: hard -"long@npm:^5.2.0, long@npm:^5.2.1": +"long@npm:^5.0.0, long@npm:^5.2.0, long@npm:^5.2.1, long@npm:^5.2.3": version: 5.2.3 resolution: "long@npm:5.2.3" checksum: 885ede7c3de4facccbd2cacc6168bae3a02c3e836159ea4252c87b6e34d40af819824b2d4edce330bfb5c4d6e8ce3ec5864bdcf9473fa1f53a4f8225860e5897 @@ -10434,6 +14115,17 @@ __metadata: languageName: node linkType: hard +"md5.js@npm:^1.3.4": + version: 1.3.5 + resolution: "md5.js@npm:1.3.5" + dependencies: + hash-base: ^3.0.0 + inherits: ^2.0.1 + safe-buffer: ^5.1.2 + checksum: 098494d885684bcc4f92294b18ba61b7bd353c23147fbc4688c75b45cb8590f5a95fd4584d742415dcc52487f7a1ef6ea611cfa1543b0dc4492fe026357f3f0c + languageName: node + linkType: hard + "mdast-util-from-markdown@npm:^0.8.0": version: 0.8.5 resolution: "mdast-util-from-markdown@npm:0.8.5" @@ -10564,7 +14256,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:^2.1.12, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.12, mime-types@npm:^2.1.34, mime-types@npm:~2.1.24, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -10617,6 +14309,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:3.0.5": + version: 3.0.5 + resolution: "minimatch@npm:3.0.5" + dependencies: + brace-expansion: ^1.1.7 + checksum: a3b84b426eafca947741b864502cee02860c4e7b145de11ad98775cfcf3066fef422583bc0ffce0952ddf4750c1ccf4220b1556430d4ce10139f66247d87d69e + languageName: node + linkType: hard + "minimatch@npm:5.1.0": version: 5.1.0 resolution: "minimatch@npm:5.1.0" @@ -10787,6 +14488,20 @@ __metadata: languageName: node linkType: hard +"mobx@npm:^6.1.7": + version: 6.12.3 + resolution: "mobx@npm:6.12.3" + checksum: 95d5a81ca80c943b0e7fe0a44cbaeb5447d1bd6be72380a3c9b22ce27dbedcf36c7597f5600d742ed3c74699e809f1d2055c26482df04c3ec4b3ac2e181414bb + languageName: node + linkType: hard + +"module-error@npm:^1.0.1, module-error@npm:^1.0.2": + version: 1.0.2 + resolution: "module-error@npm:1.0.2" + checksum: 5d653e35bd55b3e95f8aee2cdac108082ea892e71b8f651be92cde43e4ee86abee4fa8bd7fc3fe5e68b63926d42f63c54cd17b87a560c31f18739295575a3962 + languageName: node + linkType: hard + "moment-timezone@npm:^0.5.35, moment-timezone@npm:~0.5": version: 0.5.43 resolution: "moment-timezone@npm:0.5.43" @@ -10889,6 +14604,25 @@ __metadata: languageName: node linkType: hard +"multistream@npm:^4.1.0": + version: 4.1.0 + resolution: "multistream@npm:4.1.0" + dependencies: + once: ^1.4.0 + readable-stream: ^3.6.0 + checksum: 305c49a1aadcb7f63f64d8ca2bb6e7852e5f7dba94c7329e9a72ce53cd0046686b71668dc1adbf123f17d2dd107765fc946e64c36a26b15c470a3146ea3bc923 + languageName: node + linkType: hard + +"mustache@npm:^4.0.0": + version: 4.2.0 + resolution: "mustache@npm:4.2.0" + bin: + mustache: bin/mustache + checksum: 928fcb63e3aa44a562bfe9b59ba202cccbe40a46da50be6f0dd831b495be1dd7e38ca4657f0ecab2c1a89dc7bccba0885eab7ee7c1b215830da765758c7e0506 + languageName: node + linkType: hard + "mute-stream@npm:0.0.7": version: 0.0.7 resolution: "mute-stream@npm:0.0.7" @@ -10896,6 +14630,13 @@ __metadata: languageName: node linkType: hard +"mute-stream@npm:0.0.8": + version: 0.0.8 + resolution: "mute-stream@npm:0.0.8" + checksum: ff48d251fc3f827e5b1206cda0ffdaec885e56057ee86a3155e1951bc940fd5f33531774b1cc8414d7668c10a8907f863f6561875ee6e8768931a62121a531a1 + languageName: node + linkType: hard + "mz@npm:^2.7.0": version: 2.7.0 resolution: "mz@npm:2.7.0" @@ -10907,6 +14648,15 @@ __metadata: languageName: node linkType: hard +"nan@npm:^2.13.2": + version: 2.19.0 + resolution: "nan@npm:2.19.0" + dependencies: + node-gyp: latest + checksum: 29a894a003c1954c250d690768c30e69cd91017e2e5eb21b294380f7cace425559508f5ffe3e329a751307140b0bd02f83af040740fa4def1a3869be6af39600 + languageName: node + linkType: hard + "nanoid@npm:^3.0.2, nanoid@npm:^3.1.20, nanoid@npm:^3.1.23": version: 3.3.6 resolution: "nanoid@npm:3.3.6" @@ -10916,6 +14666,13 @@ __metadata: languageName: node linkType: hard +"napi-macros@npm:^2.2.2": + version: 2.2.2 + resolution: "napi-macros@npm:2.2.2" + checksum: c6f9bd71cdbbc37ddc3535aa5be481238641d89585b8a3f4d301cb89abf459e2d294810432bb7d12056d1f9350b1a0899a5afcf460237a3da6c398cf0fec7629 + languageName: node + linkType: hard + "native-fetch@npm:^3.0.0": version: 3.0.0 resolution: "native-fetch@npm:3.0.0" @@ -10939,6 +14696,48 @@ __metadata: languageName: node linkType: hard +"near-api-js@npm:^0.44.2": + version: 0.44.2 + resolution: "near-api-js@npm:0.44.2" + dependencies: + bn.js: 5.2.0 + borsh: ^0.6.0 + bs58: ^4.0.0 + depd: ^2.0.0 + error-polyfill: ^0.1.3 + http-errors: ^1.7.2 + js-sha256: ^0.9.0 + mustache: ^4.0.0 + node-fetch: ^2.6.1 + text-encoding-utf-8: ^1.0.2 + tweetnacl: ^1.0.1 + checksum: d63625ab83d695d23a9126997355909fe141204c431a4818733050e1fcda11e5508dc70ff2e8fd55c1b2842908babd42fcf0ed4f3dc8c3fdb23ae422c497996d + languageName: node + linkType: hard + +"near-hd-key@npm:^1.2.1": + version: 1.2.1 + resolution: "near-hd-key@npm:1.2.1" + dependencies: + bip39: 3.0.2 + create-hmac: 1.1.7 + tweetnacl: 1.0.3 + checksum: 7dc652952257407dfee5207df51173a37b09cde0d99966070e0de27aa7f8113f899e56338cfdae98e939a7541bfc25d79d1587df6154ee69d122b5ad919d0ff6 + languageName: node + linkType: hard + +"near-seed-phrase@npm:^0.2.0": + version: 0.2.0 + resolution: "near-seed-phrase@npm:0.2.0" + dependencies: + bip39-light: ^1.0.7 + bs58: ^4.0.1 + near-hd-key: ^1.2.1 + tweetnacl: ^1.0.2 + checksum: 66c5a946bae107746256c590429123d9b02daf22ab1f32d12cab79414bf34d6d2de7b17896d14459fd515b42c56cd510adafedf9f69075534c6105812b4438f8 + languageName: node + linkType: hard + "negotiator@npm:0.6.3, negotiator@npm:^0.6.3": version: 0.6.3 resolution: "negotiator@npm:0.6.3" @@ -10962,6 +14761,24 @@ __metadata: languageName: node linkType: hard +"node-addon-api@npm:^2.0.0": + version: 2.0.2 + resolution: "node-addon-api@npm:2.0.2" + dependencies: + node-gyp: latest + checksum: 31fb22d674648204f8dd94167eb5aac896c841b84a9210d614bf5d97c74ef059cc6326389cf0c54d2086e35312938401d4cc82e5fcd679202503eb8ac84814f8 + languageName: node + linkType: hard + +"node-addon-api@npm:^3.2.1": + version: 3.2.1 + resolution: "node-addon-api@npm:3.2.1" + dependencies: + node-gyp: latest + checksum: 2369986bb0881ccd9ef6bacdf39550e07e089a9c8ede1cbc5fc7712d8e2faa4d50da0e487e333d4125f8c7a616c730131d1091676c9d499af1d74560756b4a18 + languageName: node + linkType: hard + "node-fetch@npm:2.6.7": version: 2.6.7 resolution: "node-fetch@npm:2.6.7" @@ -10976,6 +14793,17 @@ __metadata: languageName: node linkType: hard +"node-gyp-build@npm:^4.2.0, node-gyp-build@npm:^4.3.0": + version: 4.8.0 + resolution: "node-gyp-build@npm:4.8.0" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: b82a56f866034b559dd3ed1ad04f55b04ae381b22ec2affe74b488d1582473ca6e7f85fccf52da085812d3de2b0bf23109e752a57709ac7b9963951c710fea40 + languageName: node + linkType: hard + "node-gyp@npm:latest": version: 9.4.0 resolution: "node-gyp@npm:9.4.0" @@ -11111,6 +14939,68 @@ __metadata: languageName: node linkType: hard +"nx@npm:14.8.9, nx@npm:^14.4.3": + version: 14.8.9 + resolution: "nx@npm:14.8.9" + dependencies: + "@nrwl/cli": 14.8.9 + "@nrwl/tao": 14.8.9 + "@parcel/watcher": 2.0.4 + "@yarnpkg/lockfile": ^1.1.0 + "@yarnpkg/parsers": ^3.0.0-rc.18 + "@zkochan/js-yaml": 0.0.6 + axios: ^1.0.0 + chalk: 4.1.0 + chokidar: ^3.5.1 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + cliui: ^7.0.2 + dotenv: ~10.0.0 + enquirer: ~2.3.6 + fast-glob: 3.2.7 + figures: 3.2.0 + flat: ^5.0.2 + fs-extra: ^10.1.0 + glob: 7.1.4 + ignore: ^5.0.4 + js-yaml: 4.1.0 + jsonc-parser: 3.2.0 + minimatch: 3.0.5 + npm-run-path: ^4.0.1 + open: ^8.4.0 + semver: 7.3.4 + string-width: ^4.2.3 + strong-log-transformer: ^2.1.0 + tar-stream: ~2.2.0 + tmp: ~0.2.1 + tsconfig-paths: ^3.9.0 + tslib: ^2.3.0 + v8-compile-cache: 2.3.0 + yargs: ^17.4.0 + yargs-parser: 21.0.1 + peerDependencies: + "@swc-node/register": ^1.4.2 + "@swc/core": ^1.2.173 + peerDependenciesMeta: + "@swc-node/register": + optional: true + "@swc/core": + optional: true + bin: + nx: bin/nx.js + checksum: 4c661e8739c6e7d11b213c6aedc19185039b780e0257cd0068d710b688ff14e77e7747b3eb7165574b5101d63a810644fa83802db0565d9d89320ca961700faa + languageName: node + linkType: hard + +"o3@npm:^1.0.3": + version: 1.0.3 + resolution: "o3@npm:1.0.3" + dependencies: + capability: ^0.2.5 + checksum: 3b4d0686c94ac21b3c8bd66fb2c93a4daef7b8f52a20b04595754f8dc4102550de9a7b1cdffa3db2191d47a4ae70ca568f21d9f3ba29bb15c3f004dbf636c33c + languageName: node + linkType: hard + "object-assign@npm:^4, object-assign@npm:^4.0.1, object-assign@npm:^4.1.0, object-assign@npm:^4.1.1": version: 4.1.1 resolution: "object-assign@npm:4.1.1" @@ -11125,6 +15015,13 @@ __metadata: languageName: node linkType: hard +"object-inspect@npm:^1.13.1": + version: 1.13.1 + resolution: "object-inspect@npm:1.13.1" + checksum: 7d9fa9221de3311dcb5c7c307ee5dc011cdd31dc43624b7c184b3840514e118e05ef0002be5388304c416c0eb592feb46e983db12577fc47e47d5752fbbfb61f + languageName: node + linkType: hard + "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -11224,7 +15121,7 @@ __metadata: languageName: node linkType: hard -"open@npm:^8.2.0": +"open@npm:^8.2.0, open@npm:^8.4.0": version: 8.4.2 resolution: "open@npm:8.4.2" dependencies: @@ -11271,7 +15168,7 @@ __metadata: languageName: node linkType: hard -"ora@npm:5.4.1": +"ora@npm:5.4.1, ora@npm:^5.4.1": version: 5.4.1 resolution: "ora@npm:5.4.1" dependencies: @@ -11610,6 +15507,19 @@ __metadata: languageName: node linkType: hard +"pbkdf2@npm:^3.0.9": + version: 3.1.2 + resolution: "pbkdf2@npm:3.1.2" + dependencies: + create-hash: ^1.1.2 + create-hmac: ^1.1.4 + ripemd160: ^2.0.1 + safe-buffer: ^5.0.1 + sha.js: ^2.4.8 + checksum: 2c950a100b1da72123449208e231afc188d980177d021d7121e96a2de7f2abbc96ead2b87d03d8fe5c318face097f203270d7e27908af9f471c165a4e8e69c92 + languageName: node + linkType: hard + "pg-cloudflare@npm:^1.1.1": version: 1.1.1 resolution: "pg-cloudflare@npm:1.1.1" @@ -11810,6 +15720,13 @@ __metadata: languageName: node linkType: hard +"prando@npm:^6.0.1": + version: 6.0.1 + resolution: "prando@npm:6.0.1" + checksum: c0c25dbb2cb92dff4b0f44781f0e2132886c34ab6a12f7f0839d6073c783d86589d4c632727819d8fb0a5a675a7e27223285c6907261d3b6a49167b4cbdc162a + languageName: node + linkType: hard + "prelude-ls@npm:^1.2.1": version: 1.2.1 resolution: "prelude-ls@npm:1.2.1" @@ -11896,7 +15813,14 @@ __metadata: languageName: node linkType: hard -"prom-client@npm:^14.0.1": +"process@npm:^0.11.10": + version: 0.11.10 + resolution: "process@npm:0.11.10" + checksum: bfcce49814f7d172a6e6a14d5fa3ac92cc3d0c3b9feb1279774708a719e19acd673995226351a082a9ae99978254e320ccda4240ddc474ba31a76c79491ca7c3 + languageName: node + linkType: hard + +"prom-client@npm:^14.0.1, prom-client@npm:^14.1.0": version: 14.2.0 resolution: "prom-client@npm:14.2.0" dependencies: @@ -11936,7 +15860,7 @@ __metadata: languageName: node linkType: hard -"protobufjs@npm:^6.10.2, protobufjs@npm:^6.11.4, protobufjs@npm:^6.8.8": +"protobufjs@npm:^6.10.2, protobufjs@npm:^6.11.2, protobufjs@npm:^6.11.4, protobufjs@npm:^6.8.8, protobufjs@npm:~6.11.2, protobufjs@npm:~6.11.3": version: 6.11.4 resolution: "protobufjs@npm:6.11.4" dependencies: @@ -11960,6 +15884,50 @@ __metadata: languageName: node linkType: hard +"protobufjs@npm:^7.2.4": + version: 7.2.6 + resolution: "protobufjs@npm:7.2.6" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/node": ">=13.7.0" + long: ^5.0.0 + checksum: 3c62e48f7d50017ac3b0dcd2a58e617cf858f9fba56a488bd48b9aa3482893a75540052dbcb3c12dfbaab42b1d04964611175faf06bdadcd33a4ebac982a511e + languageName: node + linkType: hard + +"protobufjs@npm:~6.10.2": + version: 6.10.3 + resolution: "protobufjs@npm:6.10.3" + dependencies: + "@protobufjs/aspromise": ^1.1.2 + "@protobufjs/base64": ^1.1.2 + "@protobufjs/codegen": ^2.0.4 + "@protobufjs/eventemitter": ^1.1.0 + "@protobufjs/fetch": ^1.1.0 + "@protobufjs/float": ^1.0.2 + "@protobufjs/inquire": ^1.1.0 + "@protobufjs/path": ^1.1.2 + "@protobufjs/pool": ^1.1.0 + "@protobufjs/utf8": ^1.1.0 + "@types/long": ^4.0.1 + "@types/node": ^13.7.0 + long: ^4.0.0 + bin: + pbjs: bin/pbjs + pbts: bin/pbts + checksum: 6fb9fa971b0676ea1d560748572f39bcc1cac973d9c9c5041afe1e3268f5767951465d17946757314521504f75b78d192424efbdb07daff45c6ea7836af782e8 + languageName: node + linkType: hard + "protocols@npm:^1.4.0": version: 1.4.8 resolution: "protocols@npm:1.4.8" @@ -12040,6 +16008,15 @@ __metadata: languageName: node linkType: hard +"qs@npm:^6.10.5": + version: 6.12.0 + resolution: "qs@npm:6.12.0" + dependencies: + side-channel: ^1.0.6 + checksum: ba007fb2488880b9c6c3df356fe6888b9c1f4c5127552edac214486cfe83a332de09a5c40d490d79bb27bef977ba1085a8497512ff52eaac72e26564f77ce908 + languageName: node + linkType: hard + "qs@npm:^6.9.4": version: 6.11.2 resolution: "qs@npm:6.11.2" @@ -12061,7 +16038,7 @@ __metadata: languageName: node linkType: hard -"queue-microtask@npm:^1.2.2": +"queue-microtask@npm:^1.2.2, queue-microtask@npm:^1.2.3": version: 1.2.3 resolution: "queue-microtask@npm:1.2.3" checksum: b676f8c040cdc5b12723ad2f91414d267605b26419d5c821ff03befa817ddd10e238d22b25d604920340fd73efd8ba795465a0377c4adf45a4a41e4234e42dc4 @@ -12075,6 +16052,15 @@ __metadata: languageName: node linkType: hard +"randombytes@npm:^2.0.1": + version: 2.1.0 + resolution: "randombytes@npm:2.1.0" + dependencies: + safe-buffer: ^5.1.0 + checksum: d779499376bd4cbb435ef3ab9a957006c8682f343f14089ed5f27764e4645114196e75b7f6abf1cbd84fd247c0cb0651698444df8c9bf30e62120fbbc52269d6 + languageName: node + linkType: hard + "range-parser@npm:~1.2.1": version: 1.2.1 resolution: "range-parser@npm:1.2.1" @@ -12165,7 +16151,7 @@ __metadata: languageName: node linkType: hard -"readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": version: 3.6.2 resolution: "readable-stream@npm:3.6.2" dependencies: @@ -12455,6 +16441,13 @@ __metadata: languageName: node linkType: hard +"retry@npm:0.13.1": + version: 0.13.1 + resolution: "retry@npm:0.13.1" + checksum: 47c4d5be674f7c13eee4cfe927345023972197dbbdfba5d3af7e461d13b44de1bfd663bfc80d2f601f8ef3fc8164c16dd99655a221921954a65d044a2fc1233b + languageName: node + linkType: hard + "retry@npm:^0.12.0": version: 0.12.0 resolution: "retry@npm:0.12.0" @@ -12509,6 +16502,16 @@ __metadata: languageName: node linkType: hard +"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1, ripemd160@npm:^2.0.2": + version: 2.0.2 + resolution: "ripemd160@npm:2.0.2" + dependencies: + hash-base: ^3.0.0 + inherits: ^2.0.1 + checksum: 006accc40578ee2beae382757c4ce2908a826b27e2b079efdcd2959ee544ddf210b7b5d7d5e80467807604244e7388427330f5c6d4cd61e6edaddc5773ccc393 + languageName: node + linkType: hard + "rotating-file-stream@npm:^3.0.2": version: 3.1.1 resolution: "rotating-file-stream@npm:3.1.1" @@ -12516,13 +16519,41 @@ __metadata: languageName: node linkType: hard -"run-async@npm:^2.2.0, run-async@npm:^2.3.0": +"rpc-websockets@npm:^7.5.1": + version: 7.9.0 + resolution: "rpc-websockets@npm:7.9.0" + dependencies: + "@babel/runtime": ^7.17.2 + bufferutil: ^4.0.1 + eventemitter3: ^4.0.7 + utf-8-validate: ^5.0.2 + uuid: ^8.3.2 + ws: ^8.5.0 + dependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: c3ddd79ea7cf63b7a6a8d32356c7f9b363e41f26a6a8bbe889f9d2c5267811d492e194340fbad1a21ecfa457d5d1f253af3357a94d0118f66fcdea1fd9236adc + languageName: node + linkType: hard + +"run-async@npm:^2.2.0, run-async@npm:^2.3.0, run-async@npm:^2.4.0": version: 2.4.1 resolution: "run-async@npm:2.4.1" checksum: a2c88aa15df176f091a2878eb840e68d0bdee319d8d97bbb89112223259cebecb94bc0defd735662b83c2f7a30bed8cddb7d1674eb48ae7322dc602b22d03797 languageName: node linkType: hard +"run-parallel-limit@npm:^1.1.0": + version: 1.1.0 + resolution: "run-parallel-limit@npm:1.1.0" + dependencies: + queue-microtask: ^1.2.2 + checksum: 672c3b87e7f939c684b9965222b361421db0930223ed1e43ebf0e7e48ccc1a022ea4de080bef4d5468434e2577c33b7681e3f03b7593fdc49ad250a55381123c + languageName: node + linkType: hard + "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -12578,7 +16609,7 @@ __metadata: languageName: node linkType: hard -"safe-buffer@npm:5.2.1, safe-buffer@npm:~5.2.0": +"safe-buffer@npm:5.2.1, safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:~5.2.0": version: 5.2.1 resolution: "safe-buffer@npm:5.2.1" checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491 @@ -12603,13 +16634,39 @@ __metadata: languageName: node linkType: hard -"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0": +"safer-buffer@npm:>= 2.1.2 < 3, safer-buffer@npm:>= 2.1.2 < 3.0.0, safer-buffer@npm:^2.1.0": version: 2.1.2 resolution: "safer-buffer@npm:2.1.2" checksum: cab8f25ae6f1434abee8d80023d7e72b598cf1327164ddab31003c51215526801e40b66c5e65d658a0af1e9d6478cadcb4c745f4bd6751f97d8644786c0978b0 languageName: node linkType: hard +"scrypt-js@npm:3.0.1": + version: 3.0.1 + resolution: "scrypt-js@npm:3.0.1" + checksum: b7c7d1a68d6ca946f2fbb0778e0c4ec63c65501b54023b2af7d7e9f48fdb6c6580d6f7675cd53bda5944c5ebc057560d5a6365079752546865defb3b79dea454 + languageName: node + linkType: hard + +"secp256k1@npm:^4.0.2": + version: 4.0.3 + resolution: "secp256k1@npm:4.0.3" + dependencies: + elliptic: ^6.5.4 + node-addon-api: ^2.0.0 + node-gyp: latest + node-gyp-build: ^4.2.0 + checksum: 21e219adc0024fbd75021001358780a3cc6ac21273c3fcaef46943af73969729709b03f1df7c012a0baab0830fb9a06ccc6b42f8d50050c665cb98078eab477b + languageName: node + linkType: hard + +"seedrandom@npm:^3.0.5": + version: 3.0.5 + resolution: "seedrandom@npm:3.0.5" + checksum: 728b56bc3bc1b9ddeabd381e449b51cb31bdc0aa86e27fcd0190cea8c44613d5bcb2f6bb63ed79f78180cbe791c20b8ec31a9627f7b7fc7f476fd2bdb7e2da9f + languageName: node + linkType: hard + "semver-diff@npm:^3.1.1": version: 3.1.1 resolution: "semver-diff@npm:3.1.1" @@ -12619,6 +16676,17 @@ __metadata: languageName: node linkType: hard +"semver@npm:7.3.4": + version: 7.3.4 + resolution: "semver@npm:7.3.4" + dependencies: + lru-cache: ^6.0.0 + bin: + semver: bin/semver.js + checksum: 96451bfd7cba9b60ee87571959dc47e87c95b2fe58a9312a926340fee9907fc7bc062c352efdaf5bb24b2dff59c145e14faf7eb9d718a84b4751312531b39f43 + languageName: node + linkType: hard + "semver@npm:^5.7.1": version: 5.7.2 resolution: "semver@npm:5.7.2" @@ -12728,6 +16796,20 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72 + languageName: node + linkType: hard + "set-function-name@npm:^2.0.0": version: 2.0.1 resolution: "set-function-name@npm:2.0.1" @@ -12746,6 +16828,18 @@ __metadata: languageName: node linkType: hard +"sha.js@npm:^2.4.0, sha.js@npm:^2.4.11, sha.js@npm:^2.4.8": + version: 2.4.11 + resolution: "sha.js@npm:2.4.11" + dependencies: + inherits: ^2.0.1 + safe-buffer: ^5.0.1 + bin: + sha.js: ./bin.js + checksum: ebd3f59d4b799000699097dadb831c8e3da3eb579144fd7eb7a19484cbcbb7aca3c68ba2bb362242eb09e33217de3b4ea56e4678184c334323eca24a58e3ad07 + languageName: node + linkType: hard + "shebang-command@npm:^2.0.0": version: 2.0.0 resolution: "shebang-command@npm:2.0.0" @@ -12786,6 +16880,18 @@ __metadata: languageName: node linkType: hard +"side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" + dependencies: + call-bind: ^1.0.7 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + object-inspect: ^1.13.1 + checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97 + languageName: node + linkType: hard + "signal-exit@npm:^3.0.2, signal-exit@npm:^3.0.3, signal-exit@npm:^3.0.7": version: 3.0.7 resolution: "signal-exit@npm:3.0.7" @@ -12930,6 +17036,16 @@ __metadata: languageName: node linkType: hard +"source-map-support@npm:^0.5.21": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: ^1.0.0 + source-map: ^0.6.0 + checksum: 43e98d700d79af1d36f859bdb7318e601dfc918c7ba2e98456118ebc4c4872b327773e5a1df09b0524e9e5063bb18f0934538eace60cca2710d1fa687645d137 + languageName: node + linkType: hard + "source-map@npm:0.7.4, source-map@npm:^0.7.4": version: 0.7.4 resolution: "source-map@npm:0.7.4" @@ -12997,6 +17113,13 @@ __metadata: languageName: node linkType: hard +"statuses@npm:>= 1.5.0 < 2": + version: 1.5.0 + resolution: "statuses@npm:1.5.0" + checksum: c469b9519de16a4bb19600205cffb39ee471a5f17b82589757ca7bd40a8d92ebb6ed9f98b5a540c5d302ccbc78f15dc03cc0280dd6e00df1335568a5d5758a5c + languageName: node + linkType: hard + "stream-to-it@npm:^0.2.2": version: 0.2.4 resolution: "stream-to-it@npm:0.2.4" @@ -13006,6 +17129,13 @@ __metadata: languageName: node linkType: hard +"stream-transform@npm:^3.3.1": + version: 3.3.1 + resolution: "stream-transform@npm:3.3.1" + checksum: ed8a9c9fc208c293539fc303c1232bf7e3a33ee005864ad9179db413eb52dc34d40e79f51f7db49515775eeeb6ec10d10934a24a256f4eadc1a57acf7e354403 + languageName: node + linkType: hard + "streamsearch@npm:^1.1.0": version: 1.1.0 resolution: "streamsearch@npm:1.1.0" @@ -13200,6 +17330,26 @@ __metadata: languageName: node linkType: hard +"strnum@npm:^1.0.5": + version: 1.0.5 + resolution: "strnum@npm:1.0.5" + checksum: 651b2031db5da1bf4a77fdd2f116a8ac8055157c5420f5569f64879133825915ad461513e7202a16d7fec63c54fd822410d0962f8ca12385c4334891b9ae6dd2 + languageName: node + linkType: hard + +"strong-log-transformer@npm:^2.1.0": + version: 2.1.0 + resolution: "strong-log-transformer@npm:2.1.0" + dependencies: + duplexer: ^0.1.1 + minimist: ^1.2.0 + through: ^2.3.4 + bin: + sl-log-transformer: bin/sl-log-transformer.js + checksum: abf9a4ac143118f26c3a0771b204b02f5cf4fa80384ae158f25e02bfbff761038accc44a7f65869ccd5a5995a7f2c16b1466b83149644ba6cecd3072a8927297 + languageName: node + linkType: hard + "subql-mono@workspace:.": version: 0.0.0-use.local resolution: "subql-mono@workspace:." @@ -13237,6 +17387,13 @@ __metadata: languageName: unknown linkType: soft +"superstruct@npm:^0.14.2": + version: 0.14.2 + resolution: "superstruct@npm:0.14.2" + checksum: c5c4840f432da82125b923ec45faca5113217e83ae416e314d80eae012b8bb603d2e745025d173450758d116348820bc7028157f8c9a72b6beae879f94b837c0 + languageName: node + linkType: hard + "supports-color@npm:^2.0.0": version: 2.0.0 resolution: "supports-color@npm:2.0.0" @@ -13306,6 +17463,19 @@ __metadata: languageName: node linkType: hard +"tar-stream@npm:~2.2.0": + version: 2.2.0 + resolution: "tar-stream@npm:2.2.0" + dependencies: + bl: ^4.0.3 + end-of-stream: ^1.4.1 + fs-constants: ^1.0.0 + inherits: ^2.0.3 + readable-stream: ^3.1.1 + checksum: 699831a8b97666ef50021c767f84924cfee21c142c2eb0e79c63254e140e6408d6d55a065a2992548e72b06de39237ef2b802b99e3ece93ca3904a37622a66f3 + languageName: node + linkType: hard + "tar@npm:^6.1.11, tar@npm:^6.1.2": version: 6.2.1 resolution: "tar@npm:6.2.1" @@ -13357,6 +17527,13 @@ __metadata: languageName: node linkType: hard +"text-encoding-utf-8@npm:^1.0.2": + version: 1.0.2 + resolution: "text-encoding-utf-8@npm:1.0.2" + checksum: ec4c15d50e738c5dba7327ad432ebf0725ec75d4d69c0bd55609254c5a3bc5341272d7003691084a0a73d60d981c8eb0e87603676fdb6f3fed60f4c9192309f9 + languageName: node + linkType: hard + "text-table@npm:^0.2.0": version: 0.2.0 resolution: "text-table@npm:0.2.0" @@ -13382,7 +17559,7 @@ __metadata: languageName: node linkType: hard -"through@npm:^2.3.6, through@npm:^2.3.8": +"through@npm:>=2.2.7 <3, through@npm:^2.3.4, through@npm:^2.3.6, through@npm:^2.3.8": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd @@ -13408,6 +17585,29 @@ __metadata: languageName: node linkType: hard +"tiny-secp256k1@npm:^1.1.3": + version: 1.1.6 + resolution: "tiny-secp256k1@npm:1.1.6" + dependencies: + bindings: ^1.3.0 + bn.js: ^4.11.8 + create-hmac: ^1.1.7 + elliptic: ^6.4.0 + nan: ^2.13.2 + node-gyp: latest + checksum: f8f705f8a76dc9ccc9aa46f7bc353c00be63940c0a1198175fd77c9b85bdf24eb6db3d72c4756d24af320900290313c580c07695cda645d98410822f94ee01f5 + languageName: node + linkType: hard + +"tmp-promise@npm:^3.0.2": + version: 3.0.3 + resolution: "tmp-promise@npm:3.0.3" + dependencies: + tmp: ^0.2.0 + checksum: f854f5307dcee6455927ec3da9398f139897faf715c5c6dcee6d9471ae85136983ea06662eba2edf2533bdcb0fca66d16648e79e14381e30c7fb20be9c1aa62c + languageName: node + linkType: hard + "tmp@npm:^0.0.33": version: 0.0.33 resolution: "tmp@npm:0.0.33" @@ -13417,6 +17617,13 @@ __metadata: languageName: node linkType: hard +"tmp@npm:^0.2.0, tmp@npm:~0.2.1": + version: 0.2.3 + resolution: "tmp@npm:0.2.3" + checksum: 73b5c96b6e52da7e104d9d44afb5d106bb1e16d9fa7d00dbeb9e6522e61b571fbdb165c756c62164be9a3bbe192b9b268c236d370a2a0955c7689cd2ae377b95 + languageName: node + linkType: hard + "tmpl@npm:1.0.5": version: 1.0.5 resolution: "tmpl@npm:1.0.5" @@ -13600,6 +17807,39 @@ __metadata: languageName: node linkType: hard +"ts-poet@npm:^6.7.0": + version: 6.8.1 + resolution: "ts-poet@npm:6.8.1" + dependencies: + dprint-node: ^1.0.8 + checksum: 834a2afd04c47f355598564a85d9dbaabf09f05d0c0ed3a33a875518194c633fbd650d361bd0d9cfb9a33f8d68b3e6a163ad5a360a9f36ff9fa0f84bc76f2cd8 + languageName: node + linkType: hard + +"ts-proto-descriptors@npm:1.15.0": + version: 1.15.0 + resolution: "ts-proto-descriptors@npm:1.15.0" + dependencies: + long: ^5.2.3 + protobufjs: ^7.2.4 + checksum: 50e77d7c89dc52e9e74ee859e3232cece527d59ddcce515852059df70b4d80b49e73eb65166ec87f6f9238cadc2c77eb05695724f82aa4501bc2378fb2457643 + languageName: node + linkType: hard + +"ts-proto@npm:^1.115.4": + version: 1.171.0 + resolution: "ts-proto@npm:1.171.0" + dependencies: + case-anything: ^2.1.13 + protobufjs: ^7.2.4 + ts-poet: ^6.7.0 + ts-proto-descriptors: 1.15.0 + bin: + protoc-gen-ts_proto: protoc-gen-ts_proto + checksum: 65f91560f75f1ea6b946b1942bb020533f059673e54e96937ce6b079e8aca6faa922ade3c38a9d2aa5e6c4908e35c4d53abea3f303b80768620d0ce626caa9ce + languageName: node + linkType: hard + "tsconfig-paths@npm:^3.12.0, tsconfig-paths@npm:^3.14.2": version: 3.14.2 resolution: "tsconfig-paths@npm:3.14.2" @@ -13612,6 +17852,18 @@ __metadata: languageName: node linkType: hard +"tsconfig-paths@npm:^3.9.0": + version: 3.15.0 + resolution: "tsconfig-paths@npm:3.15.0" + dependencies: + "@types/json5": ^0.0.29 + json5: ^1.0.2 + minimist: ^1.2.6 + strip-bom: ^3.0.0 + checksum: 59f35407a390d9482b320451f52a411a256a130ff0e7543d18c6f20afab29ac19fbe55c360a93d6476213cc335a4d76ce90f67df54c4e9037f7d240920832201 + languageName: node + linkType: hard + "tslib@npm:2.5.3": version: 2.5.3 resolution: "tslib@npm:2.5.3" @@ -13619,20 +17871,29 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.8.1, tslib@npm:^1.9.0": +"tslib@npm:^1.11.1, tslib@npm:^1.8.1, tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: dbe628ef87f66691d5d2959b3e41b9ca0045c3ee3c7c7b906cc1e328b39f199bb1ad9e671c39025bd56122ac57dfbf7385a94843b1cc07c60a4db74795829acd languageName: node linkType: hard -"tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.1, tslib@npm:^2.6.2": +"tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.3.1, tslib@npm:^2.4.0, tslib@npm:^2.6.1, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: 329ea56123005922f39642318e3d1f0f8265d1e7fcb92c633e0809521da75eeaca28d2cf96d7248229deb40e5c19adf408259f4b9640afd20d13aecc1430f3ad languageName: node linkType: hard +"tslog@npm:^3.2.2": + version: 3.3.4 + resolution: "tslog@npm:3.3.4" + dependencies: + source-map-support: ^0.5.21 + checksum: c830921239dfb0e1fd8b4733710b6d3a7e49d1c2890481a49b0f3396c86e913a2db2bbafc6be7afcc305ef4e8503b5cb58817bc770c969fef67758a1f764871b + languageName: node + linkType: hard + "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -13651,6 +17912,13 @@ __metadata: languageName: node linkType: hard +"tweetnacl@npm:1.0.3, tweetnacl@npm:^1.0.1, tweetnacl@npm:^1.0.2, tweetnacl@npm:^1.0.3": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: e4a57cac188f0c53f24c7a33279e223618a2bfb5fea426231991652a13247bea06b081fd745d71291fcae0f4428d29beba1b984b1f1ce6f66b06a6d1ab90645c + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" @@ -13775,6 +18043,13 @@ __metadata: languageName: node linkType: hard +"typeforce@npm:^1.11.5": + version: 1.18.0 + resolution: "typeforce@npm:1.18.0" + checksum: e3b21e27e76cb05f32285bef7c30a29760e79c622cfe4aa3c179ce49d1c7895b7154c8deedb9fe4599b1fd0428d35860d43e0776da1c04861168f3ad7ed99c70 + languageName: node + linkType: hard + "typescript@npm:^4.9.5": version: 4.9.5 resolution: "typescript@npm:4.9.5" @@ -13795,6 +18070,13 @@ __metadata: languageName: node linkType: hard +"u3@npm:^0.1.1": + version: 0.1.1 + resolution: "u3@npm:0.1.1" + checksum: d55f396c607b0a2340d6165526b5143a29b369e7e0397b04f79633db77cd668f2da713feb7adb4f93a588e82a388ff995d9a2b16123d0cb02fe394fd2f26b529 + languageName: node + linkType: hard + "uid@npm:2.0.2": version: 2.0.2 resolution: "uid@npm:2.0.2" @@ -13886,6 +18168,13 @@ __metadata: languageName: node linkType: hard +"unique-names-generator@npm:^4.6.0": + version: 4.7.1 + resolution: "unique-names-generator@npm:4.7.1" + checksum: 81b58efee72458fd0c84f54a89d731b2570305d331ce62c4156273e54ece77b6488fc6c607169f4b8f6644fa48b42aef8689dbe7e310ae2c4bafbd5c0a625354 + languageName: node + linkType: hard + "unique-slug@npm:^4.0.0": version: 4.0.0 resolution: "unique-slug@npm:4.0.0" @@ -14106,6 +18395,16 @@ __metadata: languageName: node linkType: hard +"utf-8-validate@npm:^5.0.2": + version: 5.0.10 + resolution: "utf-8-validate@npm:5.0.10" + dependencies: + node-gyp: latest + node-gyp-build: ^4.3.0 + checksum: 5579350a023c66a2326752b6c8804cc7b39dcd251bb088241da38db994b8d78352e388dcc24ad398ab98385ba3c5ffcadb6b5b14b2637e43f767869055e46ba6 + languageName: node + linkType: hard + "util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1": version: 1.0.2 resolution: "util-deprecate@npm:1.0.2" @@ -14122,6 +18421,13 @@ __metadata: languageName: node linkType: hard +"utility-types@npm:^3.10.0": + version: 3.11.0 + resolution: "utility-types@npm:3.11.0" + checksum: 35a4866927bbea5d037726744028d05c6e37772ded2aabaca21480ce9380185436aef586ead525e327c7f3c640b1a3287769a12ef269c7b165a2ddd50ea6ad61 + languageName: node + linkType: hard + "utils-merge@npm:1.0.1": version: 1.0.1 resolution: "utils-merge@npm:1.0.1" @@ -14147,6 +18453,15 @@ __metadata: languageName: node linkType: hard +"uuid@npm:^9.0.0, uuid@npm:^9.0.1": + version: 9.0.1 + resolution: "uuid@npm:9.0.1" + bin: + uuid: dist/bin/uuid + checksum: 39931f6da74e307f51c0fb463dc2462807531dc80760a9bff1e35af4316131b4fc3203d16da60ae33f07fdca5b56f3f1dd662da0c99fea9aaeab2004780cc5f4 + languageName: node + linkType: hard + "v8-compile-cache-lib@npm:^3.0.1": version: 3.0.1 resolution: "v8-compile-cache-lib@npm:3.0.1" @@ -14154,6 +18469,13 @@ __metadata: languageName: node linkType: hard +"v8-compile-cache@npm:2.3.0": + version: 2.3.0 + resolution: "v8-compile-cache@npm:2.3.0" + checksum: adb0a271eaa2297f2f4c536acbfee872d0dd26ec2d76f66921aa7fc437319132773483344207bdbeee169225f4739016d8d2dbf0553913a52bb34da6d0334f8e + languageName: node + linkType: hard + "v8-to-istanbul@npm:^9.0.1": version: 9.2.0 resolution: "v8-to-istanbul@npm:9.2.0" @@ -14208,6 +18530,13 @@ __metadata: languageName: node linkType: hard +"vlq@npm:^2.0.4": + version: 2.0.4 + resolution: "vlq@npm:2.0.4" + checksum: b2ed0d3a5423f34bba98a18250f8b13a96eebff9c8f9427fa9cd78065d31f35641f6fd659c5642253b79532000a37aec0582abac95d1ef4af2cd0c96a716f1b6 + languageName: node + linkType: hard + "vm2@npm:^3.9.19, vm2@npm:^3.9.9": version: 3.9.19 resolution: "vm2@npm:3.9.19" @@ -14338,6 +18667,15 @@ __metadata: languageName: node linkType: hard +"wif@npm:^2.0.6": + version: 2.0.6 + resolution: "wif@npm:2.0.6" + dependencies: + bs58check: <3.0.0 + checksum: 8c3147ef98d56f394d66f0477f699fba7fc18dd0d1c2c5d0f8408be41acffed589fa82447d80eae5afc9a3cbd943bc3eebb337b9f114955adeaad02a244f4f9a + languageName: node + linkType: hard + "wkx@npm:^0.5.0": version: 0.5.0 resolution: "wkx@npm:0.5.0" @@ -14358,7 +18696,7 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^6.2.0": +"wrap-ansi@npm:^6.0.1, wrap-ansi@npm:^6.2.0": version: 6.2.0 resolution: "wrap-ansi@npm:6.2.0" dependencies: @@ -14409,7 +18747,22 @@ __metadata: languageName: node linkType: hard -"ws@npm:^7": +"ws@npm:7.4.6": + version: 7.4.6 + resolution: "ws@npm:7.4.6" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 3a990b32ed08c72070d5e8913e14dfcd831919205be52a3ff0b4cdd998c8d554f167c9df3841605cde8b11d607768cacab3e823c58c96a5c08c987e093eb767a + languageName: node + linkType: hard + +"ws@npm:^7, ws@npm:^7.4.5": version: 7.5.9 resolution: "ws@npm:7.5.9" peerDependencies: @@ -14424,6 +18777,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.5.0": + version: 8.16.0 + resolution: "ws@npm:8.16.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: feb3eecd2bae82fa8a8beef800290ce437d8b8063bdc69712725f21aef77c49cb2ff45c6e5e7fce622248f9c7abaee506bae0a9064067ffd6935460c7357321b + languageName: node + linkType: hard + "xdg-basedir@npm:^4.0.0": version: 4.0.0 resolution: "xdg-basedir@npm:4.0.0" @@ -14483,6 +18851,13 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:21.0.1": + version: 21.0.1 + resolution: "yargs-parser@npm:21.0.1" + checksum: c3ea2ed12cad0377ce3096b3f138df8267edf7b1aa7d710cd502fe16af417bafe4443dd71b28158c22fcd1be5dfd0e86319597e47badf42ff83815485887323a + languageName: node + linkType: hard + "yargs-parser@npm:^20.2.2": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" @@ -14512,7 +18887,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.0.1, yargs@npm:^17.3.1": +"yargs@npm:^17.0.1, yargs@npm:^17.3.1, yargs@npm:^17.4.0": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: From c8d107033cd2c476f880dae4165cf132bb37a6d1 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 12 Apr 2024 08:22:22 +0800 Subject: [PATCH 33/81] fix up on bad rebase --- packages/node/src/indexer/cosmosClient.connection.ts | 5 ----- packages/node/src/utils/cosmos.ts | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/packages/node/src/indexer/cosmosClient.connection.ts b/packages/node/src/indexer/cosmosClient.connection.ts index 35b40d008..bc19eccfd 100644 --- a/packages/node/src/indexer/cosmosClient.connection.ts +++ b/packages/node/src/indexer/cosmosClient.connection.ts @@ -12,11 +12,6 @@ import { NetworkMetadataPayload, } from '@subql/node-core'; import { getLogger } from '@subql/node-core/dist'; -import { - CosmosBlock, - CosmosEvent, - CosmosTransaction, -} from '@subql/types-cosmos'; import { CosmosClient, CosmosSafeClient } from './api.service'; import { HttpClient, WebsocketClient } from './rpc-clients'; import { BlockContent } from './types'; diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index 5a642aed6..f0b6a55c9 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -355,8 +355,8 @@ export function formatBlockUtil(block: B): IBlock { } export async function fetchBlocksBatches( - blockArray: number[], api: CosmosClient, + blockArray: number[], ): Promise[]> { const blocks = await fetchCosmosBlocksArray( (height: number) => getBlockByHeightByRpc(api, height), @@ -371,7 +371,7 @@ export async function fetchBlocksBatches( ); return formatBlockUtil( - new LazyBlockContent(blockInfo, blockResults, api.registry) + new LazyBlockContent(blockInfo, blockResults, api.registry), ); } catch (e) { logger.error( From fdcd23c21df7d645286d3e5a3a854dea599584c1 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 12 Apr 2024 11:43:51 +0800 Subject: [PATCH 34/81] add clean up on failed bundle handling, rework error handle to ensure correctly thrown error, update stream configs --- packages/node/src/utils/kyve/kyve.spec.ts | 25 ++++++++++++++++++++++- packages/node/src/utils/kyve/kyve.ts | 16 +++++++++++++-- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 6b19c8db4..1873e5275 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -208,6 +208,29 @@ describe('KyveApi', () => { ).resolves.toBe(false); expect(clearFileSpy).toHaveBeenCalledTimes(1); }); + it('remove bundle.json if bundle fetch fails', async () => { + (kyveApi as any).cachedBundleDetails = await (kyveApi as any).getBundleById( + 1, + ); + + retrieveBundleDataSpy = jest + .spyOn(kyveApi as any, 'retrieveBundleData') + .mockImplementation(() => { + return new Promise((resolve, reject) => { + reject('failed to fetch'); + }); + }); + + await expect(kyveApi.getFileCacheData()).rejects.toBeDefined(); + + await expect( + fs.promises.stat( + (kyveApi as any).getBundleFilePath( + (kyveApi as any).cachedBundleDetails.id, + ), + ), + ).rejects.toThrow('no such file or directory'); + }); it('able to download and write to file, with simulated workers', async () => { (kyveApi as any).cachedBundleDetails = await (kyveApi as any).getBundleById( 1, @@ -230,7 +253,7 @@ describe('KyveApi', () => { ]), ).resolves.not.toThrow(); - expect(pollSpy).toHaveBeenCalled(); + expect(pollSpy).toHaveBeenCalledTimes(3); const r = await kyveApi.readFromFile( (kyveApi as any).getBundleFilePath( diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index b81d2da38..40add0dd6 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -227,7 +227,17 @@ export class KyveApi { async downloadAndProcessBundle(bundleFilePath: string): Promise { const writeStream = fs.createWriteStream(bundleFilePath, { - flags: 'wx+', + flags: 'wx', + mode: 0o200, // write only access for owner + }); + + await new Promise((resolve, reject) => { + writeStream.on('open', resolve); + writeStream.on('error', (err) => { + reject(err); + }); + }).catch((e) => { + throw e; }); const zippedBundleData = await this.retrieveBundleData(); @@ -242,8 +252,9 @@ export class KyveApi { .pipe(gunzip) .on('error', (err) => reject(err)) .pipe(writeStream) - .on('error', (err) => reject(err)) .on('finish', resolve); + }).catch((e) => { + throw e; }); await fs.promises.chmod(bundleFilePath, 0o444); @@ -259,6 +270,7 @@ export class KyveApi { if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { return this.pollUntilReadable(bundleFilePath); } else { + await fs.promises.unlink(bundleFilePath); throw e; } } From 1d4a41c28b23c13248e049ae21727cde5ea9ce31 Mon Sep 17 00:00:00 2001 From: bz888 Date: Sun, 14 Apr 2024 21:51:12 +0800 Subject: [PATCH 35/81] update with fixes on kyveApi cache, add test for more batchSize and worker simulators, update all other tests with updated kyveApi cache --- packages/node/src/indexer/api.service.ts | 1 - packages/node/src/utils/kyve/kyve.spec.ts | 244 +++++++++++++++------- packages/node/src/utils/kyve/kyve.ts | 122 +++++------ 3 files changed, 231 insertions(+), 136 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 5552f9b73..07cd603ea 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -141,7 +141,6 @@ export class ApiService return apiInstance.fetchBlocks(heights); }, numAttempts); } - throw e; } } diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 1873e5275..f24c7aead 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -6,6 +6,7 @@ import path from 'path'; import { Readable } from 'stream'; import { promisify } from 'util'; import { gzipSync } from 'zlib'; +import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; import { GeneratedType, Registry } from '@cosmjs/proto-signing'; import { defaultRegistryTypes } from '@cosmjs/stargate'; import { Tendermint37Client } from '@cosmjs/tendermint-rpc'; @@ -56,6 +57,10 @@ describe('KyveApi', () => { let tmpPath: string; let retrieveBundleDataSpy: jest.SpyInstance; + let decoderBlockResultsSpy: jest.SpyInstance; + let decoderBlockSpy: jest.SpyInstance; + let injectLogSpy: jest.SpyInstance; + let readerSpy: jest.SpyInstance; let zippedMockResp: Buffer; let mockStream: Readable; @@ -73,7 +78,12 @@ describe('KyveApi', () => { ); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); + retrieveBundleDataSpy = jest.spyOn(kyveApi as any, 'retrieveBundleData'); + decoderBlockSpy = jest.spyOn(kyveApi as any, 'decodeBlock'); + decoderBlockResultsSpy = jest.spyOn(kyveApi as any, 'decodeBlockResult'); + injectLogSpy = jest.spyOn(kyveApi as any, 'injectLogs'); + readerSpy = jest.spyOn(kyveApi as any, 'readFromFile'); }); beforeEach(() => { zippedMockResp = gzipSync(Buffer.from(JSON.stringify(block_3856726))); @@ -86,13 +96,15 @@ describe('KyveApi', () => { }); afterEach(() => { - // reset cache - (kyveApi as any).currentBundleId = -1; - (kyveApi as any).cachedBundleDetails = undefined; - (kyveApi as any).cachedBundle = undefined; - (kyveApi as any).cachedBlocks = undefined; - retrieveBundleDataSpy.mockRestore(); + + decoderBlockSpy.mockRestore(); + decoderBlockResultsSpy.mockRestore(); + injectLogSpy.mockRestore(); + readerSpy.mockRestore(); + + // reset cache + (kyveApi as any).cachedBundleDetails = []; }); afterAll(async () => { await promisify(rimraf)(tmpPath); @@ -133,14 +145,124 @@ describe('KyveApi', () => { expect(firstBundle).toBe(0); expect(laterBundle).toBe(113773); }); - it('retrieve and unzip storage data', async () => { - const id = 8; - (kyveApi as any).cachedBundleDetails = await (kyveApi as any).getBundleById( - id, + it('Able to write and read with parallel calls', async () => { + const bundle_0Data = [ + { + key: '1', + value: { + block: {}, + block_results: {}, + }, + }, + { + key: '150', + value: { + block: {}, + block_results: {}, + }, + }, + ]; + + const bundle_1Data = [ + { + key: '151', + value: { + block: {}, + block_results: {}, + }, + }, + { + key: '300', + value: { + block: {}, + block_results: {}, + }, + }, + ]; + const bundle_2Data = [ + { + key: '301', + value: { + block: {}, + block_results: {}, + }, + }, + ]; + + const steam0 = new Readable({ + read() { + this.push(gzipSync(Buffer.from(JSON.stringify(bundle_0Data)))); + this.push(null); + }, + }); + const steam1 = new Readable({ + read() { + this.push(gzipSync(Buffer.from(JSON.stringify(bundle_1Data)))); + this.push(null); + }, + }); + const steam2 = new Readable({ + read() { + this.push(gzipSync(Buffer.from(JSON.stringify(bundle_2Data)))); + this.push(null); + }, + }); + + retrieveBundleDataSpy.mockImplementation((storageId: string) => { + switch (storageId) { + case 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU': + return { data: steam0 }; + case 'nLFqaswVsuwZb1QoEXdLTOiB8o69AyxEGHzmxT1TNsw': + return { data: steam1 }; + case 'PnvgDqr8xq6xr9ZIwXZAo96uMb2Zil3muoVOl6eUpD8': + return { data: steam2 }; + default: + break; + } + }); + + decoderBlockSpy.mockImplementation( + (block: JsonRpcSuccessResponse) => block, + ); + decoderBlockResultsSpy.mockImplementation( + (blockResult: JsonRpcSuccessResponse) => blockResult, + ); + injectLogSpy.mockImplementation( + (kyveBlockResult: BlockResultsResponse) => kyveBlockResult, ); - const bundleFileName = (kyveApi as any).getBundleFilePath(id); - await kyveApi.downloadAndProcessBundle(bundleFileName); + // TODO, should this be called with promise.all or for loop ? + // for (const height of [1, 151, 151, 300, 301]) { + // await kyveApi.getBlockByHeight(height) + // } + // expect download to be called multiple times + + const blocks = await Promise.all([ + kyveApi.getBlockByHeight(1), + kyveApi.getBlockByHeight(151), + kyveApi.getBlockByHeight(151), + kyveApi.getBlockByHeight(300), + kyveApi.getBlockByHeight(301), + ]); + + const cachedBundles = await fs.promises.readdir(tmpPath); + expect(cachedBundles.length).toBe(3); + + for (const bundle of (kyveApi as any).cachedBundleDetails) { + const stats = await fs.promises.stat( + (kyveApi as any).getBundleFilePath(bundle.id), + ); + const permissions = (stats.mode & 0o777).toString(8); + expect(permissions).toBe('444'); + } + }); + it('retrieve and unzip storage data', async () => { + const bundle = await (kyveApi as any).getBundleById(8); + + (kyveApi as any).cachedBundleDetails.push(bundle); + + const bundleFileName = (kyveApi as any).getBundleFilePath(bundle.id); + await kyveApi.downloadAndProcessBundle(bundle); const v = await kyveApi.readFromFile(bundleFileName); @@ -149,15 +271,14 @@ describe('KyveApi', () => { expect(b).toBeDefined(); }); it('Should increment bundleId when height exceeds cache', async () => { - (kyveApi as any).currentBundleId = 0; - (kyveApi as any).cachedBundle = 'value'; - (kyveApi as any).cachedBundleDetails = { - to_key: '150', - storage_id: 'YLpTxtj_0ICoWq9HUEOx6VcIzKk8Qui1rnkhH4acbTU', - compression_id: '1', - } as any; + const bundle = await (kyveApi as any).getBundleById(0); + (kyveApi as any).cachedBundleDetails.push(bundle); + jest.spyOn(kyveApi as any, 'getFileCacheData').mockResolvedValueOnce('{}'); await (kyveApi as any).updateCurrentBundleAndDetails(160); - expect((kyveApi as any).currentBundleId).toBe(1); + + expect( + (kyveApi as any).cachedBundleDetails.find((b) => b.id === '1'), + ).toBeDefined(); }); it('compare block info', async () => { const height = 3901476; @@ -170,11 +291,11 @@ describe('KyveApi', () => { rpc: KYVE_ENDPOINT, }).createLCDClient(); - const poolId = await KyveApi.fetchPoolId('archway-1', lcdClient); + const poolId = await (KyveApi as any).fetchPoolId('archway-1', lcdClient); expect(poolId).toBe('2'); }); - it('able to update and clear file cache', async () => { + it('clear cache file when height exceeds bundle max', async () => { const checkFileExist = async (filePath: string) => { try { await fs.promises.access(filePath); @@ -184,19 +305,16 @@ describe('KyveApi', () => { } }; - // create two mock bundles await fs.promises.writeFile(path.join(tmpPath, 'bundle_130263'), 'mock'); // should be removed await fs.promises.writeFile(path.join(tmpPath, 'bundle_130264'), 'mock'); - retrieveBundleDataSpy = jest - .spyOn(kyveApi as any, 'retrieveBundleData') - .mockImplementation(() => { - return { data: mockStream }; - }); + retrieveBundleDataSpy.mockImplementation(() => { + return { data: mockStream }; + }); const clearFileSpy = jest.spyOn(kyveApi as any, 'clearFileCache'); - jest.spyOn(kyveApi as any, 'readFromFile').mockImplementation(() => { + readerSpy.mockImplementation(() => { return Promise.resolve(JSON.stringify(block_3856726)); }); @@ -209,67 +327,45 @@ describe('KyveApi', () => { expect(clearFileSpy).toHaveBeenCalledTimes(1); }); it('remove bundle.json if bundle fetch fails', async () => { - (kyveApi as any).cachedBundleDetails = await (kyveApi as any).getBundleById( - 1, - ); + const bundleDetail = await (kyveApi as any).getBundleById(1); + (kyveApi as any).cachedBundleDetails = [bundleDetail]; - retrieveBundleDataSpy = jest - .spyOn(kyveApi as any, 'retrieveBundleData') - .mockImplementation(() => { - return new Promise((resolve, reject) => { - reject('failed to fetch'); - }); + retrieveBundleDataSpy.mockImplementation(() => { + return new Promise((resolve, reject) => { + reject('failed to fetch'); }); + }); - await expect(kyveApi.getFileCacheData()).rejects.toBeDefined(); + await expect( + (kyveApi as any).getFileCacheData(bundleDetail), + ).rejects.toBeDefined(); await expect( - fs.promises.stat( - (kyveApi as any).getBundleFilePath( - (kyveApi as any).cachedBundleDetails.id, - ), - ), + fs.promises.stat((kyveApi as any).getBundleFilePath(bundleDetail.id)), ).rejects.toThrow('no such file or directory'); }); - it('able to download and write to file, with simulated workers', async () => { - (kyveApi as any).cachedBundleDetails = await (kyveApi as any).getBundleById( - 1, - ); + it('Able to poll with simulated workers', async () => { + const bundleDetail = await (kyveApi as any).getBundleById(130265); + (kyveApi as any).cachedBundleDetails = [bundleDetail]; - retrieveBundleDataSpy = jest - .spyOn(kyveApi as any, 'retrieveBundleData') - .mockImplementation(() => { - return { data: mockStream }; - }); + retrieveBundleDataSpy.mockImplementation(() => { + return { data: mockStream }; + }); const pollSpy = jest.spyOn(kyveApi as any, 'pollUntilReadable'); - - await expect( - Promise.all([ - kyveApi.getFileCacheData(), - kyveApi.getFileCacheData(), - kyveApi.getFileCacheData(), - kyveApi.getFileCacheData(), - ]), - ).resolves.not.toThrow(); + await Promise.all([ + kyveApi.fetchBlocksBatches(registry, [3856726]), + kyveApi.fetchBlocksBatches(registry, [3856726]), + kyveApi.fetchBlocksBatches(registry, [3856726]), + kyveApi.fetchBlocksBatches(registry, [3856726]), + ]); expect(pollSpy).toHaveBeenCalledTimes(3); const r = await kyveApi.readFromFile( - (kyveApi as any).getBundleFilePath( - (kyveApi as any).cachedBundleDetails.id, - ), + (kyveApi as any).getBundleFilePath(bundleDetail.id), ); - const stats = await fs.promises.stat( - (kyveApi as any).getBundleFilePath( - (kyveApi as any).cachedBundleDetails.id, - ), - ); - - const permissions = (stats.mode & 0o777).toString(8); - - expect(permissions).toBe('444'); expect(r).toEqual(JSON.stringify(block_3856726)); }); describe('able to wrap kyveBlock', () => { diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 40add0dd6..2d1331c93 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -33,14 +33,13 @@ const logger = getLogger('kyve'); // eslint-disable-next-line @typescript-eslint/no-var-requires const { version: packageVersion } = require('../../../package.json'); -interface UnZippedKyveBlockReponse { +interface KyveBundleData { value: { block: any; block_results: any }; key: string; } export class KyveApi { - private currentBundleId = -1; - private cachedBundleDetails: BundleDetails; + private cachedBundleDetails: BundleDetails[] = []; private constructor( private readonly storageUrl: string, @@ -67,7 +66,7 @@ export class KyveApi { return kyve; } - static async fetchPoolId( + private static async fetchPoolId( chainId: string, lcdClient: KyveLCDClientType, ): Promise { @@ -140,7 +139,10 @@ export class KyveApi { private async getBundleId(height: number): Promise { const latestBundleId = await this.getLatestBundleId(); - let low = this.currentBundleId; + let low = + this.cachedBundleDetails.length > 0 + ? Math.min(...this.cachedBundleDetails.map((b) => parseDecimal(b.id))) + : -1; let high = latestBundleId; let startBundleId = -1; // Initialize to an invalid ID initially @@ -153,7 +155,6 @@ export class KyveApi { if (height >= fromKey && height <= toKey) { startBundleId = mid; - this.currentBundleId = startBundleId; return startBundleId; } @@ -168,45 +169,44 @@ export class KyveApi { private findBlockByHeight( height: number, - fileCacheData: UnZippedKyveBlockReponse[], - ): UnZippedKyveBlockReponse { + fileCacheData: KyveBundleData[], + ): KyveBundleData | undefined { return fileCacheData.find( - (bk: UnZippedKyveBlockReponse) => bk.key === height.toString(), + (bk: KyveBundleData) => bk.key === height.toString(), ); } - async updateCurrentBundleAndDetails( + private addToCachedBundle(bundle: BundleDetails): void { + if (!this.cachedBundleDetails.find((b) => b.id === bundle.id)) { + this.cachedBundleDetails.push(bundle); + } + } + + private getBundleFromCache(height: number): BundleDetails | undefined { + return this.cachedBundleDetails.find( + (b) => + parseDecimal(b.from_key) <= height && height <= parseDecimal(b.to_key), + ); + } + + private async updateCurrentBundleAndDetails( height: number, - ): Promise { - // this is on init, and then when height is greater than current cache - if ( - this.currentBundleId === -1 || - parseDecimal(this.cachedBundleDetails.to_key) < height - ) { - this.currentBundleId = - this.currentBundleId === -1 - ? await this.getBundleId(height) - : this.currentBundleId + 1; - this.cachedBundleDetails = await this.getBundleById(this.currentBundleId); - try { - await fs.promises.access( - path.join( - this.tmpCacheDir, - `bundle_${parseDecimal(this.cachedBundleDetails.id) - 2}`, - ), - ); - await this.clearFileCache(); - } catch (e) { - /* if file does not exist, no need to clear fileCache */ - } + ): Promise { + if (this.cachedBundleDetails.length === 0) { + const bundleId = await this.getBundleId(height); + const bundleDetail = await this.getBundleById(bundleId); + this.addToCachedBundle(bundleDetail); + } - return JSON.parse(await this.getFileCacheData()); + const bundle = this.getBundleFromCache(height); + if (bundle) { + return JSON.parse(await this.getFileCacheData(bundle)); } else { - return JSON.parse( - await this.readFromFile( - this.getBundleFilePath(this.cachedBundleDetails.id), - ), - ); + const bundleId = await this.getBundleId(height); + const newBundleDetails = await this.getBundleById(bundleId); + + this.addToCachedBundle(newBundleDetails); + return JSON.parse(await this.getFileCacheData(newBundleDetails)); } } @@ -225,12 +225,15 @@ export class KyveApi { } } - async downloadAndProcessBundle(bundleFilePath: string): Promise { + async downloadAndProcessBundle(bundle: BundleDetails): Promise { + const bundleFilePath = this.getBundleFilePath(bundle.id); + const writeStream = fs.createWriteStream(bundleFilePath, { flags: 'wx', mode: 0o200, // write only access for owner }); + // to ensure the stream to throw an on-stack error await new Promise((resolve, reject) => { writeStream.on('open', resolve); writeStream.on('error', (err) => { @@ -240,7 +243,7 @@ export class KyveApi { throw e; }); - const zippedBundleData = await this.retrieveBundleData(); + const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); const gunzip = zlib.createUnzip({ maxOutputLength: MAX_COMPRESSION_BYTE_SIZE /* avoid zip bombs */, @@ -248,9 +251,8 @@ export class KyveApi { await new Promise((resolve, reject) => { zippedBundleData.data - .on('error', (err) => reject(err)) .pipe(gunzip) - .on('error', (err) => reject(err)) + .on('error', reject) .pipe(writeStream) .on('finish', resolve); }).catch((e) => { @@ -260,11 +262,11 @@ export class KyveApi { await fs.promises.chmod(bundleFilePath, 0o444); } - async getFileCacheData(): Promise { - const bundleFilePath = this.getBundleFilePath(this.cachedBundleDetails.id); + private async getFileCacheData(bundle: BundleDetails): Promise { + const bundleFilePath = this.getBundleFilePath(bundle.id); try { - await this.downloadAndProcessBundle(bundleFilePath); + await this.downloadAndProcessBundle(bundle); return await this.readFromFile(bundleFilePath); } catch (e: any) { if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { @@ -280,20 +282,15 @@ export class KyveApi { return fs.promises.readFile(bundleFilePath, 'utf-8'); } - async clearFileCache(): Promise { - const currentBundleId = parseDecimal(this.cachedBundleDetails.id); - const files = await fs.promises.readdir(this.tmpCacheDir); - - const minAllowedBundleId = currentBundleId - 2; - - const filesToRemove = files.filter((file) => { - const match = file.match(/bundle_(\d+)/); // Extract bundle ID from filename - return match && parseDecimal(match[1]) <= minAllowedBundleId; - }); + // todo unsure when to clear the file cache + private async clearFileCache(height: number): Promise { + const bundleToRemove = this.cachedBundleDetails.filter( + (b) => parseDecimal(b.from_key) > height, + ); - for (const file of filesToRemove) { - const filePath = path.join(this.tmpCacheDir, file); - await fs.promises.unlink(filePath); + for (const bundle of bundleToRemove) { + const bundlePath = this.getBundleFilePath(bundle.id); + await fs.promises.unlink(bundlePath); } } @@ -310,7 +307,9 @@ export class KyveApi { ]; } - private injectLogs(kyveBlockResult: BlockResultsResponse) { + private injectLogs( + kyveBlockResult: BlockResultsResponse, + ): BlockResultsResponse { try { kyveBlockResult.results.forEach((b) => { // log is readonly hence needing to cast it @@ -362,15 +361,16 @@ export class KyveApi { private async fetchBlocksArray( blockArray: number[], ): Promise<[BlockResponse, BlockResultsResponse][]> { + // use for loop instead ? return Promise.all( blockArray.map(async (height) => this.getBlockByHeight(height)), ); } - private async retrieveBundleData(): Promise { + private async retrieveBundleData(storageId: string): Promise { return axios({ method: 'get', - url: this.cachedBundleDetails.storage_id, + url: storageId, baseURL: this.storageUrl, responseType: 'stream', timeout: BUNDLE_TIMEOUT, From 44a52801c229f8f9658cb4aaf4a2b2938feaef92 Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 15 Apr 2024 08:19:17 +0800 Subject: [PATCH 36/81] add fileCache support for local reader --- .../node/src/configure/SubqueryProject.ts | 20 +++++++++++++++++-- packages/node/src/indexer/api.service.ts | 2 +- packages/node/src/utils/kyve/kyve.ts | 8 ++++++-- packages/node/src/utils/project.spec.ts | 12 +++++++++++ packages/node/src/utils/project.ts | 8 ++++++++ 5 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 packages/node/src/utils/project.spec.ts diff --git a/packages/node/src/configure/SubqueryProject.ts b/packages/node/src/configure/SubqueryProject.ts index fb8412d3b..aafd529ff 100644 --- a/packages/node/src/configure/SubqueryProject.ts +++ b/packages/node/src/configure/SubqueryProject.ts @@ -3,7 +3,7 @@ import assert from 'assert'; import { Injectable } from '@nestjs/common'; -import { validateSemver } from '@subql/common'; +import { LocalReader, makeTempDir, validateSemver } from '@subql/common'; import { CosmosProjectNetworkConfig, parseCosmosProjectManifest, @@ -28,7 +28,7 @@ import { import { buildSchemaFromString } from '@subql/utils'; import Cron from 'cron-converter'; import { GraphQLSchema } from 'graphql'; -import { processNetworkConfig } from '../utils/project'; +import { isTmpDir, processNetworkConfig } from '../utils/project'; const { version: packageVersion } = require('../../package.json'); @@ -58,6 +58,7 @@ export class SubqueryProject implements ISubqueryProject { readonly templates: CosmosProjectDsTemplate[], readonly runner?: RunnerSpecs, readonly parent?: ParentProject, + readonly fileCacheDir?: string, ) { this.#dataSources = dataSources; } @@ -100,16 +101,29 @@ export class SubqueryProject implements ISubqueryProject { NOT_SUPPORT('<1.0.0'); } + const fileCacheDir = await getFileCacheDir(reader, root); + return loadProjectFromManifestBase( manifest.asV1_0_0, reader, path, root, networkOverrides, + fileCacheDir, ); } } +async function getFileCacheDir( + reader: Reader, + projectRoot: string, +): Promise { + if (isTmpDir(projectRoot)) return projectRoot; + if (reader instanceof LocalReader) return makeTempDir(); + + return projectRoot; +} + type SUPPORT_MANIFEST = ProjectManifestV1_0_0Impl; async function loadProjectFromManifestBase( @@ -118,6 +132,7 @@ async function loadProjectFromManifestBase( path: string, root: string, networkOverrides?: Partial, + fileCacheDir?: string, ): Promise { if (typeof projectManifest.network.endpoint === 'string') { projectManifest.network.endpoint = [projectManifest.network.endpoint]; @@ -177,5 +192,6 @@ async function loadProjectFromManifestBase( templates, runner, projectManifest.parent, + fileCacheDir, ); } diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 07cd603ea..2e2079dc5 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -115,7 +115,7 @@ export class ApiService this.nodeConfig.kyveEndpoint, this.nodeConfig.kyveStorageUrl, this.nodeConfig.kyveChainId, - this.project.root, // TODO this wont work for local + this.project.fileCacheDir, ); } diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 2d1331c93..4fef4c640 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -255,8 +255,6 @@ export class KyveApi { .on('error', reject) .pipe(writeStream) .on('finish', resolve); - }).catch((e) => { - throw e; }); await fs.promises.chmod(bundleFilePath, 0o444); @@ -362,6 +360,12 @@ export class KyveApi { blockArray: number[], ): Promise<[BlockResponse, BlockResultsResponse][]> { // use for loop instead ? + // mem a promise + + // for loop resolve and get bundle for block, save a promise for bundle id + + // await promise in cache + // once bundle has been resolved return Promise.all( blockArray.map(async (height) => this.getBlockByHeight(height)), ); diff --git a/packages/node/src/utils/project.spec.ts b/packages/node/src/utils/project.spec.ts new file mode 100644 index 000000000..67e114dfa --- /dev/null +++ b/packages/node/src/utils/project.spec.ts @@ -0,0 +1,12 @@ +// Copyright 2020-2024 SubQuery Pte Ltd authors & contributors +// SPDX-License-Identifier: GPL-3.0 + +import { makeTempDir } from '@subql/common'; +import { isTmpDir } from './project'; + +describe('Project tests', () => { + it('ensure isTmpDir', async () => { + const tmpDir = await makeTempDir(); + expect(isTmpDir(tmpDir)).toBe(true); + }); +}); diff --git a/packages/node/src/utils/project.ts b/packages/node/src/utils/project.ts index c34302ada..00207a4bf 100644 --- a/packages/node/src/utils/project.ts +++ b/packages/node/src/utils/project.ts @@ -1,6 +1,7 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 +import os from 'os'; import { CosmosRuntimeHandler, CosmosCustomHandler, @@ -68,3 +69,10 @@ export async function loadNetworkChainType( return [packageName, root]; } + +export function isTmpDir(path: string): boolean { + const normalizedPath = path.replace(/\\/g, '/').toLowerCase(); + return normalizedPath.startsWith( + os.tmpdir().replace(/\\/g, '/').toLowerCase(), + ); +} From dd70d2106792d3e5e8d0a18ca1d5d45835239301 Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 15 Apr 2024 11:01:35 +0800 Subject: [PATCH 37/81] add listener on fetch block --- packages/node/src/indexer/api.service.ts | 9 ++++++++- packages/node/src/utils/kyve/kyve.ts | 5 ++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 2e2079dc5..877523800 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -117,6 +117,10 @@ export class ApiService this.nodeConfig.kyveChainId, this.project.fileCacheDir, ); + + this.eventEmitter.on('block_processing_height', (block) => { + console.log('block_processing_height', block); + }); } return this; @@ -129,7 +133,10 @@ export class ApiService ): Promise[]> { try { if (this.kyveApi) { - return this.kyveApi.fetchBlocksBatches(this.registry, heights); + const v = await this.kyveApi.fetchBlocksBatches(this.registry, heights); + // listen for processingblock, if it is + + return v; } else { throw new Error('No kyve connection'); } diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 4fef4c640..493ea8fe6 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -255,6 +255,8 @@ export class KyveApi { .on('error', reject) .pipe(writeStream) .on('finish', resolve); + }).catch((e) => { + throw e; // to ensure an on stack error is thrown }); await fs.promises.chmod(bundleFilePath, 0o444); @@ -281,7 +283,8 @@ export class KyveApi { } // todo unsure when to clear the file cache - private async clearFileCache(height: number): Promise { + async clearFileCache(height: number, clearBuffer: number): Promise { + // add listener const bundleToRemove = this.cachedBundleDetails.filter( (b) => parseDecimal(b.from_key) > height, ); From 34c8597c3d0435aa6b40626a5e3d9afc5435c781 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 16 Apr 2024 07:22:13 +0800 Subject: [PATCH 38/81] add listener for clear cache --- packages/node/src/indexer/api.service.test.ts | 62 +++++++++++++++---- packages/node/src/indexer/api.service.ts | 16 ++++- packages/node/src/utils/kyve/kyve.spec.ts | 62 ++++++++++++++----- packages/node/src/utils/kyve/kyve.ts | 41 +++++++++--- 4 files changed, 145 insertions(+), 36 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 3ce1fc889..ee5e747e7 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -1,6 +1,7 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 +import fs from 'fs'; import path from 'path'; import { toHex } from '@cosmjs/encoding'; import { Uint53 } from '@cosmjs/math'; @@ -8,23 +9,32 @@ import { toRfc3339WithNanoseconds } from '@cosmjs/tendermint-rpc'; import { INestApplication } from '@nestjs/common'; import { EventEmitter2, EventEmitterModule } from '@nestjs/event-emitter'; import { Test } from '@nestjs/testing'; -import { loadFromJsonOrYaml } from '@subql/common'; -import { ConnectionPoolService, delay, NodeConfig } from '@subql/node-core'; +import { loadFromJsonOrYaml, makeTempDir } from '@subql/common'; +import { + ConnectionPoolService, + ConnectionPoolStateManager, + delay, + NodeConfig, +} from '@subql/node-core'; import { GraphQLSchema } from 'graphql'; +import { CosmosNodeConfig } from '../configure/NodeConfig'; import { SubqueryProject } from '../configure/SubqueryProject'; import { ApiService } from './api.service'; -const ENDPOINT = 'https://rpc-juno.itastakers.com/'; -const CHAINID = 'juno-1'; - +// const ENDPOINT = 'https://rpc-juno.itastakers.com/'; +// const CHAINID = 'juno-1'; +// const TEST_BLOCKNUMBER = 3266772; +const ENDPOINT = 'https://rpc.mainnet.archway.io:443'; +const CHAINID = 'archway-1'; + const projectsDir = path.join(__dirname, '../../test'); -function testCosmosProject(): SubqueryProject { +function testCosmosProject(fileCacheDir?: string): SubqueryProject { return { network: { - endpoint: ENDPOINT, + endpoint: [ENDPOINT], chainId: CHAINID, }, dataSources: [], @@ -32,21 +42,26 @@ function testCosmosProject(): SubqueryProject { root: './', schema: new GraphQLSchema({}), templates: [], + fileCacheDir, } as SubqueryProject; } jest.setTimeout(200000); -describe.skip('ApiService', () => { +describe('ApiService', () => { let app: INestApplication; let apiService: ApiService; - const prepareApiService = async () => { + + let tmpPath: string; + + const prepareApiService = async (fileCacheDir: string) => { const module = await Test.createTestingModule({ providers: [ + ConnectionPoolStateManager, ConnectionPoolService, { provide: 'ISubqueryProject', - useFactory: () => testCosmosProject(), + useFactory: () => testCosmosProject(fileCacheDir), }, { provide: NodeConfig, @@ -61,13 +76,38 @@ describe.skip('ApiService', () => { app = module.createNestApplication(); await app.init(); apiService = app.get(ApiService); + (apiService as any).nodeConfig._config.kyveEndpoint = + 'https://api-us-1.kyve.network'; + (apiService as any).nodeConfig._config.kyveStorageUrl = + 'https://arweave.net'; await apiService.init(); }; beforeAll(async () => { - await prepareApiService(); + tmpPath = await makeTempDir(); + await prepareApiService(tmpPath); }); + it('kyve api clear cache', async () => { + // const bundles = [ + // {id: '0', from_key: '1', to_key: '150'}, + // {id: '1', from_key: '151', to_key: '300'}, + // {id: '2', from_key: '301', to_key: '500'}, + // {id: '3', from_key: '501', to_key: '800'}, + // ] + // mock bundle values + const heights = [150, 300, 1, 301, 450, 550]; + const blockArr = await Promise.all([ + apiService.fetchBlocks(heights), + apiService.fetchBlocks(heights), + ]); + + console.log(((apiService as any).kyveApi as any).cachedBundleDetails); + const files = await fs.promises.readdir(tmpPath); + // expect files to be [bundle_1.json, bundle_2, bundle_3.json] + // clear cache should be called n times + // created bundles + }); it('query block info', async () => { const api = apiService.api; const blockInfo = await api.blockInfo(TEST_BLOCKNUMBER); diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 877523800..0e00d4486 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -118,14 +118,24 @@ export class ApiService this.project.fileCacheDir, ); - this.eventEmitter.on('block_processing_height', (block) => { - console.log('block_processing_height', block); - }); + this.clearKyveCacheListener((block: { height: number }) => + this.kyveApi.clearFileCache(block.height), + ); } return this; } + clearKyveCacheListener( + callback: (block: { height: number }) => void | Promise, + ): void { + this.eventEmitter.on( + 'block_processing_height', + callback as (block: { height: number }) => void, + { async: true }, + ); + } + // Overrides the super function because of the kyve integration async fetchBlocks( heights: number[], diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index f24c7aead..e6560e93b 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -16,6 +16,7 @@ import { } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; import KyveSDK from '@kyvejs/sdk'; import { makeTempDir } from '@subql/common'; +import axios from 'axios'; import { MsgClearAdmin, MsgExecuteContract, @@ -78,14 +79,14 @@ describe('KyveApi', () => { ); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); - + }); + beforeEach(() => { retrieveBundleDataSpy = jest.spyOn(kyveApi as any, 'retrieveBundleData'); decoderBlockSpy = jest.spyOn(kyveApi as any, 'decodeBlock'); decoderBlockResultsSpy = jest.spyOn(kyveApi as any, 'decodeBlockResult'); injectLogSpy = jest.spyOn(kyveApi as any, 'injectLogs'); readerSpy = jest.spyOn(kyveApi as any, 'readFromFile'); - }); - beforeEach(() => { + zippedMockResp = gzipSync(Buffer.from(JSON.stringify(block_3856726))); mockStream = new Readable({ read() { @@ -280,6 +281,29 @@ describe('KyveApi', () => { (kyveApi as any).cachedBundleDetails.find((b) => b.id === '1'), ).toBeDefined(); }); + it('find lowest out of range bundleId', () => { + const bundles = [ + { id: '0', from_key: '1', to_key: '150' }, + { id: '1', from_key: '151', to_key: '300' }, + { id: '2', from_key: '301', to_key: '500' }, + { id: '3', from_key: '501', to_key: '800' }, + ]; + + const height = 450; + + const v = bundles.filter((bundle) => { + const toKey = parseInt(bundle.to_key, 10); + return toKey < height; + }); + const r = bundles.find( + (c) => height >= parseInt(c.from_key) && height <= parseInt(c.to_key), + ); + const toRemoveBundle = bundles.find( + (bun) => parseInt(bun.id) <= parseInt(r.id) - 2, + ); + + console.log(toRemoveBundle); + }); it('compare block info', async () => { const height = 3901476; const tendermintBlockInfo = await tendermint.block(height); @@ -295,7 +319,12 @@ describe('KyveApi', () => { expect(poolId).toBe('2'); }); - it('clear cache file when height exceeds bundle max', async () => { + it('clear cache file when height exceeds bundle', async () => { + // mock three bundle.json 0, 1 , 2 + // when clearFileCache is called + // expect bundle 0 to be removed + + // the data doesnt really matter, as it clears based on cached bundles const checkFileExist = async (filePath: string) => { try { await fs.promises.access(filePath); @@ -318,21 +347,25 @@ describe('KyveApi', () => { return Promise.resolve(JSON.stringify(block_3856726)); }); - await kyveApi.getBlockByHeight(3856726); - expect((kyveApi as any).cachedBundleDetails).not.toBe('0'); - - await expect( - checkFileExist(path.join(tmpPath, 'bundle_130263')), - ).resolves.toBe(false); + // await kyveApi.getBlockByHeight(3856726); + // expect((kyveApi as any).cachedBundleDetails).not.toBe('0'); + // + // await expect( + // checkFileExist(path.join(tmpPath, 'bundle_130263')), + // ).resolves.toBe(false); expect(clearFileSpy).toHaveBeenCalledTimes(1); }); it('remove bundle.json if bundle fetch fails', async () => { - const bundleDetail = await (kyveApi as any).getBundleById(1); + const bundleDetail = await (kyveApi as any).getBundleById(8); (kyveApi as any).cachedBundleDetails = [bundleDetail]; + jest.spyOn(axios, 'isAxiosError').mockImplementationOnce(() => true); + retrieveBundleDataSpy.mockImplementation(() => { return new Promise((resolve, reject) => { - reject('failed to fetch'); + reject({ + response: 'err', + }); }); }); @@ -340,9 +373,8 @@ describe('KyveApi', () => { (kyveApi as any).getFileCacheData(bundleDetail), ).rejects.toBeDefined(); - await expect( - fs.promises.stat((kyveApi as any).getBundleFilePath(bundleDetail.id)), - ).rejects.toThrow('no such file or directory'); + const files = await fs.promises.readdir(tmpPath); + expect(files.length).toBe(0); }); it('Able to poll with simulated workers', async () => { const bundleDetail = await (kyveApi as any).getBundleById(130265); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 493ea8fe6..bdccaeeeb 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -18,6 +18,7 @@ import { SupportedChains } from '@kyvejs/sdk/src/constants'; // Currently these import { QueryPoolsResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; import { delay, getLogger, IBlock } from '@subql/node-core'; import axios, { AxiosResponse } from 'axios'; +import { remove } from 'lodash'; import { BlockContent } from '../../indexer/types'; import { formatBlockUtil, LazyBlockContent } from '../cosmos'; import { BundleDetails } from './kyveTypes'; @@ -272,7 +273,10 @@ export class KyveApi { if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { return this.pollUntilReadable(bundleFilePath); } else { - await fs.promises.unlink(bundleFilePath); + if (axios.isAxiosError(e)) { + await fs.promises.unlink(bundleFilePath); + } + throw e; } } @@ -283,16 +287,39 @@ export class KyveApi { } // todo unsure when to clear the file cache - async clearFileCache(height: number, clearBuffer: number): Promise { - // add listener - const bundleToRemove = this.cachedBundleDetails.filter( - (b) => parseDecimal(b.from_key) > height, + async clearFileCache(height: number): Promise { + console.log(this); + const bundles = this.cachedBundleDetails.filter( + (b) => parseDecimal(b.to_key) < height, + ); + const r = this.cachedBundleDetails.find( + (c) => + height >= parseDecimal(c.from_key) && height <= parseDecimal(c.to_key), ); - for (const bundle of bundleToRemove) { - const bundlePath = this.getBundleFilePath(bundle.id); + const toRemoveBundle = bundles.find( + (bun) => parseDecimal(bun.id) <= parseDecimal(r.id) - 2, + ); + + if (!toRemoveBundle) { + console.log('bundle not found', height); + console.log('bundle not found cache', this.cachedBundleDetails.length); + return; + } + + const bundlePath = this.getBundleFilePath(toRemoveBundle.id); + try { await fs.promises.unlink(bundlePath); + remove(this.cachedBundleDetails, (b) => b.id === toRemoveBundle.id); + console.log('cache after removal', this.cachedBundleDetails.length); + } catch (e) { + if (e.code === 'ENOENT') { + console.error(e); + } else { + throw e; + } } + console.log('removed bundle id:', toRemoveBundle, 'at', height); } async getBlockByHeight( From 510f70be5e5094f68f892268c956611888186d22 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 16 Apr 2024 07:58:43 +0800 Subject: [PATCH 39/81] fix removal bundle on failed fetch test --- packages/node/src/indexer/api.service.test.ts | 141 ++++++++++-------- packages/node/src/utils/kyve/kyve.spec.ts | 43 +----- 2 files changed, 86 insertions(+), 98 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index ee5e747e7..12c89ccb9 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -21,21 +21,19 @@ import { CosmosNodeConfig } from '../configure/NodeConfig'; import { SubqueryProject } from '../configure/SubqueryProject'; import { ApiService } from './api.service'; -// const ENDPOINT = 'https://rpc-juno.itastakers.com/'; -// const CHAINID = 'juno-1'; -// const TEST_BLOCKNUMBER = 3266772; -const ENDPOINT = 'https://rpc.mainnet.archway.io:443'; -const CHAINID = 'archway-1'; - const projectsDir = path.join(__dirname, '../../test'); -function testCosmosProject(fileCacheDir?: string): SubqueryProject { +function testCosmosProject( + endpoint: string, + chainId: string, + fileCacheDir?: string, +): SubqueryProject { return { network: { - endpoint: [ENDPOINT], - chainId: CHAINID, + endpoint: [endpoint], + chainId: chainId, }, dataSources: [], id: 'test', @@ -54,14 +52,19 @@ describe('ApiService', () => { let tmpPath: string; - const prepareApiService = async (fileCacheDir: string) => { + const prepareApiService = async ( + endpoint: string, + chainId: string, + kyve: boolean, + fileCacheDir?: string, + ) => { const module = await Test.createTestingModule({ providers: [ ConnectionPoolStateManager, ConnectionPoolService, { provide: 'ISubqueryProject', - useFactory: () => testCosmosProject(fileCacheDir), + useFactory: () => testCosmosProject(endpoint, chainId, fileCacheDir), }, { provide: NodeConfig, @@ -76,63 +79,79 @@ describe('ApiService', () => { app = module.createNestApplication(); await app.init(); apiService = app.get(ApiService); - (apiService as any).nodeConfig._config.kyveEndpoint = - 'https://api-us-1.kyve.network'; - (apiService as any).nodeConfig._config.kyveStorageUrl = - 'https://arweave.net'; + if (kyve) { + (apiService as any).nodeConfig._config.kyveEndpoint = + 'https://api-us-1.kyve.network'; + (apiService as any).nodeConfig._config.kyveStorageUrl = + 'https://arweave.net'; + } await apiService.init(); }; - beforeAll(async () => { - tmpPath = await makeTempDir(); - await prepareApiService(tmpPath); - }); - it('kyve api clear cache', async () => { - // const bundles = [ - // {id: '0', from_key: '1', to_key: '150'}, - // {id: '1', from_key: '151', to_key: '300'}, - // {id: '2', from_key: '301', to_key: '500'}, - // {id: '3', from_key: '501', to_key: '800'}, - // ] - // mock bundle values - const heights = [150, 300, 1, 301, 450, 550]; - const blockArr = await Promise.all([ - apiService.fetchBlocks(heights), - apiService.fetchBlocks(heights), - ]); + describe('KYVE Api service', () => { + beforeAll(async () => { + const ENDPOINT = 'https://rpc.mainnet.archway.io:443'; + const CHAINID = 'archway-1'; + + tmpPath = await makeTempDir(); + await prepareApiService(ENDPOINT, CHAINID, true, tmpPath); + }); - console.log(((apiService as any).kyveApi as any).cachedBundleDetails); - const files = await fs.promises.readdir(tmpPath); - // expect files to be [bundle_1.json, bundle_2, bundle_3.json] - // clear cache should be called n times + it('kyve api clear cache', async () => { + // const bundles = [ + // {id: '0', from_key: '1', to_key: '150'}, + // {id: '1', from_key: '151', to_key: '300'}, + // {id: '2', from_key: '301', to_key: '500'}, + // {id: '3', from_key: '501', to_key: '800'}, + // ] + // mock bundle values + const heights = [150, 300, 1, 301, 450, 550]; + const blockArr = await Promise.all([ + apiService.fetchBlocks(heights), + apiService.fetchBlocks(heights), + ]); - // created bundles + console.log(((apiService as any).kyveApi as any).cachedBundleDetails); + const files = await fs.promises.readdir(tmpPath); + // expect files to be [bundle_1.json, bundle_2, bundle_3.json] + // clear cache should be called n times + + // created bundles + }); }); - it('query block info', async () => { - const api = apiService.api; - const blockInfo = await api.blockInfo(TEST_BLOCKNUMBER); - const doc: any = loadFromJsonOrYaml( - path.join(projectsDir, 'block_3266772.json'), - ); - const realBlockInfo = { - id: toHex(doc.block_id.hash).toUpperCase(), - header: { - version: { - block: new Uint53(+doc.block.header.version.block).toString(), - app: blockInfo.block.header.version.app, + describe.skip('RPC api service', () => { + beforeAll(async () => { + const ENDPOINT = 'https://rpc-juno.itastakers.com/'; + const CHAINID = 'juno-1'; + + await prepareApiService(ENDPOINT, CHAINID, false); + }); + it('query block info', async () => { + const api = apiService.api; + const blockInfo = await api.blockInfo(TEST_BLOCKNUMBER); + const doc: any = loadFromJsonOrYaml( + path.join(projectsDir, 'block_3266772.json'), + ); + const realBlockInfo = { + id: toHex(doc.block_id.hash).toUpperCase(), + header: { + version: { + block: new Uint53(+doc.block.header.version.block).toString(), + app: blockInfo.block.header.version.app, + }, + height: doc.block.header.height, + chainId: doc.block.header.chainId, + time: toRfc3339WithNanoseconds(doc.block.header.time), }, - height: doc.block.header.height, - chainId: doc.block.header.chainId, - time: toRfc3339WithNanoseconds(doc.block.header.time), - }, - txs: doc.block.txs, - }; - expect(blockInfo).toMatchObject(realBlockInfo); - }); + txs: doc.block.txs, + }; + expect(blockInfo).toMatchObject(realBlockInfo); + }); - it('query tx info by height', async () => { - const api = apiService.api; - const txInfos = await api.txInfoByHeight(TEST_BLOCKNUMBER); - expect(txInfos.length).toEqual(4); + it('query tx info by height', async () => { + const api = apiService.api; + const txInfos = await api.txInfoByHeight(TEST_BLOCKNUMBER); + expect(txInfos.length).toEqual(4); + }); }); }); diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index e6560e93b..11dcfa1f4 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -80,7 +80,7 @@ describe('KyveApi', () => { const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); }); - beforeEach(() => { + beforeEach(async () => { retrieveBundleDataSpy = jest.spyOn(kyveApi as any, 'retrieveBundleData'); decoderBlockSpy = jest.spyOn(kyveApi as any, 'decodeBlock'); decoderBlockResultsSpy = jest.spyOn(kyveApi as any, 'decodeBlockResult'); @@ -94,6 +94,11 @@ describe('KyveApi', () => { this.push(null); }, }); + + const files = await fs.promises.readdir(tmpPath); + for (const file of files) { + await fs.promises.unlink(path.join(tmpPath, file)); + } }); afterEach(() => { @@ -319,42 +324,6 @@ describe('KyveApi', () => { expect(poolId).toBe('2'); }); - it('clear cache file when height exceeds bundle', async () => { - // mock three bundle.json 0, 1 , 2 - // when clearFileCache is called - // expect bundle 0 to be removed - - // the data doesnt really matter, as it clears based on cached bundles - const checkFileExist = async (filePath: string) => { - try { - await fs.promises.access(filePath); - return true; - } catch (e) { - return false; - } - }; - - await fs.promises.writeFile(path.join(tmpPath, 'bundle_130263'), 'mock'); // should be removed - await fs.promises.writeFile(path.join(tmpPath, 'bundle_130264'), 'mock'); - - retrieveBundleDataSpy.mockImplementation(() => { - return { data: mockStream }; - }); - - const clearFileSpy = jest.spyOn(kyveApi as any, 'clearFileCache'); - - readerSpy.mockImplementation(() => { - return Promise.resolve(JSON.stringify(block_3856726)); - }); - - // await kyveApi.getBlockByHeight(3856726); - // expect((kyveApi as any).cachedBundleDetails).not.toBe('0'); - // - // await expect( - // checkFileExist(path.join(tmpPath, 'bundle_130263')), - // ).resolves.toBe(false); - expect(clearFileSpy).toHaveBeenCalledTimes(1); - }); it('remove bundle.json if bundle fetch fails', async () => { const bundleDetail = await (kyveApi as any).getBundleById(8); (kyveApi as any).cachedBundleDetails = [bundleDetail]; From 6d0f85a2231d7a125fc964b22efe55155f7327da Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 16 Apr 2024 14:55:06 +0800 Subject: [PATCH 40/81] update clear cache, added test --- packages/node/src/indexer/api.service.test.ts | 2 +- packages/node/src/indexer/api.service.ts | 26 +++---- packages/node/src/utils/kyve/kyve.spec.ts | 69 ++++++++++-------- packages/node/src/utils/kyve/kyve.ts | 70 ++++++++++++------- 4 files changed, 97 insertions(+), 70 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 12c89ccb9..3d21305cb 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -108,7 +108,7 @@ describe('ApiService', () => { const heights = [150, 300, 1, 301, 450, 550]; const blockArr = await Promise.all([ apiService.fetchBlocks(heights), - apiService.fetchBlocks(heights), + // apiService.fetchBlocks(heights), ]); console.log(((apiService as any).kyveApi as any).cachedBundleDetails); diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 0e00d4486..5df1b6c91 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -117,25 +117,11 @@ export class ApiService this.nodeConfig.kyveChainId, this.project.fileCacheDir, ); - - this.clearKyveCacheListener((block: { height: number }) => - this.kyveApi.clearFileCache(block.height), - ); } return this; } - clearKyveCacheListener( - callback: (block: { height: number }) => void | Promise, - ): void { - this.eventEmitter.on( - 'block_processing_height', - callback as (block: { height: number }) => void, - { async: true }, - ); - } - // Overrides the super function because of the kyve integration async fetchBlocks( heights: number[], @@ -143,10 +129,16 @@ export class ApiService ): Promise[]> { try { if (this.kyveApi) { - const v = await this.kyveApi.fetchBlocksBatches(this.registry, heights); - // listen for processingblock, if it is + // batchSize + // this.nodeConfig.batchSize + const bufferSize = 100; + return this.kyveApi.fetchBlocksBatches( + this.registry, + heights, + bufferSize, + ); - return v; + // delete only happens when nothing else is reading from } else { throw new Error('No kyve connection'); } diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 11dcfa1f4..faac5d903 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -30,6 +30,7 @@ import rimraf from 'rimraf'; import { HttpClient } from '../../indexer/rpc-clients'; import { LazyBlockContent } from '../cosmos'; import { KyveApi } from './kyve'; +import { BundleDetails } from './kyveTypes'; const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ ['/cosmwasm.wasm.v1.MsgClearAdmin', MsgClearAdmin], @@ -103,7 +104,6 @@ describe('KyveApi', () => { afterEach(() => { retrieveBundleDataSpy.mockRestore(); - decoderBlockSpy.mockRestore(); decoderBlockResultsSpy.mockRestore(); injectLogSpy.mockRestore(); @@ -286,29 +286,6 @@ describe('KyveApi', () => { (kyveApi as any).cachedBundleDetails.find((b) => b.id === '1'), ).toBeDefined(); }); - it('find lowest out of range bundleId', () => { - const bundles = [ - { id: '0', from_key: '1', to_key: '150' }, - { id: '1', from_key: '151', to_key: '300' }, - { id: '2', from_key: '301', to_key: '500' }, - { id: '3', from_key: '501', to_key: '800' }, - ]; - - const height = 450; - - const v = bundles.filter((bundle) => { - const toKey = parseInt(bundle.to_key, 10); - return toKey < height; - }); - const r = bundles.find( - (c) => height >= parseInt(c.from_key) && height <= parseInt(c.to_key), - ); - const toRemoveBundle = bundles.find( - (bun) => parseInt(bun.id) <= parseInt(r.id) - 2, - ); - - console.log(toRemoveBundle); - }); it('compare block info', async () => { const height = 3901476; const tendermintBlockInfo = await tendermint.block(height); @@ -345,6 +322,42 @@ describe('KyveApi', () => { const files = await fs.promises.readdir(tmpPath); expect(files.length).toBe(0); }); + it('remove cached bundle files when past height', async () => { + await kyveApi.fetchBlocksBatches(registry, [1, 151, 301, 501], 300); + const files = await fs.promises.readdir(tmpPath); + + await kyveApi.fetchBlocksBatches(registry, [502, 504, 600, 800], 300); + + console.log(files); + expect(files).not.toContain('bundle_0.json'); + expect(files).not.toContain('bundle_1.json'); + expect(files).not.toContain('bundle_2.json'); + }); + it('ensure to remove logic', () => { + const cachedBundleDetails = [ + { id: '0', from_key: '1', to_key: '150' }, + { id: '1', from_key: '151', to_key: '300' }, + { id: '2', from_key: '301', to_key: '500' }, + { id: '3', from_key: '501', to_key: '800' }, + ] as BundleDetails[]; + (kyveApi as any).cachedBundleDetails = cachedBundleDetails; + + const height = 650; + const bufferSize = 300; + + const toRemoveBundles = (kyveApi as any).getToRemoveBundles( + cachedBundleDetails, + height, + bufferSize, + ); + + expect(toRemoveBundles.sort()).toEqual( + [ + { id: '0', from_key: '1', to_key: '150' }, + { id: '1', from_key: '151', to_key: '300' }, + ].sort(), + ); + }); it('Able to poll with simulated workers', async () => { const bundleDetail = await (kyveApi as any).getBundleById(130265); (kyveApi as any).cachedBundleDetails = [bundleDetail]; @@ -355,10 +368,10 @@ describe('KyveApi', () => { const pollSpy = jest.spyOn(kyveApi as any, 'pollUntilReadable'); await Promise.all([ - kyveApi.fetchBlocksBatches(registry, [3856726]), - kyveApi.fetchBlocksBatches(registry, [3856726]), - kyveApi.fetchBlocksBatches(registry, [3856726]), - kyveApi.fetchBlocksBatches(registry, [3856726]), + kyveApi.fetchBlocksBatches(registry, [3856726], 1), + kyveApi.fetchBlocksBatches(registry, [3856726], 1), + kyveApi.fetchBlocksBatches(registry, [3856726], 1), + kyveApi.fetchBlocksBatches(registry, [3856726], 1), ]); expect(pollSpy).toHaveBeenCalledTimes(3); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index bdccaeeeb..a99470d7e 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -286,40 +286,57 @@ export class KyveApi { return fs.promises.readFile(bundleFilePath, 'utf-8'); } - // todo unsure when to clear the file cache - async clearFileCache(height: number): Promise { - console.log(this); - const bundles = this.cachedBundleDetails.filter( - (b) => parseDecimal(b.to_key) < height, - ); - const r = this.cachedBundleDetails.find( - (c) => - height >= parseDecimal(c.from_key) && height <= parseDecimal(c.to_key), - ); + private getToRemoveBundles( + cachedBundles: BundleDetails[], + height: number, + bufferSize: number, + ): BundleDetails[] { + const currentBundle = this.getBundleFromCache(height); + + return cachedBundles.filter((b) => { + const isNotCurrentBundleAndLower = + currentBundle.id !== b.id && + parseDecimal(currentBundle.id) > parseDecimal(b.id); + const isOutsiderBuffer = + height < parseDecimal(b.from_key) - bufferSize || + height > parseDecimal(b.to_key) + bufferSize; + + return isNotCurrentBundleAndLower && isOutsiderBuffer; + }); + } - const toRemoveBundle = bundles.find( - (bun) => parseDecimal(bun.id) <= parseDecimal(r.id) - 2, + async clearFileCache( + cachedBundles: BundleDetails[], + height: number, + bufferSize: number, + ): Promise { + const toRemoveBundles = this.getToRemoveBundles( + cachedBundles, + height, + bufferSize, ); - if (!toRemoveBundle) { + if (toRemoveBundles.length) { console.log('bundle not found', height); console.log('bundle not found cache', this.cachedBundleDetails.length); return; } - const bundlePath = this.getBundleFilePath(toRemoveBundle.id); - try { - await fs.promises.unlink(bundlePath); - remove(this.cachedBundleDetails, (b) => b.id === toRemoveBundle.id); - console.log('cache after removal', this.cachedBundleDetails.length); - } catch (e) { - if (e.code === 'ENOENT') { - console.error(e); - } else { - throw e; + for (const bundle of toRemoveBundles) { + const bundlePath = this.getBundleFilePath(bundle.id); + try { + await fs.promises.unlink(bundlePath); + remove(this.cachedBundleDetails, (b) => b.id === bundle.id); + console.log('cache after removal', this.cachedBundleDetails.length); + } catch (e) { + if (e.code === 'ENOENT') { + console.error(e); + } else { + throw e; + } } + console.log('removed bundle id:', bundle.id, 'at', height); } - console.log('removed bundle id:', toRemoveBundle, 'at', height); } async getBlockByHeight( @@ -419,8 +436,13 @@ export class KyveApi { async fetchBlocksBatches( registry: Registry, blockArray: number[], + bufferSize: number, ): Promise[]> { const blocks = await this.fetchBlocksArray(blockArray); + const minHeight = Math.min(...blockArray); + + await this.clearFileCache(this.cachedBundleDetails, minHeight, bufferSize); + return blocks.map(([blockInfo, blockResults]) => { try { assert( From 0178985017cf5399a6e10c861cd00cad04b3e552 Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Tue, 16 Apr 2024 07:47:44 +0000 Subject: [PATCH 41/81] ensure working tests on cache file removal --- packages/node/src/utils/kyve/kyve.spec.ts | 6 +----- packages/node/src/utils/kyve/kyve.ts | 7 ++----- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index faac5d903..da2d9f1a9 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -324,14 +324,10 @@ describe('KyveApi', () => { }); it('remove cached bundle files when past height', async () => { await kyveApi.fetchBlocksBatches(registry, [1, 151, 301, 501], 300); - const files = await fs.promises.readdir(tmpPath); - await kyveApi.fetchBlocksBatches(registry, [502, 504, 600, 800], 300); - console.log(files); + const files = await fs.promises.readdir(tmpPath); expect(files).not.toContain('bundle_0.json'); - expect(files).not.toContain('bundle_1.json'); - expect(files).not.toContain('bundle_2.json'); }); it('ensure to remove logic', () => { const cachedBundleDetails = [ diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index a99470d7e..e34361538 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -316,9 +316,7 @@ export class KyveApi { bufferSize, ); - if (toRemoveBundles.length) { - console.log('bundle not found', height); - console.log('bundle not found cache', this.cachedBundleDetails.length); + if (!toRemoveBundles.length) { return; } @@ -327,7 +325,6 @@ export class KyveApi { try { await fs.promises.unlink(bundlePath); remove(this.cachedBundleDetails, (b) => b.id === bundle.id); - console.log('cache after removal', this.cachedBundleDetails.length); } catch (e) { if (e.code === 'ENOENT') { console.error(e); @@ -361,7 +358,7 @@ export class KyveApi { (b.log as any) = JSON.stringify(this.reconstructLogs(kyveBlockResult)); }); } catch (e) { - throw new Error(`Failed to inject kyveBlock`); + throw new Error(`Failed to inject kyveBlock, ${e}`); } return kyveBlockResult; } From 39d43180d5230a9d06c23b3e2bda636f2580c649 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 16 Apr 2024 22:36:28 +0800 Subject: [PATCH 42/81] add fetch cache on bundles --- packages/node/src/indexer/api.service.test.ts | 17 +++++++-- packages/node/src/utils/kyve/kyve.spec.ts | 1 + packages/node/src/utils/kyve/kyve.ts | 37 +++++++++++-------- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 3d21305cb..dd460ba96 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -97,7 +97,7 @@ describe('ApiService', () => { await prepareApiService(ENDPOINT, CHAINID, true, tmpPath); }); - it('kyve api clear cache', async () => { + it('Able to fetch with cached promises', async () => { // const bundles = [ // {id: '0', from_key: '1', to_key: '150'}, // {id: '1', from_key: '151', to_key: '300'}, @@ -105,13 +105,22 @@ describe('ApiService', () => { // {id: '3', from_key: '501', to_key: '800'}, // ] // mock bundle values - const heights = [150, 300, 1, 301, 450, 550]; + // add the cache + // cacheBundle should be working on init + + // able to pull blocks + // standard incrementing blocks and bundle id + const heights_1 = [150, 300, 1, 301, 450, 550]; + + // fetch from a bundle id prior to latest + const heights_2 = [498, 600, 801, 1100]; const blockArr = await Promise.all([ - apiService.fetchBlocks(heights), + apiService.fetchBlocks(heights_1), + apiService.fetchBlocks(heights_2), // apiService.fetchBlocks(heights), ]); - console.log(((apiService as any).kyveApi as any).cachedBundleDetails); + console.log(blockArr.length); const files = await fs.promises.readdir(tmpPath); // expect files to be [bundle_1.json, bundle_2, bundle_3.json] // clear cache should be called n times diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index da2d9f1a9..43dcc111a 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -328,6 +328,7 @@ describe('KyveApi', () => { const files = await fs.promises.readdir(tmpPath); expect(files).not.toContain('bundle_0.json'); + expect((kyveApi as any).cachedBundleDetails.length).toBe(4); }); it('ensure to remove logic', () => { const cachedBundleDetails = [ diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index e34361538..3b321080e 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -41,6 +41,7 @@ interface KyveBundleData { export class KyveApi { private cachedBundleDetails: BundleDetails[] = []; + private fetchingBundles: Record> = {}; private constructor( private readonly storageUrl: string, @@ -193,12 +194,6 @@ export class KyveApi { private async updateCurrentBundleAndDetails( height: number, ): Promise { - if (this.cachedBundleDetails.length === 0) { - const bundleId = await this.getBundleId(height); - const bundleDetail = await this.getBundleById(bundleId); - this.addToCachedBundle(bundleDetail); - } - const bundle = this.getBundleFromCache(height); if (bundle) { return JSON.parse(await this.getFileCacheData(bundle)); @@ -339,9 +334,10 @@ export class KyveApi { async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { - const blocks = await this.updateCurrentBundleAndDetails(height); - + const blocks = await this.fetchBundleCached(height); + console.log('blocks', blocks.length); const blockData = this.findBlockByHeight(height, blocks); + console.log('block data', !!blockData); return [ this.decodeBlock(blockData.value.block), @@ -400,16 +396,27 @@ export class KyveApi { return logs; } + async fetchBundleCached(height: number): Promise { + let bundle = this.getBundleFromCache(height); + + if (!bundle) { + const bundleId = await this.getBundleId(height); + + bundle = await this.getBundleById(bundleId); + this.addToCachedBundle(bundle); + } + + // eslint-disable-next-line @typescript-eslint/no-misused-promises + if (!this.fetchingBundles[bundle.id]) { + this.fetchingBundles[bundle.id] = + this.updateCurrentBundleAndDetails(height); + } + return this.fetchingBundles[bundle.id]; + } + private async fetchBlocksArray( blockArray: number[], ): Promise<[BlockResponse, BlockResultsResponse][]> { - // use for loop instead ? - // mem a promise - - // for loop resolve and get bundle for block, save a promise for bundle id - - // await promise in cache - // once bundle has been resolved return Promise.all( blockArray.map(async (height) => this.getBlockByHeight(height)), ); From e802860be616ccab2ab5e3b50e78f4cac4a5cbb7 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 16 Apr 2024 23:22:13 +0800 Subject: [PATCH 43/81] update tests with correct values and fixes --- packages/node/src/indexer/api.service.test.ts | 10 ++--- packages/node/src/utils/kyve/kyve.spec.ts | 44 ++++++++++++++----- packages/node/src/utils/kyve/kyve.ts | 3 -- 3 files changed, 36 insertions(+), 21 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index dd460ba96..6ad9b0616 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -117,15 +117,13 @@ describe('ApiService', () => { const blockArr = await Promise.all([ apiService.fetchBlocks(heights_1), apiService.fetchBlocks(heights_2), - // apiService.fetchBlocks(heights), ]); - console.log(blockArr.length); + blockArr.forEach((b) => { + console.log(b[0].block.block.blockId); + }); const files = await fs.promises.readdir(tmpPath); - // expect files to be [bundle_1.json, bundle_2, bundle_3.json] - // clear cache should be called n times - - // created bundles + console.log(files); }); }); describe.skip('RPC api service', () => { diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 43dcc111a..b8a67ad45 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -16,6 +16,7 @@ import { } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; import KyveSDK from '@kyvejs/sdk'; import { makeTempDir } from '@subql/common'; +import { delay } from '@subql/node-core'; import axios from 'axios'; import { MsgClearAdmin, @@ -237,12 +238,6 @@ describe('KyveApi', () => { (kyveBlockResult: BlockResultsResponse) => kyveBlockResult, ); - // TODO, should this be called with promise.all or for loop ? - // for (const height of [1, 151, 151, 300, 301]) { - // await kyveApi.getBlockByHeight(height) - // } - // expect download to be called multiple times - const blocks = await Promise.all([ kyveApi.getBlockByHeight(1), kyveApi.getBlockByHeight(151), @@ -253,6 +248,7 @@ describe('KyveApi', () => { const cachedBundles = await fs.promises.readdir(tmpPath); expect(cachedBundles.length).toBe(3); + expect(blocks.length).toBe(5); for (const bundle of (kyveApi as any).cachedBundleDetails) { const stats = await fs.promises.stat( @@ -359,19 +355,43 @@ describe('KyveApi', () => { const bundleDetail = await (kyveApi as any).getBundleById(130265); (kyveApi as any).cachedBundleDetails = [bundleDetail]; - retrieveBundleDataSpy.mockImplementation(() => { + const workerKyveApi = await KyveApi.create( + 'archway-1', + KYVE_ENDPOINT, + KYVE_STORAGE_URL, + KYVE_CHAINID, + tmpPath, + ); + + (workerKyveApi as any).cachedBundleDetails = [bundleDetail]; + + jest + .spyOn(workerKyveApi, 'downloadAndProcessBundle') + .mockImplementation(async (bundle: BundleDetails) => { + await delay(2); + return kyveApi.downloadAndProcessBundle(bundle); + }); + + jest + .spyOn(workerKyveApi as any, 'retrieveBundleData') + .mockImplementation(async () => { + await delay(4); + return { data: mockStream }; + }); + + retrieveBundleDataSpy.mockImplementation(async () => { + await delay(3); return { data: mockStream }; }); - const pollSpy = jest.spyOn(kyveApi as any, 'pollUntilReadable'); + const pollSpy = jest.spyOn(workerKyveApi as any, 'pollUntilReadable'); await Promise.all([ kyveApi.fetchBlocksBatches(registry, [3856726], 1), - kyveApi.fetchBlocksBatches(registry, [3856726], 1), - kyveApi.fetchBlocksBatches(registry, [3856726], 1), - kyveApi.fetchBlocksBatches(registry, [3856726], 1), + workerKyveApi.fetchBlocksBatches(registry, [3856726], 1), ]); - expect(pollSpy).toHaveBeenCalledTimes(3); + console.log(tmpPath); + expect(pollSpy).toHaveBeenCalledTimes(1); const r = await kyveApi.readFromFile( (kyveApi as any).getBundleFilePath(bundleDetail.id), diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 3b321080e..79014db47 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -335,9 +335,7 @@ export class KyveApi { height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { const blocks = await this.fetchBundleCached(height); - console.log('blocks', blocks.length); const blockData = this.findBlockByHeight(height, blocks); - console.log('block data', !!blockData); return [ this.decodeBlock(blockData.value.block), @@ -401,7 +399,6 @@ export class KyveApi { if (!bundle) { const bundleId = await this.getBundleId(height); - bundle = await this.getBundleById(bundleId); this.addToCachedBundle(bundle); } From f0d305135e37dc0e009ade273357ad593193f816 Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 17 Apr 2024 00:02:28 +0800 Subject: [PATCH 44/81] update tests --- packages/node/src/indexer/api.service.test.ts | 26 +++++++------------ packages/node/src/utils/kyve/kyve.spec.ts | 9 ------- packages/node/src/utils/kyve/kyve.ts | 7 +++-- 3 files changed, 12 insertions(+), 30 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 6ad9b0616..0932683f2 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -19,6 +19,7 @@ import { import { GraphQLSchema } from 'graphql'; import { CosmosNodeConfig } from '../configure/NodeConfig'; import { SubqueryProject } from '../configure/SubqueryProject'; +import { LazyBlockContent } from '../utils/cosmos'; import { ApiService } from './api.service'; const TEST_BLOCKNUMBER = 3266772; @@ -97,33 +98,24 @@ describe('ApiService', () => { await prepareApiService(ENDPOINT, CHAINID, true, tmpPath); }); - it('Able to fetch with cached promises', async () => { - // const bundles = [ - // {id: '0', from_key: '1', to_key: '150'}, - // {id: '1', from_key: '151', to_key: '300'}, - // {id: '2', from_key: '301', to_key: '500'}, - // {id: '3', from_key: '501', to_key: '800'}, - // ] - // mock bundle values - // add the cache - // cacheBundle should be working on init - - // able to pull blocks - // standard incrementing blocks and bundle id + it('Able to fetch with cached promises and remove cached bundle files', async () => { const heights_1 = [150, 300, 1, 301, 450, 550]; - // fetch from a bundle id prior to latest const heights_2 = [498, 600, 801, 1100]; const blockArr = await Promise.all([ apiService.fetchBlocks(heights_1), apiService.fetchBlocks(heights_2), ]); - blockArr.forEach((b) => { - console.log(b[0].block.block.blockId); + blockArr.forEach((blockContent) => { + blockContent.forEach((b) => { + expect(b.block instanceof LazyBlockContent).toBe(true); + }); }); + const files = await fs.promises.readdir(tmpPath); - console.log(files); + expect(files).not.toContain('bundle_0.json'); + expect(files).not.toContain('bundle_1.json'); }); }); describe.skip('RPC api service', () => { diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index b8a67ad45..5f742ec3b 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -318,14 +318,6 @@ describe('KyveApi', () => { const files = await fs.promises.readdir(tmpPath); expect(files.length).toBe(0); }); - it('remove cached bundle files when past height', async () => { - await kyveApi.fetchBlocksBatches(registry, [1, 151, 301, 501], 300); - await kyveApi.fetchBlocksBatches(registry, [502, 504, 600, 800], 300); - - const files = await fs.promises.readdir(tmpPath); - expect(files).not.toContain('bundle_0.json'); - expect((kyveApi as any).cachedBundleDetails.length).toBe(4); - }); it('ensure to remove logic', () => { const cachedBundleDetails = [ { id: '0', from_key: '1', to_key: '150' }, @@ -390,7 +382,6 @@ describe('KyveApi', () => { workerKyveApi.fetchBlocksBatches(registry, [3856726], 1), ]); - console.log(tmpPath); expect(pollSpy).toHaveBeenCalledTimes(1); const r = await kyveApi.readFromFile( diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 79014db47..6a57d0c05 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -286,6 +286,7 @@ export class KyveApi { height: number, bufferSize: number, ): BundleDetails[] { + if (!cachedBundles.length) return []; const currentBundle = this.getBundleFromCache(height); return cachedBundles.filter((b) => { @@ -321,13 +322,11 @@ export class KyveApi { await fs.promises.unlink(bundlePath); remove(this.cachedBundleDetails, (b) => b.id === bundle.id); } catch (e) { - if (e.code === 'ENOENT') { - console.error(e); - } else { + if (e.code !== 'ENOENT') { + // if it does not exist, should be removed throw e; } } - console.log('removed bundle id:', bundle.id, 'at', height); } } From d5da98015030def1eedf4fb478efd2f340ce7e27 Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 17 Apr 2024 11:35:31 +0800 Subject: [PATCH 45/81] refactor based on review, removed fetchingBundle cache, fixed polling, add remove file cache for existing files, added tests --- packages/node/src/indexer/api.service.test.ts | 5 +- packages/node/src/indexer/api.service.ts | 62 ++++----- packages/node/src/utils/kyve/kyve.spec.ts | 45 ++++--- packages/node/src/utils/kyve/kyve.ts | 121 ++++++++++-------- packages/node/src/utils/kyve/kyveTypes.ts | 1 + packages/node/src/utils/project.spec.ts | 6 + 6 files changed, 133 insertions(+), 107 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 0932683f2..4ff665078 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -99,8 +99,11 @@ describe('ApiService', () => { }); it('Able to fetch with cached promises and remove cached bundle files', async () => { - const heights_1 = [150, 300, 1, 301, 450, 550]; + jest + .spyOn(apiService as any, 'retryFetch') + .mockRejectedValue('Disabled rpc for kyve testing'); + const heights_1 = [150, 300, 1, 301, 450, 550]; const heights_2 = [498, 600, 801, 1100]; const blockArr = await Promise.all([ apiService.fetchBlocks(heights_1), diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 5df1b6c91..16d393e4a 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -12,16 +12,16 @@ import { } from '@cosmjs/tendermint-rpc'; import { BlockResponse, - Validator, BlockResultsResponse, + Validator, } from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; import { CosmosProjectNetConfig } from '@subql/common-cosmos'; import { - getLogger, - ConnectionPoolService, ApiService as BaseApiService, + ConnectionPoolService, + getLogger, IBlock, NodeConfig, } from '@subql/node-core'; @@ -44,6 +44,7 @@ import { BlockContent } from './types'; const logger = getLogger('api'); const MAX_RECONNECT_ATTEMPTS = 5; +const KYVE_BUFFER_RANGE = 10; @Injectable() export class ApiService @@ -110,13 +111,19 @@ export class ApiService ); if (this.nodeConfig.kyveEndpoint) { - this.kyveApi = await KyveApi.create( - network.chainId, - this.nodeConfig.kyveEndpoint, - this.nodeConfig.kyveStorageUrl, - this.nodeConfig.kyveChainId, - this.project.fileCacheDir, - ); + try { + this.kyveApi = await KyveApi.create( + network.chainId, + this.nodeConfig.kyveEndpoint, + this.nodeConfig.kyveStorageUrl, + this.nodeConfig.kyveChainId, + this.project.fileCacheDir, + ); + } catch (e) { + logger.warn( + `Failed to use kyve for network: ${network.chainId}, resolving to rpc`, + ); + } } return this; @@ -127,31 +134,28 @@ export class ApiService heights: number[], numAttempts = MAX_RECONNECT_ATTEMPTS, ): Promise[]> { - try { - if (this.kyveApi) { - // batchSize - // this.nodeConfig.batchSize - const bufferSize = 100; - return this.kyveApi.fetchBlocksBatches( + if (this.kyveApi) { + const bufferSize = KYVE_BUFFER_RANGE * this.nodeConfig.batchSize; + try { + return await this.kyveApi.fetchBlocksBatches( this.registry, heights, bufferSize, ); - - // delete only happens when nothing else is reading from - } else { - throw new Error('No kyve connection'); - } - } catch (e) { - if (e.message === 'No kyve connection') { - return this.retryFetch(async () => { - // Get the latest fetch function from the provider - const apiInstance = this.connectionPoolService.api; - return apiInstance.fetchBlocks(heights); - }, numAttempts); + } catch (e) { + logger.warn( + `Failed to fetch blocks: ${JSON.stringify( + heights, + )} via Kyve, switching to rpc`, + ); } - throw e; } + + return this.retryFetch(async () => { + // Get the latest fetch function from the provider + const apiInstance = this.connectionPoolService.api; + return apiInstance.fetchBlocks(heights); + }, numAttempts); } get api(): CosmosClient { diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 5f742ec3b..fbe25efd7 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -260,22 +260,14 @@ describe('KyveApi', () => { }); it('retrieve and unzip storage data', async () => { const bundle = await (kyveApi as any).getBundleById(8); - (kyveApi as any).cachedBundleDetails.push(bundle); - - const bundleFileName = (kyveApi as any).getBundleFilePath(bundle.id); - await kyveApi.downloadAndProcessBundle(bundle); - - const v = await kyveApi.readFromFile(bundleFileName); - - const b = (kyveApi as any).findBlockByHeight(1338, JSON.parse(v)); - - expect(b).toBeDefined(); + const block = await kyveApi.getBlockByHeight(1338); + expect(block.length).toBe(2); }); it('Should increment bundleId when height exceeds cache', async () => { const bundle = await (kyveApi as any).getBundleById(0); (kyveApi as any).cachedBundleDetails.push(bundle); - jest.spyOn(kyveApi as any, 'getFileCacheData').mockResolvedValueOnce('{}'); + jest.spyOn(kyveApi as any, 'getBundleData').mockResolvedValueOnce('{}'); await (kyveApi as any).updateCurrentBundleAndDetails(160); expect( @@ -305,15 +297,13 @@ describe('KyveApi', () => { retrieveBundleDataSpy.mockImplementation(() => { return new Promise((resolve, reject) => { - reject({ - response: 'err', - }); + reject('Failed to fetch'); }); }); - await expect( - (kyveApi as any).getFileCacheData(bundleDetail), - ).rejects.toBeDefined(); + await expect((kyveApi as any).getBundleData(bundleDetail)).rejects.toBe( + 'Failed to fetch', + ); const files = await fs.promises.readdir(tmpPath); expect(files.length).toBe(0); @@ -366,13 +356,11 @@ describe('KyveApi', () => { jest .spyOn(workerKyveApi as any, 'retrieveBundleData') - .mockImplementation(async () => { - await delay(4); + .mockImplementation(() => { return { data: mockStream }; }); - retrieveBundleDataSpy.mockImplementation(async () => { - await delay(3); + retrieveBundleDataSpy.mockImplementation(() => { return { data: mockStream }; }); @@ -390,6 +378,21 @@ describe('KyveApi', () => { expect(r).toEqual(JSON.stringify(block_3856726)); }); + it('isBundle', () => { + const bundle = 'bundle_0.json'; + const notBundle = 'data.json'; + + expect((kyveApi as any).isBundleFile(bundle)).toBe(true); + expect((kyveApi as any).isBundleFile(notBundle)).toBe(false); + }); + it('clear existing bundle files in directory when outside buffer', async () => { + await fs.promises.writeFile((kyveApi as any).getBundleFilePath(0), 'mock'); + await fs.promises.writeFile((kyveApi as any).getBundleFilePath(1), 'mock'); + + const removeFiles = await (kyveApi as any).getToRemoveBundles([], 800, 1); + + expect(removeFiles.map((r) => r.id).sort()).toEqual(['0', '1'].sort()); + }); describe('able to wrap kyveBlock', () => { let rpcLazyBlockContent: LazyBlockContent; let kyveLazyBlockContent: LazyBlockContent; diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 6a57d0c05..d45794674 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -21,6 +21,7 @@ import axios, { AxiosResponse } from 'axios'; import { remove } from 'lodash'; import { BlockContent } from '../../indexer/types'; import { formatBlockUtil, LazyBlockContent } from '../cosmos'; +import { isTmpDir } from '../project'; import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms @@ -41,7 +42,6 @@ interface KyveBundleData { export class KyveApi { private cachedBundleDetails: BundleDetails[] = []; - private fetchingBundles: Record> = {}; private constructor( private readonly storageUrl: string, @@ -57,6 +57,9 @@ export class KyveApi { kyveChainId: SupportedChains, tmpCacheDir: string, ): Promise { + if (!isTmpDir(tmpCacheDir)) + throw new Error('File cache directory must be a tmp directory'); + const lcdClient = new KyveSDK(kyveChainId, { rpc: endpoint, }).createLCDClient(); @@ -194,15 +197,21 @@ export class KyveApi { private async updateCurrentBundleAndDetails( height: number, ): Promise { + if (this.cachedBundleDetails.length === 0) { + const bundleId = await this.getBundleId(height); + const bundleDetail = await this.getBundleById(bundleId); + this.addToCachedBundle(bundleDetail); + } + const bundle = this.getBundleFromCache(height); if (bundle) { - return JSON.parse(await this.getFileCacheData(bundle)); + return JSON.parse(await this.getBundleData(bundle)); } else { const bundleId = await this.getBundleId(height); const newBundleDetails = await this.getBundleById(bundleId); this.addToCachedBundle(newBundleDetails); - return JSON.parse(await this.getFileCacheData(newBundleDetails)); + return JSON.parse(await this.getBundleData(newBundleDetails)); } } @@ -229,36 +238,39 @@ export class KyveApi { mode: 0o200, // write only access for owner }); - // to ensure the stream to throw an on-stack error - await new Promise((resolve, reject) => { - writeStream.on('open', resolve); - writeStream.on('error', (err) => { - reject(err); + try { + await new Promise((resolve, reject) => { + writeStream.on('open', resolve); + writeStream.on('error', (err) => { + reject(err); + }); }); - }).catch((e) => { - throw e; - }); - const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); + const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); - const gunzip = zlib.createUnzip({ - maxOutputLength: MAX_COMPRESSION_BYTE_SIZE /* avoid zip bombs */, - }); + const gunzip = zlib.createUnzip({ + maxOutputLength: MAX_COMPRESSION_BYTE_SIZE /* avoid zip bombs */, + }); - await new Promise((resolve, reject) => { - zippedBundleData.data - .pipe(gunzip) - .on('error', reject) - .pipe(writeStream) - .on('finish', resolve); - }).catch((e) => { - throw e; // to ensure an on stack error is thrown - }); + await new Promise((resolve, reject) => { + zippedBundleData.data + .pipe(gunzip) + .pipe(writeStream) + .on('error', reject) + .on('finish', resolve); + }); + } catch (e) { + if (axios.isAxiosError(e)) { + await fs.promises.unlink(bundleFilePath); + } + + throw e; + } await fs.promises.chmod(bundleFilePath, 0o444); } - private async getFileCacheData(bundle: BundleDetails): Promise { + private async getBundleData(bundle: BundleDetails): Promise { const bundleFilePath = this.getBundleFilePath(bundle.id); try { @@ -268,10 +280,6 @@ export class KyveApi { if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { return this.pollUntilReadable(bundleFilePath); } else { - if (axios.isAxiosError(e)) { - await fs.promises.unlink(bundleFilePath); - } - throw e; } } @@ -281,12 +289,35 @@ export class KyveApi { return fs.promises.readFile(bundleFilePath, 'utf-8'); } - private getToRemoveBundles( + private isBundleFile(filename: string): boolean { + return /^bundle_\d+\.json$/.test(filename); + } + + private async getExisitngBundlesFromCacheDirectory( + tmpDir: string, + ): Promise { + const bundles: BundleDetails[] = []; + const files = await fs.promises.readdir(tmpDir); + + for (const file of files) { + if (this.isBundleFile(file)) { + const id = parseDecimal(file.match(/^bundle_(\d+)\.json$/)[1]); + bundles.push(await this.getBundleById(id)); + } + } + + return bundles; + } + + private async getToRemoveBundles( cachedBundles: BundleDetails[], height: number, bufferSize: number, - ): BundleDetails[] { - if (!cachedBundles.length) return []; + ): Promise { + if (!cachedBundles.length) { + return this.getExisitngBundlesFromCacheDirectory(this.tmpCacheDir); + } + const currentBundle = this.getBundleFromCache(height); return cachedBundles.filter((b) => { @@ -306,16 +337,12 @@ export class KyveApi { height: number, bufferSize: number, ): Promise { - const toRemoveBundles = this.getToRemoveBundles( + const toRemoveBundles = await this.getToRemoveBundles( cachedBundles, height, bufferSize, ); - if (!toRemoveBundles.length) { - return; - } - for (const bundle of toRemoveBundles) { const bundlePath = this.getBundleFilePath(bundle.id); try { @@ -333,9 +360,8 @@ export class KyveApi { async getBlockByHeight( height: number, ): Promise<[BlockResponse, BlockResultsResponse]> { - const blocks = await this.fetchBundleCached(height); + const blocks = await this.updateCurrentBundleAndDetails(height); const blockData = this.findBlockByHeight(height, blocks); - return [ this.decodeBlock(blockData.value.block), this.injectLogs(this.decodeBlockResult(blockData.value.block_results)), @@ -393,23 +419,6 @@ export class KyveApi { return logs; } - async fetchBundleCached(height: number): Promise { - let bundle = this.getBundleFromCache(height); - - if (!bundle) { - const bundleId = await this.getBundleId(height); - bundle = await this.getBundleById(bundleId); - this.addToCachedBundle(bundle); - } - - // eslint-disable-next-line @typescript-eslint/no-misused-promises - if (!this.fetchingBundles[bundle.id]) { - this.fetchingBundles[bundle.id] = - this.updateCurrentBundleAndDetails(height); - } - return this.fetchingBundles[bundle.id]; - } - private async fetchBlocksArray( blockArray: number[], ): Promise<[BlockResponse, BlockResultsResponse][]> { diff --git a/packages/node/src/utils/kyve/kyveTypes.ts b/packages/node/src/utils/kyve/kyveTypes.ts index 9fb9df6bb..11072f950 100644 --- a/packages/node/src/utils/kyve/kyveTypes.ts +++ b/packages/node/src/utils/kyve/kyveTypes.ts @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0 // Note: this is due to incorrect typings provided by kyvejs +// https://github.com/KYVENetwork/kyvejs/issues/131 export interface BundleDetails { pool_id: string; id: string; diff --git a/packages/node/src/utils/project.spec.ts b/packages/node/src/utils/project.spec.ts index 67e114dfa..392f63079 100644 --- a/packages/node/src/utils/project.spec.ts +++ b/packages/node/src/utils/project.spec.ts @@ -9,4 +9,10 @@ describe('Project tests', () => { const tmpDir = await makeTempDir(); expect(isTmpDir(tmpDir)).toBe(true); }); + it('Not isTmpDir', () => { + const unixDir = '/Users/test/'; + const winDir = 'C:\\Users\\test\\'; + expect(isTmpDir(unixDir)).toBe(false); + expect(isTmpDir(winDir)).toBe(false); + }); }); From f37102a5cb1936a14780cc0b7872ddfa002a0dd2 Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 17 Apr 2024 11:37:43 +0800 Subject: [PATCH 46/81] tidy up --- packages/node/src/utils/kyve/kyve.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index d45794674..37117aa3b 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -57,8 +57,9 @@ export class KyveApi { kyveChainId: SupportedChains, tmpCacheDir: string, ): Promise { - if (!isTmpDir(tmpCacheDir)) + if (!isTmpDir(tmpCacheDir)) { throw new Error('File cache directory must be a tmp directory'); + } const lcdClient = new KyveSDK(kyveChainId, { rpc: endpoint, @@ -235,7 +236,6 @@ export class KyveApi { const writeStream = fs.createWriteStream(bundleFilePath, { flags: 'wx', - mode: 0o200, // write only access for owner }); try { From 3ba4fa1561b8a3e4249c6b638d585c14b558b98f Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 17 Apr 2024 11:53:26 +0800 Subject: [PATCH 47/81] fix api service kyve test --- packages/node/src/indexer/api.service.test.ts | 8 ++++---- packages/node/src/utils/kyve/kyve.spec.ts | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 4ff665078..210ab93a6 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -17,7 +17,7 @@ import { NodeConfig, } from '@subql/node-core'; import { GraphQLSchema } from 'graphql'; -import { CosmosNodeConfig } from '../configure/NodeConfig'; +import Pino from 'pino'; import { SubqueryProject } from '../configure/SubqueryProject'; import { LazyBlockContent } from '../utils/cosmos'; import { ApiService } from './api.service'; @@ -99,9 +99,7 @@ describe('ApiService', () => { }); it('Able to fetch with cached promises and remove cached bundle files', async () => { - jest - .spyOn(apiService as any, 'retryFetch') - .mockRejectedValue('Disabled rpc for kyve testing'); + const rpcFetchSpy = jest.spyOn(apiService as any, 'retryFetch'); const heights_1 = [150, 300, 1, 301, 450, 550]; const heights_2 = [498, 600, 801, 1100]; @@ -117,6 +115,8 @@ describe('ApiService', () => { }); const files = await fs.promises.readdir(tmpPath); + + expect(rpcFetchSpy).toHaveBeenCalledTimes(0); expect(files).not.toContain('bundle_0.json'); expect(files).not.toContain('bundle_1.json'); }); diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index fbe25efd7..b8ea1f05f 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -308,7 +308,7 @@ describe('KyveApi', () => { const files = await fs.promises.readdir(tmpPath); expect(files.length).toBe(0); }); - it('ensure to remove logic', () => { + it('ensure to remove logic', async () => { const cachedBundleDetails = [ { id: '0', from_key: '1', to_key: '150' }, { id: '1', from_key: '151', to_key: '300' }, @@ -320,7 +320,7 @@ describe('KyveApi', () => { const height = 650; const bufferSize = 300; - const toRemoveBundles = (kyveApi as any).getToRemoveBundles( + const toRemoveBundles = await (kyveApi as any).getToRemoveBundles( cachedBundleDetails, height, bufferSize, From 491989d6f749147c1b92f86adc4aa7f491e7a61f Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 17 Apr 2024 13:49:13 +0800 Subject: [PATCH 48/81] refactor based on review, update tmpDir, update error handling on stream, tidy up --- .../node/src/configure/SubqueryProject.ts | 25 +++++++++++++----- packages/node/src/indexer/api.service.ts | 7 +++-- packages/node/src/utils/kyve/kyve.ts | 26 +++++-------------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/packages/node/src/configure/SubqueryProject.ts b/packages/node/src/configure/SubqueryProject.ts index aafd529ff..e0372f617 100644 --- a/packages/node/src/configure/SubqueryProject.ts +++ b/packages/node/src/configure/SubqueryProject.ts @@ -2,8 +2,11 @@ // SPDX-License-Identifier: GPL-3.0 import assert from 'assert'; +import fs from 'fs'; +import os from 'os'; +import path from 'path'; import { Injectable } from '@nestjs/common'; -import { LocalReader, makeTempDir, validateSemver } from '@subql/common'; +import { LocalReader, validateSemver } from '@subql/common'; import { CosmosProjectNetworkConfig, parseCosmosProjectManifest, @@ -101,15 +104,12 @@ export class SubqueryProject implements ISubqueryProject { NOT_SUPPORT('<1.0.0'); } - const fileCacheDir = await getFileCacheDir(reader, root); - return loadProjectFromManifestBase( manifest.asV1_0_0, reader, path, root, networkOverrides, - fileCacheDir, ); } } @@ -117,10 +117,20 @@ export class SubqueryProject implements ISubqueryProject { async function getFileCacheDir( reader: Reader, projectRoot: string, + chainId: string, ): Promise { if (isTmpDir(projectRoot)) return projectRoot; - if (reader instanceof LocalReader) return makeTempDir(); - + if (reader instanceof LocalReader) { + const tmpDir = path.join(os.tmpdir(), `kyveTmpFileCache_${chainId}`); + try { + await fs.promises.mkdir(tmpDir); + } catch (e) { + if (e.code === 'EEXIST') { + return tmpDir; + } + } + return tmpDir; + } return projectRoot; } @@ -132,7 +142,6 @@ async function loadProjectFromManifestBase( path: string, root: string, networkOverrides?: Partial, - fileCacheDir?: string, ): Promise { if (typeof projectManifest.network.endpoint === 'string') { projectManifest.network.endpoint = [projectManifest.network.endpoint]; @@ -183,6 +192,8 @@ async function loadProjectFromManifestBase( ), ); + const fileCacheDir = await getFileCacheDir(reader, root, network.chainId); + return new SubqueryProject( reader.root ? reader.root : path, //TODO, need to method to get project_id root, diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 16d393e4a..bc705219e 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -53,7 +53,7 @@ export class ApiService { private fetchBlocksBatches = CosmosUtil.fetchBlocksBatches; private nodeConfig: CosmosNodeConfig; - private kyveApi: KyveApi; + private kyveApi?: KyveApi; registry: Registry; constructor( @@ -111,6 +111,7 @@ export class ApiService ); if (this.nodeConfig.kyveEndpoint) { + console.log(this.project.fileCacheDir); try { this.kyveApi = await KyveApi.create( network.chainId, @@ -120,9 +121,7 @@ export class ApiService this.project.fileCacheDir, ); } catch (e) { - logger.warn( - `Failed to use kyve for network: ${network.chainId}, resolving to rpc`, - ); + logger.warn(`${e}`); } } diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 37117aa3b..03a7edd33 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -198,22 +198,13 @@ export class KyveApi { private async updateCurrentBundleAndDetails( height: number, ): Promise { - if (this.cachedBundleDetails.length === 0) { + let bundle = this.getBundleFromCache(height); + if (!bundle) { const bundleId = await this.getBundleId(height); - const bundleDetail = await this.getBundleById(bundleId); - this.addToCachedBundle(bundleDetail); - } - - const bundle = this.getBundleFromCache(height); - if (bundle) { - return JSON.parse(await this.getBundleData(bundle)); - } else { - const bundleId = await this.getBundleId(height); - const newBundleDetails = await this.getBundleById(bundleId); - - this.addToCachedBundle(newBundleDetails); - return JSON.parse(await this.getBundleData(newBundleDetails)); + bundle = await this.getBundleById(bundleId); + this.addToCachedBundle(bundle); } + return JSON.parse(await this.getBundleData(bundle)); } private async pollUntilReadable(bundleFilePath: string): Promise { @@ -241,9 +232,7 @@ export class KyveApi { try { await new Promise((resolve, reject) => { writeStream.on('open', resolve); - writeStream.on('error', (err) => { - reject(err); - }); + writeStream.on('error', reject); }); const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); @@ -260,10 +249,9 @@ export class KyveApi { .on('finish', resolve); }); } catch (e) { - if (axios.isAxiosError(e)) { + if (!['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { await fs.promises.unlink(bundleFilePath); } - throw e; } From 72d09477a5491c894501e86190d63f12b63ee83f Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 17 Apr 2024 16:31:39 +0800 Subject: [PATCH 49/81] update tests --- packages/node/src/indexer/api.service.test.ts | 63 ++++++++----------- packages/node/src/indexer/api.service.ts | 1 - packages/node/src/utils/kyve/kyve.spec.ts | 23 +++++-- packages/node/src/utils/kyve/kyve.ts | 4 +- 4 files changed, 44 insertions(+), 47 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 210ab93a6..069bf9ccb 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -56,7 +56,6 @@ describe('ApiService', () => { const prepareApiService = async ( endpoint: string, chainId: string, - kyve: boolean, fileCacheDir?: string, ) => { const module = await Test.createTestingModule({ @@ -80,55 +79,41 @@ describe('ApiService', () => { app = module.createNestApplication(); await app.init(); apiService = app.get(ApiService); - if (kyve) { - (apiService as any).nodeConfig._config.kyveEndpoint = - 'https://api-us-1.kyve.network'; - (apiService as any).nodeConfig._config.kyveStorageUrl = - 'https://arweave.net'; - } + (apiService as any).nodeConfig._config.kyveEndpoint = + 'https://api-us-1.kyve.network'; + (apiService as any).nodeConfig._config.kyveStorageUrl = + 'https://arweave.net'; await apiService.init(); }; - describe('KYVE Api service', () => { - beforeAll(async () => { - const ENDPOINT = 'https://rpc.mainnet.archway.io:443'; - const CHAINID = 'archway-1'; + const ENDPOINT = 'https://rpc-juno.itastakers.com/'; + const CHAINID = 'juno-1'; + describe('RPC api service', () => { + beforeAll(async () => { tmpPath = await makeTempDir(); - await prepareApiService(ENDPOINT, CHAINID, true, tmpPath); }); + it('Falls back on rpc if kyve fails', async () => { + const endpoint = 'https://rpc.mainnet.archway.io:443'; + const chainId = 'archway-1'; - it('Able to fetch with cached promises and remove cached bundle files', async () => { - const rpcFetchSpy = jest.spyOn(apiService as any, 'retryFetch'); + await prepareApiService(endpoint, chainId, tmpPath); - const heights_1 = [150, 300, 1, 301, 450, 550]; - const heights_2 = [498, 600, 801, 1100]; - const blockArr = await Promise.all([ - apiService.fetchBlocks(heights_1), - apiService.fetchBlocks(heights_2), - ]); + jest + .spyOn((apiService as any).kyveApi, 'retrieveBundleData') + .mockRejectedValueOnce( + 'Error: Client network socket disconnected before secure TLS connection was established', + ); - blockArr.forEach((blockContent) => { - blockContent.forEach((b) => { - expect(b.block instanceof LazyBlockContent).toBe(true); - }); - }); + const rpcFetchSpy = jest.spyOn(apiService as any, 'retryFetch'); - const files = await fs.promises.readdir(tmpPath); + await apiService.fetchBlocks([1]); - expect(rpcFetchSpy).toHaveBeenCalledTimes(0); - expect(files).not.toContain('bundle_0.json'); - expect(files).not.toContain('bundle_1.json'); + expect(rpcFetchSpy).toHaveBeenCalledTimes(1); }); - }); - describe.skip('RPC api service', () => { - beforeAll(async () => { - const ENDPOINT = 'https://rpc-juno.itastakers.com/'; - const CHAINID = 'juno-1'; + it.skip('query block info', async () => { + await prepareApiService(ENDPOINT, CHAINID, tmpPath); - await prepareApiService(ENDPOINT, CHAINID, false); - }); - it('query block info', async () => { const api = apiService.api; const blockInfo = await api.blockInfo(TEST_BLOCKNUMBER); const doc: any = loadFromJsonOrYaml( @@ -150,7 +135,9 @@ describe('ApiService', () => { expect(blockInfo).toMatchObject(realBlockInfo); }); - it('query tx info by height', async () => { + it.skip('query tx info by height', async () => { + await prepareApiService(ENDPOINT, CHAINID, tmpPath); + const api = apiService.api; const txInfos = await api.txInfoByHeight(TEST_BLOCKNUMBER); expect(txInfos.length).toEqual(4); diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index bc705219e..102c01e0a 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -111,7 +111,6 @@ export class ApiService ); if (this.nodeConfig.kyveEndpoint) { - console.log(this.project.fileCacheDir); try { this.kyveApi = await KyveApi.create( network.chainId, diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index b8ea1f05f..df06ea8d8 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -258,11 +258,24 @@ describe('KyveApi', () => { expect(permissions).toBe('444'); } }); - it('retrieve and unzip storage data', async () => { - const bundle = await (kyveApi as any).getBundleById(8); - (kyveApi as any).cachedBundleDetails.push(bundle); - const block = await kyveApi.getBlockByHeight(1338); - expect(block.length).toBe(2); + it('able to fetch/write/read blocks using Kyve api', async () => { + const heights_1 = [150, 300, 1, 301, 450, 550]; + const heights_2 = [498, 600, 801, 1100]; + const blockArr = await Promise.all([ + kyveApi.fetchBlocksBatches(registry, heights_1, 300), + kyveApi.fetchBlocksBatches(registry, heights_2, 300), + ]); + + blockArr.forEach((blockContent) => { + blockContent.forEach((b) => { + expect(b.block instanceof LazyBlockContent).toBe(true); + }); + }); + + const files = await fs.promises.readdir(tmpPath); + + expect(files).not.toContain('bundle_0.json'); + expect(files).not.toContain('bundle_1.json'); }); it('Should increment bundleId when height exceeds cache', async () => { const bundle = await (kyveApi as any).getBundleById(0); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 03a7edd33..f66427ff5 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -67,9 +67,7 @@ export class KyveApi { const poolId = await KyveApi.fetchPoolId(chainId, lcdClient); - const kyve = new KyveApi(storageUrl, tmpCacheDir, poolId, lcdClient); - - return kyve; + return new KyveApi(storageUrl, tmpCacheDir, poolId, lcdClient); } private static async fetchPoolId( From d57f260d589f16994e09c89819875463072b2b99 Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 17 Apr 2024 18:17:34 +0800 Subject: [PATCH 50/81] fix up poller; --- packages/node/src/utils/kyve/kyve.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index f66427ff5..ddcfa59c2 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -225,6 +225,7 @@ export class KyveApi { const writeStream = fs.createWriteStream(bundleFilePath, { flags: 'wx', + mode: 0o200, // write only access for owner }); try { @@ -258,7 +259,6 @@ export class KyveApi { private async getBundleData(bundle: BundleDetails): Promise { const bundleFilePath = this.getBundleFilePath(bundle.id); - try { await this.downloadAndProcessBundle(bundle); return await this.readFromFile(bundleFilePath); From 14b2b5ada89bdfa1276b10f00da4264b82d07f5a Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Wed, 17 Apr 2024 10:46:59 +0000 Subject: [PATCH 51/81] fix test cases, update logic in removal --- packages/node/src/utils/kyve/kyve.spec.ts | 1 - packages/node/src/utils/kyve/kyve.ts | 22 ++++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index df06ea8d8..0fd558b6b 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -275,7 +275,6 @@ describe('KyveApi', () => { const files = await fs.promises.readdir(tmpPath); expect(files).not.toContain('bundle_0.json'); - expect(files).not.toContain('bundle_1.json'); }); it('Should increment bundleId when height exceeds cache', async () => { const bundle = await (kyveApi as any).getBundleById(0); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index ddcfa59c2..b08c815d3 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -306,16 +306,18 @@ export class KyveApi { const currentBundle = this.getBundleFromCache(height); - return cachedBundles.filter((b) => { - const isNotCurrentBundleAndLower = - currentBundle.id !== b.id && - parseDecimal(currentBundle.id) > parseDecimal(b.id); - const isOutsiderBuffer = - height < parseDecimal(b.from_key) - bufferSize || - height > parseDecimal(b.to_key) + bufferSize; - - return isNotCurrentBundleAndLower && isOutsiderBuffer; - }); + return currentBundle + ? cachedBundles.filter((b) => { + const isNotCurrentBundleAndLower = + currentBundle.id !== b.id && + parseDecimal(currentBundle.id) > parseDecimal(b.id); + const isOutsiderBuffer = + height < parseDecimal(b.from_key) - bufferSize || + height > parseDecimal(b.to_key) + bufferSize; + + return isNotCurrentBundleAndLower && isOutsiderBuffer; + }) + : []; } async clearFileCache( From 6fbf6b09b7da52e3d8314debbec4d1d93c9ccae7 Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 22 Apr 2024 07:26:04 +0800 Subject: [PATCH 52/81] update bundle regex, tidy up based on review --- .../node/src/configure/SubqueryProject.ts | 34 ++++------------ packages/node/src/utils/kyve/kyve.spec.ts | 16 ++++++++ packages/node/src/utils/kyve/kyve.ts | 40 ++++++++++++++++--- 3 files changed, 58 insertions(+), 32 deletions(-) diff --git a/packages/node/src/configure/SubqueryProject.ts b/packages/node/src/configure/SubqueryProject.ts index e0372f617..de8a535cc 100644 --- a/packages/node/src/configure/SubqueryProject.ts +++ b/packages/node/src/configure/SubqueryProject.ts @@ -2,11 +2,8 @@ // SPDX-License-Identifier: GPL-3.0 import assert from 'assert'; -import fs from 'fs'; -import os from 'os'; -import path from 'path'; import { Injectable } from '@nestjs/common'; -import { LocalReader, validateSemver } from '@subql/common'; +import { validateSemver } from '@subql/common'; import { CosmosProjectNetworkConfig, parseCosmosProjectManifest, @@ -31,7 +28,8 @@ import { import { buildSchemaFromString } from '@subql/utils'; import Cron from 'cron-converter'; import { GraphQLSchema } from 'graphql'; -import { isTmpDir, processNetworkConfig } from '../utils/project'; +import { KyveApi } from '../utils/kyve/kyve'; +import { processNetworkConfig } from '../utils/project'; const { version: packageVersion } = require('../../package.json'); @@ -114,26 +112,6 @@ export class SubqueryProject implements ISubqueryProject { } } -async function getFileCacheDir( - reader: Reader, - projectRoot: string, - chainId: string, -): Promise { - if (isTmpDir(projectRoot)) return projectRoot; - if (reader instanceof LocalReader) { - const tmpDir = path.join(os.tmpdir(), `kyveTmpFileCache_${chainId}`); - try { - await fs.promises.mkdir(tmpDir); - } catch (e) { - if (e.code === 'EEXIST') { - return tmpDir; - } - } - return tmpDir; - } - return projectRoot; -} - type SUPPORT_MANIFEST = ProjectManifestV1_0_0Impl; async function loadProjectFromManifestBase( @@ -192,7 +170,11 @@ async function loadProjectFromManifestBase( ), ); - const fileCacheDir = await getFileCacheDir(reader, root, network.chainId); + const fileCacheDir = await KyveApi.getFileCacheDir( + reader, + root, + network.chainId, + ); return new SubqueryProject( reader.root ? reader.root : path, //TODO, need to method to get project_id diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 0fd558b6b..b5dd82489 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -405,6 +405,22 @@ describe('KyveApi', () => { expect(removeFiles.map((r) => r.id).sort()).toEqual(['0', '1'].sort()); }); + it('ensure file bundle id regex is correct', () => { + const files = [ + 'bundle_2_0.json', + 'bundle_2_1.json', + 'bundle_2_2.json', + 'bundle_2_3.json', + 'bundle_5_0.json', + 'bundle_4_0.json', + 'bundle_3_0.json', + 'bundle_1_0.json', + ]; + + expect(files.filter((f) => (kyveApi as any).isBundleFile(f)).length).toBe( + 4, + ); + }); describe('able to wrap kyveBlock', () => { let rpcLazyBlockContent: LazyBlockContent; let kyveLazyBlockContent: LazyBlockContent; diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index b08c815d3..06e0b48f9 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -3,6 +3,7 @@ import assert from 'assert'; import fs from 'fs'; +import os from 'os'; import path from 'path'; import * as zlib from 'zlib'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; @@ -16,7 +17,9 @@ import { import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; // Currently these types are not exported import { QueryPoolsResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; +import { LocalReader } from '@subql/common'; import { delay, getLogger, IBlock } from '@subql/node-core'; +import { Reader } from '@subql/types-core'; import axios, { AxiosResponse } from 'axios'; import { remove } from 'lodash'; import { BlockContent } from '../../indexer/types'; @@ -27,6 +30,8 @@ import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms const POLL_TIMER = 3; // sec const MAX_COMPRESSION_BYTE_SIZE = 2 * 10 ** 9; +const BUNDLE_FILE_ID_REG = (poolId: string) => + new RegExp(`^bundle_${poolId}_\\d+\\.json$`); const parseDecimal = (value: string) => parseInt(value, 10); @@ -112,7 +117,7 @@ export class KyveApi { } private getBundleFilePath(id: string): string { - return path.join(this.tmpCacheDir, `bundle_${id}.json`); + return path.join(this.tmpCacheDir, `bundle_${this.poolId}_${id}.json`); } private async getBundleById(bundleId: number): Promise { @@ -276,10 +281,10 @@ export class KyveApi { } private isBundleFile(filename: string): boolean { - return /^bundle_\d+\.json$/.test(filename); + return BUNDLE_FILE_ID_REG(this.poolId).test(filename); } - private async getExisitngBundlesFromCacheDirectory( + private async getExistingBundlesFromCacheDirectory( tmpDir: string, ): Promise { const bundles: BundleDetails[] = []; @@ -287,7 +292,7 @@ export class KyveApi { for (const file of files) { if (this.isBundleFile(file)) { - const id = parseDecimal(file.match(/^bundle_(\d+)\.json$/)[1]); + const id = parseDecimal(file.match(BUNDLE_FILE_ID_REG(this.poolId))[1]); bundles.push(await this.getBundleById(id)); } } @@ -301,7 +306,7 @@ export class KyveApi { bufferSize: number, ): Promise { if (!cachedBundles.length) { - return this.getExisitngBundlesFromCacheDirectory(this.tmpCacheDir); + return this.getExistingBundlesFromCacheDirectory(this.tmpCacheDir); } const currentBundle = this.getBundleFromCache(height); @@ -362,7 +367,9 @@ export class KyveApi { try { kyveBlockResult.results.forEach((b) => { // log is readonly hence needing to cast it - (b.log as any) = JSON.stringify(this.reconstructLogs(kyveBlockResult)); + (b.log as string) = JSON.stringify( + this.reconstructLogs(kyveBlockResult), + ); }); } catch (e) { throw new Error(`Failed to inject kyveBlock, ${e}`); @@ -459,4 +466,25 @@ export class KyveApi { } }); } + + static async getFileCacheDir( + reader: Reader, + projectRoot: string, + chainId: string, + ): Promise { + if (isTmpDir(projectRoot)) return projectRoot; + if (reader instanceof LocalReader) { + const tmpDir = path.join(os.tmpdir(), `kyveTmpFileCache_${chainId}`); + try { + await fs.promises.mkdir(tmpDir); + } catch (e) { + if (e.code === 'EEXIST') { + return tmpDir; + } + throw e; + } + return tmpDir; + } + return projectRoot; + } } From 606501c8c561d22e62a4c83b1cfbfcafb392c8bf Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 22 Apr 2024 08:44:49 +0800 Subject: [PATCH 53/81] fix regex, update changelog --- packages/node/CHANGELOG.md | 4 ++-- packages/node/src/utils/kyve/kyve.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/node/CHANGELOG.md b/packages/node/CHANGELOG.md index 1ee533189..f76adbc47 100644 --- a/packages/node/CHANGELOG.md +++ b/packages/node/CHANGELOG.md @@ -8,8 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Support for KYVE integration with supporting flags (#235) - `--kyve-endpoint` - - `--kyve-chain-id` - - `--kyve-storage-url` + - `--kyve-chain-id` (default value is `kyve-1`) + - `--kyve-storage-url` (default value is `https://arweave.net`) ## [3.10.0] - 2024-04-10 ### Changed diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 06e0b48f9..6d702644d 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -31,7 +31,7 @@ const BUNDLE_TIMEOUT = 10000; //ms const POLL_TIMER = 3; // sec const MAX_COMPRESSION_BYTE_SIZE = 2 * 10 ** 9; const BUNDLE_FILE_ID_REG = (poolId: string) => - new RegExp(`^bundle_${poolId}_\\d+\\.json$`); + new RegExp(`^bundle_${poolId}_(\\d+)\\.json$`); const parseDecimal = (value: string) => parseInt(value, 10); From 1a3e9c49c967ee84a1fe8d268cfc26fce850499d Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 22 Apr 2024 08:48:55 +0800 Subject: [PATCH 54/81] update tests --- packages/node/src/utils/kyve/kyve.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index b5dd82489..85048c16b 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -391,7 +391,7 @@ describe('KyveApi', () => { expect(r).toEqual(JSON.stringify(block_3856726)); }); it('isBundle', () => { - const bundle = 'bundle_0.json'; + const bundle = 'bundle_2_0.json'; const notBundle = 'data.json'; expect((kyveApi as any).isBundleFile(bundle)).toBe(true); From af7855080249ab7b322f8083bb823bfb72a82aaf Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 22 Apr 2024 09:17:09 +0800 Subject: [PATCH 55/81] tidy up test --- packages/node/src/utils/kyve/kyve.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 85048c16b..9cc5f3c62 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -274,7 +274,7 @@ describe('KyveApi', () => { const files = await fs.promises.readdir(tmpPath); - expect(files).not.toContain('bundle_0.json'); + expect(files).not.toContain('bundle_2_0.json'); }); it('Should increment bundleId when height exceeds cache', async () => { const bundle = await (kyveApi as any).getBundleById(0); From 0abf7f74842b996815ad71fe26a4efe38ca896df Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 22 Apr 2024 09:59:09 +0800 Subject: [PATCH 56/81] add logging --- packages/node/src/utils/kyve/kyve.ts | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 6d702644d..eed7adecf 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -72,6 +72,7 @@ export class KyveApi { const poolId = await KyveApi.fetchPoolId(chainId, lcdClient); + logger.info(`Kyve API connected`); return new KyveApi(storageUrl, tmpCacheDir, poolId, lcdClient); } @@ -230,7 +231,7 @@ export class KyveApi { const writeStream = fs.createWriteStream(bundleFilePath, { flags: 'wx', - mode: 0o200, // write only access for owner + mode: 0o200, // Ensure that only writer has access to file }); try { @@ -245,6 +246,8 @@ export class KyveApi { maxOutputLength: MAX_COMPRESSION_BYTE_SIZE /* avoid zip bombs */, }); + logger.info(`Retrieving bundle ${bundle.id}`); + await new Promise((resolve, reject) => { zippedBundleData.data .pipe(gunzip) @@ -252,14 +255,14 @@ export class KyveApi { .on('error', reject) .on('finish', resolve); }); + + await fs.promises.chmod(bundleFilePath, 0o444); } catch (e) { if (!['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { await fs.promises.unlink(bundleFilePath); } throw e; } - - await fs.promises.chmod(bundleFilePath, 0o444); } private async getBundleData(bundle: BundleDetails): Promise { @@ -477,13 +480,13 @@ export class KyveApi { const tmpDir = path.join(os.tmpdir(), `kyveTmpFileCache_${chainId}`); try { await fs.promises.mkdir(tmpDir); + return tmpDir; } catch (e) { if (e.code === 'EEXIST') { return tmpDir; } throw e; } - return tmpDir; } return projectRoot; } From da5cb9481700927b0b63f3cceefbca117ee3c613 Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Mon, 22 Apr 2024 03:49:14 +0000 Subject: [PATCH 57/81] add await for poller and fix bundleCache id --- packages/node/src/utils/kyve/kyve.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index eed7adecf..7be9635b9 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -204,7 +204,12 @@ export class KyveApi { ): Promise { let bundle = this.getBundleFromCache(height); if (!bundle) { - const bundleId = await this.getBundleId(height); + const bundleId = + this.cachedBundleDetails.length !== 0 + ? Math.max( + ...this.cachedBundleDetails.map((b) => parseDecimal(b.id)), + ) + 1 + : await this.getBundleId(height); bundle = await this.getBundleById(bundleId); this.addToCachedBundle(bundle); } @@ -272,7 +277,8 @@ export class KyveApi { return await this.readFromFile(bundleFilePath); } catch (e: any) { if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { - return this.pollUntilReadable(bundleFilePath); + const res = await this.pollUntilReadable(bundleFilePath); + return res; } else { throw e; } From 2d1d76b35967fa0c8ca0f8e144940c2e63e2afd3 Mon Sep 17 00:00:00 2001 From: bz888 Date: Mon, 22 Apr 2024 12:44:14 +0800 Subject: [PATCH 58/81] refactor cacheBundle to be object --- packages/node/src/utils/kyve/kyve.spec.ts | 61 ++++++++++--------- packages/node/src/utils/kyve/kyve.ts | 74 +++++++++++++---------- 2 files changed, 76 insertions(+), 59 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 9cc5f3c62..9e34ca7bf 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -111,7 +111,10 @@ describe('KyveApi', () => { readerSpy.mockRestore(); // reset cache - (kyveApi as any).cachedBundleDetails = []; + ((kyveApi as any).cachedBundleDetails as Record< + string, + Promise + >) = {}; }); afterAll(async () => { await promisify(rimraf)(tmpPath); @@ -250,7 +253,11 @@ describe('KyveApi', () => { expect(cachedBundles.length).toBe(3); expect(blocks.length).toBe(5); - for (const bundle of (kyveApi as any).cachedBundleDetails) { + const bundles = (await Promise.all( + Object.values((kyveApi as any).cachedBundleDetails), + )) as BundleDetails[]; + + for (const bundle of bundles) { const stats = await fs.promises.stat( (kyveApi as any).getBundleFilePath(bundle.id), ); @@ -277,14 +284,11 @@ describe('KyveApi', () => { expect(files).not.toContain('bundle_2_0.json'); }); it('Should increment bundleId when height exceeds cache', async () => { - const bundle = await (kyveApi as any).getBundleById(0); - (kyveApi as any).cachedBundleDetails.push(bundle); + (kyveApi as any).addToCachedBundle(0, (kyveApi as any).getBundleById(0)); jest.spyOn(kyveApi as any, 'getBundleData').mockResolvedValueOnce('{}'); await (kyveApi as any).updateCurrentBundleAndDetails(160); - expect( - (kyveApi as any).cachedBundleDetails.find((b) => b.id === '1'), - ).toBeDefined(); + expect((kyveApi as any).cachedBundleDetails['1']).toBeDefined(); }); it('compare block info', async () => { const height = 3901476; @@ -302,8 +306,9 @@ describe('KyveApi', () => { expect(poolId).toBe('2'); }); it('remove bundle.json if bundle fetch fails', async () => { - const bundleDetail = await (kyveApi as any).getBundleById(8); - (kyveApi as any).cachedBundleDetails = [bundleDetail]; + (kyveApi as any).cachedBundleDetails = { + '8': (kyveApi as any).getBundleById(8), + }; jest.spyOn(axios, 'isAxiosError').mockImplementationOnce(() => true); @@ -313,7 +318,8 @@ describe('KyveApi', () => { }); }); - await expect((kyveApi as any).getBundleData(bundleDetail)).rejects.toBe( + const bundleDetails = await (kyveApi as any).cachedBundleDetails['8']; + await expect((kyveApi as any).getBundleData(bundleDetails)).rejects.toBe( 'Failed to fetch', ); @@ -321,33 +327,32 @@ describe('KyveApi', () => { expect(files.length).toBe(0); }); it('ensure to remove logic', async () => { - const cachedBundleDetails = [ - { id: '0', from_key: '1', to_key: '150' }, - { id: '1', from_key: '151', to_key: '300' }, - { id: '2', from_key: '301', to_key: '500' }, - { id: '3', from_key: '501', to_key: '800' }, - ] as BundleDetails[]; - (kyveApi as any).cachedBundleDetails = cachedBundleDetails; + const mockCachedBundles: Record> = { + '0': (kyveApi as any).getBundleById(0), + '1': (kyveApi as any).getBundleById(1), + '2': (kyveApi as any).getBundleById(2), + '3': (kyveApi as any).getBundleById(3), + '4': (kyveApi as any).getBundleById(4), + }; + + (kyveApi as any).cachedBundleDetails = mockCachedBundles; const height = 650; const bufferSize = 300; const toRemoveBundles = await (kyveApi as any).getToRemoveBundles( - cachedBundleDetails, + mockCachedBundles, height, bufferSize, ); - expect(toRemoveBundles.sort()).toEqual( - [ - { id: '0', from_key: '1', to_key: '150' }, - { id: '1', from_key: '151', to_key: '300' }, - ].sort(), - ); + expect(toRemoveBundles.sort().map((b) => b.id)).toEqual(['0', '1'].sort()); }); it('Able to poll with simulated workers', async () => { - const bundleDetail = await (kyveApi as any).getBundleById(130265); - (kyveApi as any).cachedBundleDetails = [bundleDetail]; + const mockCacheDetails = { + '130265': (kyveApi as any).getBundleById(130265), + }; + (kyveApi as any).cachedBundleDetails = mockCacheDetails; const workerKyveApi = await KyveApi.create( 'archway-1', @@ -357,7 +362,7 @@ describe('KyveApi', () => { tmpPath, ); - (workerKyveApi as any).cachedBundleDetails = [bundleDetail]; + (workerKyveApi as any).cachedBundleDetails = mockCacheDetails; jest .spyOn(workerKyveApi, 'downloadAndProcessBundle') @@ -385,7 +390,7 @@ describe('KyveApi', () => { expect(pollSpy).toHaveBeenCalledTimes(1); const r = await kyveApi.readFromFile( - (kyveApi as any).getBundleFilePath(bundleDetail.id), + (kyveApi as any).getBundleFilePath('130265'), ); expect(r).toEqual(JSON.stringify(block_3856726)); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 7be9635b9..3ea5a36a6 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -46,7 +46,7 @@ interface KyveBundleData { } export class KyveApi { - private cachedBundleDetails: BundleDetails[] = []; + private cachedBundleDetails: Record> = {}; private constructor( private readonly storageUrl: string, @@ -149,9 +149,11 @@ export class KyveApi { private async getBundleId(height: number): Promise { const latestBundleId = await this.getLatestBundleId(); + const lowestCacheHeight = Object.keys(this.cachedBundleDetails); + let low = - this.cachedBundleDetails.length > 0 - ? Math.min(...this.cachedBundleDetails.map((b) => parseDecimal(b.id))) + lowestCacheHeight.length > 0 + ? Math.min(...lowestCacheHeight.map((id) => parseDecimal(id))) : -1; let high = latestBundleId; let startBundleId = -1; // Initialize to an invalid ID initially @@ -186,14 +188,23 @@ export class KyveApi { ); } - private addToCachedBundle(bundle: BundleDetails): void { - if (!this.cachedBundleDetails.find((b) => b.id === bundle.id)) { - this.cachedBundleDetails.push(bundle); + private addToCachedBundle( + bundleId: string, + bundlePromise: Promise, + ): void { + // eslint-disable-next-line @typescript-eslint/no-misused-promises + if (!this.cachedBundleDetails[bundleId]) { + this.cachedBundleDetails[bundleId] = bundlePromise; } } - private getBundleFromCache(height: number): BundleDetails | undefined { - return this.cachedBundleDetails.find( + private async getBundleFromCache( + height: number, + ): Promise | undefined { + const bundles: BundleDetails[] = await Promise.all( + Object.values(this.cachedBundleDetails), + ); + return bundles.find( (b) => parseDecimal(b.from_key) <= height && height <= parseDecimal(b.to_key), ); @@ -202,16 +213,16 @@ export class KyveApi { private async updateCurrentBundleAndDetails( height: number, ): Promise { - let bundle = this.getBundleFromCache(height); + let bundle = await this.getBundleFromCache(height); if (!bundle) { + const bundleIds = Object.keys(this.cachedBundleDetails); const bundleId = - this.cachedBundleDetails.length !== 0 - ? Math.max( - ...this.cachedBundleDetails.map((b) => parseDecimal(b.id)), - ) + 1 + bundleIds.length !== 0 + ? Math.max(...bundleIds.map((key) => parseDecimal(key))) + 1 : await this.getBundleId(height); - bundle = await this.getBundleById(bundleId); - this.addToCachedBundle(bundle); + this.addToCachedBundle(bundleId.toString(), this.getBundleById(bundleId)); + + bundle = await this.cachedBundleDetails[bundleId]; } return JSON.parse(await this.getBundleData(bundle)); } @@ -310,32 +321,33 @@ export class KyveApi { } private async getToRemoveBundles( - cachedBundles: BundleDetails[], + cachedBundles: Record>, height: number, bufferSize: number, ): Promise { - if (!cachedBundles.length) { + if (!Object.keys(cachedBundles).length) { return this.getExistingBundlesFromCacheDirectory(this.tmpCacheDir); } - const currentBundle = this.getBundleFromCache(height); + const currentBundle = await this.getBundleFromCache(height); + if (!currentBundle) return []; + + const bundles = await Promise.all(Object.values(cachedBundles)); - return currentBundle - ? cachedBundles.filter((b) => { - const isNotCurrentBundleAndLower = - currentBundle.id !== b.id && - parseDecimal(currentBundle.id) > parseDecimal(b.id); - const isOutsiderBuffer = - height < parseDecimal(b.from_key) - bufferSize || - height > parseDecimal(b.to_key) + bufferSize; + return bundles.filter((b) => { + const isNotCurrentBundleAndLower = + currentBundle.id !== b.id && + parseDecimal(currentBundle.id) > parseDecimal(b.id); + const isOutsiderBuffer = + height < parseDecimal(b.from_key) - bufferSize || + height > parseDecimal(b.to_key) + bufferSize; - return isNotCurrentBundleAndLower && isOutsiderBuffer; - }) - : []; + return isNotCurrentBundleAndLower && isOutsiderBuffer; + }); } async clearFileCache( - cachedBundles: BundleDetails[], + cachedBundles: Record>, height: number, bufferSize: number, ): Promise { @@ -349,7 +361,7 @@ export class KyveApi { const bundlePath = this.getBundleFilePath(bundle.id); try { await fs.promises.unlink(bundlePath); - remove(this.cachedBundleDetails, (b) => b.id === bundle.id); + delete this.cachedBundleDetails[bundle.id]; } catch (e) { if (e.code !== 'ENOENT') { // if it does not exist, should be removed From 4e91cb3252949f74300d14154726f75a6ceb8aa9 Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:17:11 +1200 Subject: [PATCH 59/81] Fixes and improvements (#252) Co-authored-by: Scott Twiname --- packages/node/src/indexer/api.service.ts | 1 + packages/node/src/utils/kyve/kyve.spec.ts | 6 ++- packages/node/src/utils/kyve/kyve.ts | 62 ++++++++++------------- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 102c01e0a..60461782d 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -142,6 +142,7 @@ export class ApiService ); } catch (e) { logger.warn( + e, `Failed to fetch blocks: ${JSON.stringify( heights, )} via Kyve, switching to rpc`, diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 9e34ca7bf..7c90c11bd 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -82,6 +82,7 @@ describe('KyveApi', () => { const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); }); + beforeEach(async () => { retrieveBundleDataSpy = jest.spyOn(kyveApi as any, 'retrieveBundleData'); decoderBlockSpy = jest.spyOn(kyveApi as any, 'decodeBlock'); @@ -116,6 +117,7 @@ describe('KyveApi', () => { Promise >) = {}; }); + afterAll(async () => { await promisify(rimraf)(tmpPath); }); @@ -155,6 +157,7 @@ describe('KyveApi', () => { expect(firstBundle).toBe(0); expect(laterBundle).toBe(113773); }); + it('Able to write and read with parallel calls', async () => { const bundle_0Data = [ { @@ -257,6 +260,7 @@ describe('KyveApi', () => { Object.values((kyveApi as any).cachedBundleDetails), )) as BundleDetails[]; + // Because somethings in the cache bundle doesn't mean its downloaded or on disc for (const bundle of bundles) { const stats = await fs.promises.stat( (kyveApi as any).getBundleFilePath(bundle.id), @@ -284,7 +288,7 @@ describe('KyveApi', () => { expect(files).not.toContain('bundle_2_0.json'); }); it('Should increment bundleId when height exceeds cache', async () => { - (kyveApi as any).addToCachedBundle(0, (kyveApi as any).getBundleById(0)); + (kyveApi as any).cachedBundleDetails[0] = (kyveApi as any).getBundleById(0); jest.spyOn(kyveApi as any, 'getBundleData').mockResolvedValueOnce('{}'); await (kyveApi as any).updateCurrentBundleAndDetails(160); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 3ea5a36a6..eca65aea7 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -21,7 +21,6 @@ import { LocalReader } from '@subql/common'; import { delay, getLogger, IBlock } from '@subql/node-core'; import { Reader } from '@subql/types-core'; import axios, { AxiosResponse } from 'axios'; -import { remove } from 'lodash'; import { BlockContent } from '../../indexer/types'; import { formatBlockUtil, LazyBlockContent } from '../cosmos'; import { isTmpDir } from '../project'; @@ -46,7 +45,7 @@ interface KyveBundleData { } export class KyveApi { - private cachedBundleDetails: Record> = {}; + private cachedBundleDetails: Record> = {}; private constructor( private readonly storageUrl: string, @@ -122,12 +121,17 @@ export class KyveApi { } private async getBundleById(bundleId: number): Promise { - const bundleDetail = - await this.lcdClient.kyve.query.v1beta1.finalizedBundle({ + return (this.cachedBundleDetails[bundleId] ??= (() => { + logger.debug(`getBundleId ${bundleId}`); + return this.lcdClient.kyve.query.v1beta1.finalizedBundle({ pool_id: this.poolId, id: bundleId.toString(), - }); - return bundleDetail as BundleDetails; + }) as Promise; + })()); + } + + private async getResolvedBundleDetails(): Promise { + return Promise.all(Object.values(this.cachedBundleDetails)); } private async getLatestBundleId(): Promise { @@ -147,16 +151,13 @@ export class KyveApi { } private async getBundleId(height: number): Promise { - const latestBundleId = await this.getLatestBundleId(); - const lowestCacheHeight = Object.keys(this.cachedBundleDetails); let low = lowestCacheHeight.length > 0 - ? Math.min(...lowestCacheHeight.map((id) => parseDecimal(id))) + ? Math.min(...lowestCacheHeight.map(parseDecimal)) : -1; - let high = latestBundleId; - let startBundleId = -1; // Initialize to an invalid ID initially + let high = await this.getLatestBundleId(); while (low <= high) { const mid = Math.floor((low + high) / 2); @@ -166,8 +167,7 @@ export class KyveApi { const toKey = parseDecimal(midBundle.to_key); if (height >= fromKey && height <= toKey) { - startBundleId = mid; - return startBundleId; + return mid; } if (height > toKey) { @@ -176,7 +176,7 @@ export class KyveApi { high = mid - 1; } } - throw new Error(`No suitable bundle found for height ${height}}`); + throw new Error(`No suitable bundle found for height ${height}`); } private findBlockByHeight( @@ -188,22 +188,10 @@ export class KyveApi { ); } - private addToCachedBundle( - bundleId: string, - bundlePromise: Promise, - ): void { - // eslint-disable-next-line @typescript-eslint/no-misused-promises - if (!this.cachedBundleDetails[bundleId]) { - this.cachedBundleDetails[bundleId] = bundlePromise; - } - } - private async getBundleFromCache( height: number, ): Promise | undefined { - const bundles: BundleDetails[] = await Promise.all( - Object.values(this.cachedBundleDetails), - ); + const bundles = await this.getResolvedBundleDetails(); return bundles.find( (b) => parseDecimal(b.from_key) <= height && height <= parseDecimal(b.to_key), @@ -218,28 +206,30 @@ export class KyveApi { const bundleIds = Object.keys(this.cachedBundleDetails); const bundleId = bundleIds.length !== 0 - ? Math.max(...bundleIds.map((key) => parseDecimal(key))) + 1 + ? Math.max(...bundleIds.map(parseDecimal)) + 1 : await this.getBundleId(height); - this.addToCachedBundle(bundleId.toString(), this.getBundleById(bundleId)); - - bundle = await this.cachedBundleDetails[bundleId]; + bundle = await this.getBundleById(bundleId); } + return JSON.parse(await this.getBundleData(bundle)); } private async pollUntilReadable(bundleFilePath: string): Promise { - // eslint-disable-next-line no-constant-condition - while (true) { + // XXXX:SCOTT This limit can be removed if the timeout problem is resolved in downloadAndProcessBundle + let limit = 10; + while (limit > 0) { try { return await this.readFromFile(bundleFilePath); } catch (e) { if (e.code === 'EACCES') { await delay(POLL_TIMER); + limit--; } else { throw e; } } } + throw new Error('Timeout waiting for bundle'); } async downloadAndProcessBundle(bundle: BundleDetails): Promise { @@ -251,11 +241,12 @@ export class KyveApi { }); try { + // XXXX:SCOTT This can get stuck and not resolve, it seems a file can get stuck with permissions not reset (indexer restart) + // Its probably worth adding a timeout on this function await new Promise((resolve, reject) => { writeStream.on('open', resolve); writeStream.on('error', reject); }); - const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); const gunzip = zlib.createUnzip({ @@ -358,6 +349,7 @@ export class KyveApi { ); for (const bundle of toRemoveBundles) { + logger.debug(`Removing bundle ${bundle.id}`); const bundlePath = this.getBundleFilePath(bundle.id); try { await fs.promises.unlink(bundlePath); @@ -376,6 +368,8 @@ export class KyveApi { ): Promise<[BlockResponse, BlockResultsResponse]> { const blocks = await this.updateCurrentBundleAndDetails(height); const blockData = this.findBlockByHeight(height, blocks); + // XXXX:SCOTT blockData is regularly undefined, this should not happen and is not handled. + // TypeError: Cannot read properties of undefined (reading 'value') return [ this.decodeBlock(blockData.value.block), this.injectLogs(this.decodeBlockResult(blockData.value.block_results)), From 536771594cf3f4a18bbbb2a35107162aca4dbca4 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 23 Apr 2024 09:44:57 +0800 Subject: [PATCH 60/81] Fix cache gaps, added timeout on stream --- packages/node/src/utils/kyve/kyve.spec.ts | 18 +++++++- packages/node/src/utils/kyve/kyve.ts | 50 ++++++++++++++++++----- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 7c90c11bd..e3cb513c6 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -157,7 +157,23 @@ describe('KyveApi', () => { expect(firstBundle).toBe(0); expect(laterBundle).toBe(113773); }); - + it('Concurrent fetch with incrementing bundle id', async () => { + // should increment from bundle id 8 to 9 only calling binary search once + const binarySearchSpy = jest.spyOn(kyveApi as any, 'getBundleById'); + await Promise.all([ + kyveApi.getBlockByHeight(1338), + kyveApi.getBlockByHeight(1339), + kyveApi.getBlockByHeight(1350), + kyveApi.getBlockByHeight(1351), + ]); + const batch2 = await Promise.all([ + kyveApi.getBlockByHeight(1500), + kyveApi.getBlockByHeight(1501), + ]); + expect((kyveApi as any).cachedBundleDetails[10]).toBeDefined(); + expect(binarySearchSpy).toHaveBeenCalledTimes(4); + expect(batch2.length).toBe(2); + }); it('Able to write and read with parallel calls', async () => { const bundle_0Data = [ { diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index eca65aea7..8e480b0fe 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -151,6 +151,7 @@ export class KyveApi { } private async getBundleId(height: number): Promise { + logger.info(`Binary search used on height: ${height}`); const lowestCacheHeight = Object.keys(this.cachedBundleDetails); let low = @@ -202,13 +203,27 @@ export class KyveApi { height: number, ): Promise { let bundle = await this.getBundleFromCache(height); + if (!bundle) { const bundleIds = Object.keys(this.cachedBundleDetails); - const bundleId = - bundleIds.length !== 0 - ? Math.max(...bundleIds.map(parseDecimal)) + 1 - : await this.getBundleId(height); - bundle = await this.getBundleById(bundleId); + + let bundleId: number; + if (bundleIds.length === 0) { + bundleId = await this.getBundleId(height); + } else { + // + const cachedBundles = await this.getResolvedBundleDetails(); + const nearestBundle = cachedBundles.filter( + (b) => parseDecimal(b.to_key) < height, + ); + + bundleId = + Math.max(...nearestBundle.map((b) => parseDecimal(b.id))) + 1; + + this.cachedBundleDetails[bundleId] = this.getBundleById(bundleId); + } + + bundle = await this.cachedBundleDetails[bundleId]; } return JSON.parse(await this.getBundleData(bundle)); @@ -243,10 +258,16 @@ export class KyveApi { try { // XXXX:SCOTT This can get stuck and not resolve, it seems a file can get stuck with permissions not reset (indexer restart) // Its probably worth adding a timeout on this function - await new Promise((resolve, reject) => { - writeStream.on('open', resolve); - writeStream.on('error', reject); - }); + await Promise.race([ + new Promise((resolve, reject) => { + writeStream.on('open', resolve); + writeStream.on('error', reject); + }), + delay(5).then(() => { + throw new Error('Timeout: File stream did not open'); + }), + ]); + const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); const gunzip = zlib.createUnzip({ @@ -265,7 +286,14 @@ export class KyveApi { await fs.promises.chmod(bundleFilePath, 0o444); } catch (e) { - if (!['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { + if ( + !['EEXIST', 'EACCES', 'ENOENT'].includes(e.code) || + e.msg === 'Timeout: File stream did not open' + ) { + console.log( + 'write error is timeout on file', + e.msg === 'Timeout: File stream did not open', + ); await fs.promises.unlink(bundleFilePath); } throw e; @@ -368,8 +396,8 @@ export class KyveApi { ): Promise<[BlockResponse, BlockResultsResponse]> { const blocks = await this.updateCurrentBundleAndDetails(height); const blockData = this.findBlockByHeight(height, blocks); + assert(blockData, `Unable to retrieve block: ${height} from file cache.`); // XXXX:SCOTT blockData is regularly undefined, this should not happen and is not handled. - // TypeError: Cannot read properties of undefined (reading 'value') return [ this.decodeBlock(blockData.value.block), this.injectLogs(this.decodeBlockResult(blockData.value.block_results)), From a3e2e1ec6cccefc629eeebb48471ae5fbe033b7b Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Tue, 23 Apr 2024 02:27:38 +0000 Subject: [PATCH 61/81] Fixes and Improvements --- packages/node/src/utils/kyve/kyve.spec.ts | 4 +++- packages/node/src/utils/kyve/kyve.ts | 8 ++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index e3cb513c6..11609baba 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -159,7 +159,7 @@ describe('KyveApi', () => { }); it('Concurrent fetch with incrementing bundle id', async () => { // should increment from bundle id 8 to 9 only calling binary search once - const binarySearchSpy = jest.spyOn(kyveApi as any, 'getBundleById'); + const binarySearchSpy = jest.spyOn(kyveApi as any, 'getBundleId'); await Promise.all([ kyveApi.getBlockByHeight(1338), kyveApi.getBlockByHeight(1339), @@ -169,6 +169,8 @@ describe('KyveApi', () => { const batch2 = await Promise.all([ kyveApi.getBlockByHeight(1500), kyveApi.getBlockByHeight(1501), + // note: what happens if it jumps more than incremental bundle + // kyveApi.getBlockByHeight(4000) ]); expect((kyveApi as any).cachedBundleDetails[10]).toBeDefined(); expect(binarySearchSpy).toHaveBeenCalledTimes(4); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 8e480b0fe..1f74d404c 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -151,7 +151,6 @@ export class KyveApi { } private async getBundleId(height: number): Promise { - logger.info(`Binary search used on height: ${height}`); const lowestCacheHeight = Object.keys(this.cachedBundleDetails); let low = @@ -290,10 +289,6 @@ export class KyveApi { !['EEXIST', 'EACCES', 'ENOENT'].includes(e.code) || e.msg === 'Timeout: File stream did not open' ) { - console.log( - 'write error is timeout on file', - e.msg === 'Timeout: File stream did not open', - ); await fs.promises.unlink(bundleFilePath); } throw e; @@ -381,12 +376,13 @@ export class KyveApi { const bundlePath = this.getBundleFilePath(bundle.id); try { await fs.promises.unlink(bundlePath); - delete this.cachedBundleDetails[bundle.id]; } catch (e) { if (e.code !== 'ENOENT') { // if it does not exist, should be removed throw e; } + } finally { + delete this.cachedBundleDetails[bundle.id]; } } } From 96b2fbceea1b9716fb52af8eb4a40be06a9dad32 Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Tue, 23 Apr 2024 03:26:23 +0000 Subject: [PATCH 62/81] Update bundleId increment --- packages/node/src/utils/kyve/kyve.spec.ts | 13 ++++++----- packages/node/src/utils/kyve/kyve.ts | 28 +++++++++++------------ 2 files changed, 20 insertions(+), 21 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 11609baba..45d3a9ef9 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -169,12 +169,11 @@ describe('KyveApi', () => { const batch2 = await Promise.all([ kyveApi.getBlockByHeight(1500), kyveApi.getBlockByHeight(1501), - // note: what happens if it jumps more than incremental bundle - // kyveApi.getBlockByHeight(4000) + kyveApi.getBlockByHeight(4000), ]); expect((kyveApi as any).cachedBundleDetails[10]).toBeDefined(); expect(binarySearchSpy).toHaveBeenCalledTimes(4); - expect(batch2.length).toBe(2); + expect(batch2.length).toBe(3); }); it('Able to write and read with parallel calls', async () => { const bundle_0Data = [ @@ -274,9 +273,11 @@ describe('KyveApi', () => { expect(cachedBundles.length).toBe(3); expect(blocks.length).toBe(5); - const bundles = (await Promise.all( - Object.values((kyveApi as any).cachedBundleDetails), - )) as BundleDetails[]; + const bundles = (await Promise.all([ + (kyveApi as any).getBundleById(0), + (kyveApi as any).getBundleById(1), + (kyveApi as any).getBundleById(2), + ])) as BundleDetails[]; // Because somethings in the cache bundle doesn't mean its downloaded or on disc for (const bundle of bundles) { diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 1f74d404c..a64969381 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -18,7 +18,7 @@ import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; // Currently these types are not exported import { QueryPoolsResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; import { LocalReader } from '@subql/common'; -import { delay, getLogger, IBlock } from '@subql/node-core'; +import { delay, getLogger, IBlock, timeout } from '@subql/node-core'; import { Reader } from '@subql/types-core'; import axios, { AxiosResponse } from 'axios'; import { BlockContent } from '../../indexer/types'; @@ -209,8 +209,8 @@ export class KyveApi { let bundleId: number; if (bundleIds.length === 0) { bundleId = await this.getBundleId(height); + bundle = await this.cachedBundleDetails[bundleId]; } else { - // const cachedBundles = await this.getResolvedBundleDetails(); const nearestBundle = cachedBundles.filter( (b) => parseDecimal(b.to_key) < height, @@ -219,10 +219,13 @@ export class KyveApi { bundleId = Math.max(...nearestBundle.map((b) => parseDecimal(b.id))) + 1; - this.cachedBundleDetails[bundleId] = this.getBundleById(bundleId); - } + bundle = await this.getBundleById(bundleId); - bundle = await this.cachedBundleDetails[bundleId]; + while (parseDecimal(bundle.to_key) < height) { + bundleId++; + bundle = await this.getBundleById(bundleId); + } + } } return JSON.parse(await this.getBundleData(bundle)); @@ -257,15 +260,14 @@ export class KyveApi { try { // XXXX:SCOTT This can get stuck and not resolve, it seems a file can get stuck with permissions not reset (indexer restart) // Its probably worth adding a timeout on this function - await Promise.race([ + + await timeout( new Promise((resolve, reject) => { writeStream.on('open', resolve); writeStream.on('error', reject); }), - delay(5).then(() => { - throw new Error('Timeout: File stream did not open'); - }), - ]); + 5, + ); const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); @@ -282,13 +284,9 @@ export class KyveApi { .on('error', reject) .on('finish', resolve); }); - await fs.promises.chmod(bundleFilePath, 0o444); } catch (e) { - if ( - !['EEXIST', 'EACCES', 'ENOENT'].includes(e.code) || - e.msg === 'Timeout: File stream did not open' - ) { + if (!['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { await fs.promises.unlink(bundleFilePath); } throw e; From 5070979446a67d210268ad03bb7ebc9e5473eb50 Mon Sep 17 00:00:00 2001 From: bz888 Date: Tue, 23 Apr 2024 19:47:00 +0800 Subject: [PATCH 63/81] Fix for stale polling --- packages/node/src/utils/kyve/kyve.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index a64969381..cd7919fe2 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -232,7 +232,6 @@ export class KyveApi { } private async pollUntilReadable(bundleFilePath: string): Promise { - // XXXX:SCOTT This limit can be removed if the timeout problem is resolved in downloadAndProcessBundle let limit = 10; while (limit > 0) { try { @@ -246,6 +245,8 @@ export class KyveApi { } } } + + await fs.promises.chmod(bundleFilePath, '0o666'); // Reset permissions if polling exceeds throw new Error('Timeout waiting for bundle'); } @@ -266,7 +267,7 @@ export class KyveApi { writeStream.on('open', resolve); writeStream.on('error', reject); }), - 5, + BUNDLE_TIMEOUT, ); const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); @@ -282,11 +283,13 @@ export class KyveApi { .pipe(gunzip) .pipe(writeStream) .on('error', reject) - .on('finish', resolve); + .on('finish', async () => { + await fs.promises.chmod(bundleFilePath, 0o444); + resolve('Stream Completed'); + }); }); - await fs.promises.chmod(bundleFilePath, 0o444); } catch (e) { - if (!['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { + if (!['EEXIST', 'EACCES'].includes(e.code)) { await fs.promises.unlink(bundleFilePath); } throw e; @@ -299,7 +302,7 @@ export class KyveApi { await this.downloadAndProcessBundle(bundle); return await this.readFromFile(bundleFilePath); } catch (e: any) { - if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { + if (['EEXIST', 'EACCES'].includes(e.code)) { const res = await this.pollUntilReadable(bundleFilePath); return res; } else { From ee55964bfa896868e8ce99b5bff9a00f010df114 Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:45:32 +0000 Subject: [PATCH 64/81] fix chmod permission --- packages/node/src/utils/kyve/kyve.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index cd7919fe2..8d5d63da5 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -246,7 +246,7 @@ export class KyveApi { } } - await fs.promises.chmod(bundleFilePath, '0o666'); // Reset permissions if polling exceeds + await fs.promises.chmod(bundleFilePath, 0o666); // Reset permissions if polling exceeds throw new Error('Timeout waiting for bundle'); } From 56b245fec9db637b9125295efb622a3a6127ecd2 Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 24 Apr 2024 08:30:02 +0800 Subject: [PATCH 65/81] Fixes and improvements based on review --- packages/node/src/utils/kyve/kyve.ts | 114 +++++++++++++-------------- 1 file changed, 56 insertions(+), 58 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 8d5d63da5..71ecb0767 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -28,6 +28,7 @@ import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms const POLL_TIMER = 3; // sec +const POLL_LIMIT = 10; const MAX_COMPRESSION_BYTE_SIZE = 2 * 10 ** 9; const BUNDLE_FILE_ID_REG = (poolId: string) => new RegExp(`^bundle_${poolId}_(\\d+)\\.json$`); @@ -135,19 +136,38 @@ export class KyveApi { } private async getLatestBundleId(): Promise { - return ( - parseDecimal( - ( - await this.lcdClient.kyve.query.v1beta1.finalizedBundles({ - pool_id: this.poolId, - index: '1', - pagination: { - limit: '1', - }, - }) - ).pagination.total, - ) - 1 - ); // bundle id starts from 0 + return parseDecimal( + ( + await this.lcdClient.kyve.query.v1beta1.finalizedBundles({ + pool_id: this.poolId, + index: '1', + pagination: { + reverse: true, + limit: '1', + }, + }) + ).finalized_bundles[0].id, + ); + } + + private async bundleIdIterator(height: number): Promise { + let bundle: BundleDetails; + let bundleId: number; + + const cachedBundles = await this.getResolvedBundleDetails(); + const nearestBundle = cachedBundles.filter( + (b) => parseDecimal(b.to_key) < height, + ); + + bundleId = Math.max(...nearestBundle.map((b) => parseDecimal(b.id))) + 1; + + bundle = await this.getBundleById(bundleId); + + while (parseDecimal(bundle.to_key) < height) { + bundleId++; + bundle = await this.getBundleById(bundleId); + } + return parseDecimal(bundle.id); } private async getBundleId(height: number): Promise { @@ -206,33 +226,19 @@ export class KyveApi { if (!bundle) { const bundleIds = Object.keys(this.cachedBundleDetails); - let bundleId: number; - if (bundleIds.length === 0) { - bundleId = await this.getBundleId(height); - bundle = await this.cachedBundleDetails[bundleId]; - } else { - const cachedBundles = await this.getResolvedBundleDetails(); - const nearestBundle = cachedBundles.filter( - (b) => parseDecimal(b.to_key) < height, - ); - - bundleId = - Math.max(...nearestBundle.map((b) => parseDecimal(b.id))) + 1; + const bundleId = + bundleIds.length === 0 + ? await this.getBundleId(height) + : await this.bundleIdIterator(height); - bundle = await this.getBundleById(bundleId); - - while (parseDecimal(bundle.to_key) < height) { - bundleId++; - bundle = await this.getBundleById(bundleId); - } - } + bundle = await this.cachedBundleDetails[bundleId]; } return JSON.parse(await this.getBundleData(bundle)); } private async pollUntilReadable(bundleFilePath: string): Promise { - let limit = 10; + let limit = POLL_LIMIT; while (limit > 0) { try { return await this.readFromFile(bundleFilePath); @@ -246,7 +252,6 @@ export class KyveApi { } } - await fs.promises.chmod(bundleFilePath, 0o666); // Reset permissions if polling exceeds throw new Error('Timeout waiting for bundle'); } @@ -259,9 +264,6 @@ export class KyveApi { }); try { - // XXXX:SCOTT This can get stuck and not resolve, it seems a file can get stuck with permissions not reset (indexer restart) - // Its probably worth adding a timeout on this function - await timeout( new Promise((resolve, reject) => { writeStream.on('open', resolve); @@ -283,16 +285,17 @@ export class KyveApi { .pipe(gunzip) .pipe(writeStream) .on('error', reject) - .on('finish', async () => { - await fs.promises.chmod(bundleFilePath, 0o444); - resolve('Stream Completed'); - }); + .on('finish', resolve); }); } catch (e) { if (!['EEXIST', 'EACCES'].includes(e.code)) { await fs.promises.unlink(bundleFilePath); } throw e; + } finally { + // In order to prevent stalling on polling + // File permission should be set to readable regardless if the bundle retrieval is successful or not. + await fs.promises.chmod(bundleFilePath, 0o444); } } @@ -322,17 +325,18 @@ export class KyveApi { private async getExistingBundlesFromCacheDirectory( tmpDir: string, ): Promise { - const bundles: BundleDetails[] = []; const files = await fs.promises.readdir(tmpDir); - for (const file of files) { - if (this.isBundleFile(file)) { - const id = parseDecimal(file.match(BUNDLE_FILE_ID_REG(this.poolId))[1]); - bundles.push(await this.getBundleById(id)); - } - } - - return bundles; + return Promise.all( + files + .filter((file) => this.isBundleFile(file)) + .map((file) => { + const id = parseDecimal( + file.match(BUNDLE_FILE_ID_REG(this.poolId))[1], + ); + return this.getBundleById(id); + }), + ); } private async getToRemoveBundles( @@ -345,17 +349,13 @@ export class KyveApi { } const currentBundle = await this.getBundleFromCache(height); - if (!currentBundle) return []; - const bundles = await Promise.all(Object.values(cachedBundles)); return bundles.filter((b) => { const isNotCurrentBundleAndLower = currentBundle.id !== b.id && parseDecimal(currentBundle.id) > parseDecimal(b.id); - const isOutsiderBuffer = - height < parseDecimal(b.from_key) - bufferSize || - height > parseDecimal(b.to_key) + bufferSize; + const isOutsiderBuffer = height > parseDecimal(b.to_key) + bufferSize; return isNotCurrentBundleAndLower && isOutsiderBuffer; }); @@ -373,10 +373,10 @@ export class KyveApi { ); for (const bundle of toRemoveBundles) { - logger.debug(`Removing bundle ${bundle.id}`); const bundlePath = this.getBundleFilePath(bundle.id); try { await fs.promises.unlink(bundlePath); + logger.debug(`Removed bundle ${bundle.id}`); } catch (e) { if (e.code !== 'ENOENT') { // if it does not exist, should be removed @@ -393,8 +393,6 @@ export class KyveApi { ): Promise<[BlockResponse, BlockResultsResponse]> { const blocks = await this.updateCurrentBundleAndDetails(height); const blockData = this.findBlockByHeight(height, blocks); - assert(blockData, `Unable to retrieve block: ${height} from file cache.`); - // XXXX:SCOTT blockData is regularly undefined, this should not happen and is not handled. return [ this.decodeBlock(blockData.value.block), this.injectLogs(this.decodeBlockResult(blockData.value.block_results)), From cde6d33de4f8d9d29b474a9fbadbe1ace134bb3f Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Wed, 24 Apr 2024 05:28:00 +0000 Subject: [PATCH 66/81] Remove finally on download, fix reconstructed logs --- packages/node/src/utils/kyve/kyve.spec.ts | 21 ++++++ packages/node/src/utils/kyve/kyve.ts | 80 +++++++++++++---------- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 45d3a9ef9..cef369034 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -319,6 +319,27 @@ describe('KyveApi', () => { const [kyveBlockInfo] = await kyveApi.getBlockByHeight(height); expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); }); + it('Compare reconstructed logs and RPC logs', async () => { + const height = 4284742; + + const blocks = await (kyveApi as any).updateCurrentBundleAndDetails(height); + const blockData = (kyveApi as any).findBlockByHeight(height, blocks); + + const blockRes = (kyveApi as any).decodeBlockResult( + blockData.value.block_results, + ); + const rpcBlockResult = await tendermint.blockResults(height); + const reconstructedKyveBlock = (kyveApi as any).injectLogs(blockRes); + + expect(JSON.parse(reconstructedKyveBlock.results[0].log).length).toBe(1); + expect(JSON.parse(reconstructedKyveBlock.results[1].log).length).toBe(1); + + expect( + reconstructedKyveBlock.results[0].log.includes( + 'wasm-astrovault-ratio_pool_factory-update_direct_ratios', + ) && !reconstructedKyveBlock.results[0].log.includes('ibc_transfer'), + ).toBe(true); + }); it('determine correct pool', async () => { const lcdClient = new KyveSDK(KYVE_CHAINID, { rpc: KYVE_ENDPOINT, diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 71ecb0767..48c7f6bcc 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -9,11 +9,12 @@ import * as zlib from 'zlib'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; import { Registry } from '@cosmjs/proto-signing'; import { logs } from '@cosmjs/stargate'; -import { Responses } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; // adaptor is not exported import { BlockResponse, BlockResultsResponse, -} from '@cosmjs/tendermint-rpc/build/tendermint37/responses'; + TxData, +} from '@cosmjs/tendermint-rpc/build/tendermint37'; +import { Responses } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; // adaptor is not exported import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; // Currently these types are not exported import { QueryPoolsResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; @@ -252,6 +253,19 @@ export class KyveApi { } } + // on start up main thread + // check permission, remove permissions on stale files or remove them + // if file exists + // json parse fails + // should clean up file and re attempt download, this probs should be handled by future block in bundle + // + + // In order to prevent stalling on polling + // File permission should be set to readable regardless if the bundle retrieval is successful or not. + + // this hsould belong somewhere else + await fs.promises.chmod(bundleFilePath, 0o666); + throw new Error('Timeout waiting for bundle'); } @@ -278,7 +292,8 @@ export class KyveApi { maxOutputLength: MAX_COMPRESSION_BYTE_SIZE /* avoid zip bombs */, }); - logger.info(`Retrieving bundle ${bundle.id}`); + logger.debug(`Retrieving bundle ${bundle.id}`); + logger.info(`Fetching blocks ${bundle.from_key} to ${bundle.to_key}`); await new Promise((resolve, reject) => { zippedBundleData.data @@ -287,15 +302,15 @@ export class KyveApi { .on('error', reject) .on('finish', resolve); }); + + await fs.promises.chmod(bundleFilePath, 0o444); + + logger.debug(`Bundle ${bundle.id} ready`); } catch (e) { if (!['EEXIST', 'EACCES'].includes(e.code)) { await fs.promises.unlink(bundleFilePath); } throw e; - } finally { - // In order to prevent stalling on polling - // File permission should be set to readable regardless if the bundle retrieval is successful or not. - await fs.promises.chmod(bundleFilePath, 0o444); } } @@ -405,9 +420,7 @@ export class KyveApi { try { kyveBlockResult.results.forEach((b) => { // log is readonly hence needing to cast it - (b.log as string) = JSON.stringify( - this.reconstructLogs(kyveBlockResult), - ); + (b.log as string) = JSON.stringify(this.reconstructLog(b)); }); } catch (e) { throw new Error(`Failed to inject kyveBlock, ${e}`); @@ -415,40 +428,37 @@ export class KyveApi { return kyveBlockResult; } - private reconstructLogs( - blockResultResponse: BlockResultsResponse, - ): logs.Log[] { + private reconstructLog(txData: TxData): logs.Log[] { const logs: logs.Log[] = []; - for (const tx of blockResultResponse.results) { - let currentLog: any = { - msg_index: -1, - events: [], - }; - - let msgIndex = -1; - for (const event of tx.events) { - const isMessageEvent = - event.type === 'message' && - event.attributes.some((e) => e.key === 'action'); - - if (isMessageEvent) { - if (msgIndex >= 0) { - logs.push(currentLog); - } - msgIndex += 1; - currentLog = { msg_index: msgIndex, events: [] }; - } + let currentLog: any = { + msg_index: -1, + events: [], + }; + + let msgIndex = -1; + for (const event of txData.events) { + const isMessageEvent = + event.type === 'message' && + event.attributes.some((e) => e.key === 'action'); + if (isMessageEvent) { if (msgIndex >= 0) { - currentLog.events.push(event); + logs.push(currentLog); } + msgIndex += 1; + currentLog = { msg_index: msgIndex, events: [] }; } - if (currentLog.events.length > 0) { - logs.push(currentLog); + if (msgIndex >= 0) { + currentLog.events.push(event); } } + + if (currentLog.events.length > 0) { + logs.push(currentLog); + } + return logs; } From fc3a1594d64056b18fdad0a6bebcf009e13ceb75 Mon Sep 17 00:00:00 2001 From: bz888 Date: Wed, 24 Apr 2024 15:52:11 +0800 Subject: [PATCH 67/81] add stale file remover --- packages/node/src/utils/kyve/kyve.spec.ts | 4 +- packages/node/src/utils/kyve/kyve.ts | 50 +++++++++++++++++------ 2 files changed, 39 insertions(+), 15 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index cef369034..2f62a9ccc 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -443,8 +443,8 @@ describe('KyveApi', () => { const bundle = 'bundle_2_0.json'; const notBundle = 'data.json'; - expect((kyveApi as any).isBundleFile(bundle)).toBe(true); - expect((kyveApi as any).isBundleFile(notBundle)).toBe(false); + expect((KyveApi as any).isBundleFile(bundle, '2')).toBe(true); + expect((KyveApi as any).isBundleFile(notBundle, '2')).toBe(false); }); it('clear existing bundle files in directory when outside buffer', async () => { await fs.promises.writeFile((kyveApi as any).getBundleFilePath(0), 'mock'); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 48c7f6bcc..1068d895c 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -3,6 +3,7 @@ import assert from 'assert'; import fs from 'fs'; +import { isMainThread } from 'node:worker_threads'; import os from 'os'; import path from 'path'; import * as zlib from 'zlib'; @@ -73,6 +74,8 @@ export class KyveApi { const poolId = await KyveApi.fetchPoolId(chainId, lcdClient); + await KyveApi.clearStaleFiles(tmpCacheDir, poolId); + logger.info(`Kyve API connected`); return new KyveApi(storageUrl, tmpCacheDir, poolId, lcdClient); } @@ -100,6 +103,38 @@ export class KyveApi { throw new Error(`${chainId} is not available on Kyve network`); } + private static async clearStaleFiles( + fileCacheDir: string, + poolId: string, + ): Promise { + if (isMainThread) { + const files = await fs.promises.readdir(fileCacheDir); + + const isStale = async (file: string) => + ((await fs.promises.stat(file)).mode & 0o777).toString(8) === '200'; + + files + .filter((f) => KyveApi.isBundleFile(f, poolId)) + .map(async (bundleFile) => { + if (await isStale(bundleFile)) { + try { + logger.debug(`Removing stale bundle: ${bundleFile}`); + await fs.promises.unlink(bundleFile); + } catch (e) { + if (e.code !== 'ENOENT') { + logger.error(`Failed to clear bundle: ${bundleFile}`); + throw e; + } + } + } + }); + } + } + + private static isBundleFile(filename: string, poolId: string): boolean { + return BUNDLE_FILE_ID_REG(poolId).test(filename); + } + private decodeBlock(block: JsonRpcSuccessResponse): BlockResponse { return Responses.decodeBlock({ id: 1, @@ -253,19 +288,11 @@ export class KyveApi { } } - // on start up main thread - // check permission, remove permissions on stale files or remove them // if file exists // json parse fails // should clean up file and re attempt download, this probs should be handled by future block in bundle - // - - // In order to prevent stalling on polling - // File permission should be set to readable regardless if the bundle retrieval is successful or not. // this hsould belong somewhere else - await fs.promises.chmod(bundleFilePath, 0o666); - throw new Error('Timeout waiting for bundle'); } @@ -324,6 +351,7 @@ export class KyveApi { const res = await this.pollUntilReadable(bundleFilePath); return res; } else { + await fs.promises.unlink(bundleFilePath).catch(); throw e; } } @@ -333,10 +361,6 @@ export class KyveApi { return fs.promises.readFile(bundleFilePath, 'utf-8'); } - private isBundleFile(filename: string): boolean { - return BUNDLE_FILE_ID_REG(this.poolId).test(filename); - } - private async getExistingBundlesFromCacheDirectory( tmpDir: string, ): Promise { @@ -344,7 +368,7 @@ export class KyveApi { return Promise.all( files - .filter((file) => this.isBundleFile(file)) + .filter((file) => KyveApi.isBundleFile(file, this.poolId)) .map((file) => { const id = parseDecimal( file.match(BUNDLE_FILE_ID_REG(this.poolId))[1], From bd129757da83f4864de86294656e5945add26847 Mon Sep 17 00:00:00 2001 From: bz888 Date: Thu, 25 Apr 2024 09:31:54 +0800 Subject: [PATCH 68/81] tidy up --- packages/node/src/utils/kyve/kyve.ts | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 1068d895c..6643471d6 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -287,12 +287,6 @@ export class KyveApi { } } } - - // if file exists - // json parse fails - // should clean up file and re attempt download, this probs should be handled by future block in bundle - - // this hsould belong somewhere else throw new Error('Timeout waiting for bundle'); } @@ -347,13 +341,12 @@ export class KyveApi { await this.downloadAndProcessBundle(bundle); return await this.readFromFile(bundleFilePath); } catch (e: any) { - if (['EEXIST', 'EACCES'].includes(e.code)) { + if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { const res = await this.pollUntilReadable(bundleFilePath); return res; - } else { - await fs.promises.unlink(bundleFilePath).catch(); - throw e; } + await fs.promises.unlink(bundleFilePath).catch(); + throw e; } } From ee3f72728766ebc3c9d0775b1bf65244c4667661 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 26 Apr 2024 06:55:29 +0800 Subject: [PATCH 69/81] add log --- packages/node/src/indexer/api.service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 60461782d..67e047d98 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -120,7 +120,7 @@ export class ApiService this.project.fileCacheDir, ); } catch (e) { - logger.warn(`${e}`); + logger.warn(`Kyve Api is not connection. ${e}`); } } From c1e1b6dfb029b8c958191e61274768da11709788 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 26 Apr 2024 09:56:39 +0800 Subject: [PATCH 70/81] tidy up based on review, add test --- packages/node/src/utils/kyve/kyve.spec.ts | 30 ++++++++-- packages/node/src/utils/kyve/kyve.ts | 72 +++++++++++++---------- 2 files changed, 66 insertions(+), 36 deletions(-) diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 2f62a9ccc..9f64e146e 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -64,6 +64,7 @@ describe('KyveApi', () => { let decoderBlockSpy: jest.SpyInstance; let injectLogSpy: jest.SpyInstance; let readerSpy: jest.SpyInstance; + let getBundleDataSpy: jest.SpyInstance; let zippedMockResp: Buffer; let mockStream: Readable; @@ -89,6 +90,7 @@ describe('KyveApi', () => { decoderBlockResultsSpy = jest.spyOn(kyveApi as any, 'decodeBlockResult'); injectLogSpy = jest.spyOn(kyveApi as any, 'injectLogs'); readerSpy = jest.spyOn(kyveApi as any, 'readFromFile'); + getBundleDataSpy = jest.spyOn(kyveApi as any, 'getBundleData'); zippedMockResp = gzipSync(Buffer.from(JSON.stringify(block_3856726))); mockStream = new Readable({ @@ -110,6 +112,7 @@ describe('KyveApi', () => { decoderBlockResultsSpy.mockRestore(); injectLogSpy.mockRestore(); readerSpy.mockRestore(); + getBundleDataSpy.mockRestore(); // reset cache ((kyveApi as any).cachedBundleDetails as Record< @@ -149,17 +152,32 @@ describe('KyveApi', () => { it('ensure correct bundle ID on binary search', async () => { (kyveApi as any).currentBundleId = -1; // reset cached bundle Id const a = Date.now(); - const firstBundle = await (kyveApi as any).getBundleId(120); // https://app.kyve.network/#/pools/2/bundles/0 + const firstBundle = await (kyveApi as any).getBundleIdSearch(120); // https://app.kyve.network/#/pools/2/bundles/0 const b = Date.now(); console.log(`${b - a}ms`); - const laterBundle = await (kyveApi as any).getBundleId(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 + const laterBundle = await (kyveApi as any).getBundleIdSearch(3489747); // https://app.kyve.network/#/pools/2/bundles/5149474 expect(firstBundle).toBe(0); expect(laterBundle).toBe(113773); }); + it('Ensure bundleId is defined', async () => { + getBundleDataSpy.mockResolvedValue(JSON.stringify({ mock: 'value' })); + + await Promise.all([ + (kyveApi as any).updateCurrentBundleAndDetails(1), + (kyveApi as any).updateCurrentBundleAndDetails(150), + (kyveApi as any).updateCurrentBundleAndDetails(151), + (kyveApi as any).updateCurrentBundleAndDetails(500), + (kyveApi as any).updateCurrentBundleAndDetails(1000), + (kyveApi as any).updateCurrentBundleAndDetails(2500), + ]); + + expect(getBundleDataSpy).toHaveBeenCalledTimes(6); + expect(getBundleDataSpy).not.toHaveBeenCalledWith(undefined); + }); it('Concurrent fetch with incrementing bundle id', async () => { // should increment from bundle id 8 to 9 only calling binary search once - const binarySearchSpy = jest.spyOn(kyveApi as any, 'getBundleId'); + const binarySearchSpy = jest.spyOn(kyveApi as any, 'getBundleIdSearch'); await Promise.all([ kyveApi.getBlockByHeight(1338), kyveApi.getBlockByHeight(1339), @@ -466,9 +484,9 @@ describe('KyveApi', () => { 'bundle_1_0.json', ]; - expect(files.filter((f) => (kyveApi as any).isBundleFile(f)).length).toBe( - 4, - ); + expect( + files.filter((f) => (KyveApi as any).isBundleFile(f, '2')).length, + ).toBe(4); }); describe('able to wrap kyveBlock', () => { let rpcLazyBlockContent: LazyBlockContent; diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 6643471d6..cf911bfb1 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -110,24 +110,26 @@ export class KyveApi { if (isMainThread) { const files = await fs.promises.readdir(fileCacheDir); - const isStale = async (file: string) => - ((await fs.promises.stat(file)).mode & 0o777).toString(8) === '200'; - - files - .filter((f) => KyveApi.isBundleFile(f, poolId)) - .map(async (bundleFile) => { - if (await isStale(bundleFile)) { - try { - logger.debug(`Removing stale bundle: ${bundleFile}`); - await fs.promises.unlink(bundleFile); - } catch (e) { - if (e.code !== 'ENOENT') { - logger.error(`Failed to clear bundle: ${bundleFile}`); - throw e; - } - } + const isStaleBundle = async (file: string) => { + try { + const isStale = + ((await fs.promises.stat(file)).mode & 0o777).toString(8) === '200'; + if (isStale) { + logger.debug(`Removing stale bundle: ${file}`); + await fs.promises.unlink(file); + } + } catch (e) { + if (e.code !== 'ENOENT') { + logger.error(`Failed to clear bundle: ${file}`); + throw e; } - }); + } + }; + await Promise.all( + files + .filter((f) => KyveApi.isBundleFile(f, poolId)) + .map((bundleFile) => isStaleBundle(bundleFile)), + ); } } @@ -186,7 +188,11 @@ export class KyveApi { ); } - private async bundleIdIterator(height: number): Promise { + /** + * Find bundleID based on height + * @description Increment bundleId by 1 until height is found in bundle + */ + private async getBundleIdIncrement(height: number): Promise { let bundle: BundleDetails; let bundleId: number; @@ -206,7 +212,11 @@ export class KyveApi { return parseDecimal(bundle.id); } - private async getBundleId(height: number): Promise { + /** + * Find bundleID based on height + * @description Binary search to find height in bundle + */ + private async getBundleIdSearch(height: number): Promise { const lowestCacheHeight = Object.keys(this.cachedBundleDetails); let low = @@ -264,8 +274,8 @@ export class KyveApi { const bundleId = bundleIds.length === 0 - ? await this.getBundleId(height) - : await this.bundleIdIterator(height); + ? await this.getBundleIdSearch(height) + : await this.getBundleIdIncrement(height); bundle = await this.cachedBundleDetails[bundleId]; } @@ -329,23 +339,30 @@ export class KyveApi { logger.debug(`Bundle ${bundle.id} ready`); } catch (e) { if (!['EEXIST', 'EACCES'].includes(e.code)) { - await fs.promises.unlink(bundleFilePath); + await this.unlinkFile(bundleFilePath); } throw e; } } + private async unlinkFile(file: string): Promise { + await fs.promises.unlink(file).catch((e) => { + // If file does not exist, no need to remove + if (e.code !== 'ENOENT') throw e; + }); + } + private async getBundleData(bundle: BundleDetails): Promise { const bundleFilePath = this.getBundleFilePath(bundle.id); try { await this.downloadAndProcessBundle(bundle); return await this.readFromFile(bundleFilePath); } catch (e: any) { - if (['EEXIST', 'EACCES', 'ENOENT'].includes(e.code)) { + if (['EEXIST', 'EACCES'].includes(e.code)) { const res = await this.pollUntilReadable(bundleFilePath); return res; } - await fs.promises.unlink(bundleFilePath).catch(); + await this.unlinkFile(bundleFilePath); throw e; } } @@ -407,13 +424,8 @@ export class KyveApi { for (const bundle of toRemoveBundles) { const bundlePath = this.getBundleFilePath(bundle.id); try { - await fs.promises.unlink(bundlePath); + await this.unlinkFile(bundlePath); logger.debug(`Removed bundle ${bundle.id}`); - } catch (e) { - if (e.code !== 'ENOENT') { - // if it does not exist, should be removed - throw e; - } } finally { delete this.cachedBundleDetails[bundle.id]; } From 8d0a87b0b1e1faa725dcc609feb909f8cb342841 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 26 Apr 2024 10:40:04 +0800 Subject: [PATCH 71/81] update unlink file; --- packages/node/CHANGELOG.md | 2 +- packages/node/src/utils/kyve/kyve.ts | 29 +++++++++++++++------------- packages/node/src/yargs.ts | 1 + 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/packages/node/CHANGELOG.md b/packages/node/CHANGELOG.md index f76adbc47..8bd13f31b 100644 --- a/packages/node/CHANGELOG.md +++ b/packages/node/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Support for KYVE integration with supporting flags (#235) - - `--kyve-endpoint` + - `--kyve-endpoint` (default value is `https://api-us-1.kyve.network`) - `--kyve-chain-id` (default value is `kyve-1`) - `--kyve-storage-url` (default value is `https://arweave.net`) diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index cf911bfb1..ae4a0cfca 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -115,14 +115,10 @@ export class KyveApi { const isStale = ((await fs.promises.stat(file)).mode & 0o777).toString(8) === '200'; if (isStale) { - logger.debug(`Removing stale bundle: ${file}`); - await fs.promises.unlink(file); + await KyveApi.unlinkFile(file, `Removed stale bundle: ${file}`); } } catch (e) { - if (e.code !== 'ENOENT') { - logger.error(`Failed to clear bundle: ${file}`); - throw e; - } + if (e.code !== 'ENOENT') throw e; } }; await Promise.all( @@ -339,17 +335,25 @@ export class KyveApi { logger.debug(`Bundle ${bundle.id} ready`); } catch (e) { if (!['EEXIST', 'EACCES'].includes(e.code)) { - await this.unlinkFile(bundleFilePath); + await KyveApi.unlinkFile(bundleFilePath); } throw e; } } - private async unlinkFile(file: string): Promise { - await fs.promises.unlink(file).catch((e) => { + private static async unlinkFile( + file: string, + loggerMsg?: string, + ): Promise { + try { + await fs.promises.unlink(file); + if (loggerMsg) { + logger.debug(loggerMsg); + } + } catch (e) { // If file does not exist, no need to remove if (e.code !== 'ENOENT') throw e; - }); + } } private async getBundleData(bundle: BundleDetails): Promise { @@ -362,7 +366,7 @@ export class KyveApi { const res = await this.pollUntilReadable(bundleFilePath); return res; } - await this.unlinkFile(bundleFilePath); + await KyveApi.unlinkFile(bundleFilePath); throw e; } } @@ -424,8 +428,7 @@ export class KyveApi { for (const bundle of toRemoveBundles) { const bundlePath = this.getBundleFilePath(bundle.id); try { - await this.unlinkFile(bundlePath); - logger.debug(`Removed bundle ${bundle.id}`); + await KyveApi.unlinkFile(bundlePath, `Removed bundle ${bundle.id}`); } finally { delete this.cachedBundleDetails[bundle.id]; } diff --git a/packages/node/src/yargs.ts b/packages/node/src/yargs.ts index e59378528..ac77e1155 100644 --- a/packages/node/src/yargs.ts +++ b/packages/node/src/yargs.ts @@ -34,6 +34,7 @@ export const yargsOptions = yargsBuilder({ describe: 'If indexing a network that Kyve supports adding a Kyve LCD endpoint will fetch blocks from Kyve', type: 'string', + default: 'https://api-us-1.kyve.network', }, 'kyve-storage-url': { demandOption: false, From f4ba219adca87ccdc6daf6bfc602d27882bcb052 Mon Sep 17 00:00:00 2001 From: Ben <89335033+bz888@users.noreply.github.com> Date: Fri, 26 Apr 2024 03:52:49 +0000 Subject: [PATCH 72/81] tidy up and add test for stale cleaner, disable kyve with false --- packages/node/CHANGELOG.md | 2 +- packages/node/src/indexer/api.service.ts | 9 +++++++-- packages/node/src/utils/kyve/kyve.spec.ts | 14 +++++++++++++- packages/node/src/utils/kyve/kyve.ts | 11 +++++++++-- packages/node/src/yargs.ts | 2 +- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/node/CHANGELOG.md b/packages/node/CHANGELOG.md index 8bd13f31b..4db018f0a 100644 --- a/packages/node/CHANGELOG.md +++ b/packages/node/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] ### Added - Support for KYVE integration with supporting flags (#235) - - `--kyve-endpoint` (default value is `https://api-us-1.kyve.network`) + - `--kyve-endpoint` (default value is `https://api-us-1.kyve.network`, To disable use `false`) - `--kyve-chain-id` (default value is `kyve-1`) - `--kyve-storage-url` (default value is `https://arweave.net`) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 67e047d98..59bbbaaf3 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -110,7 +110,10 @@ export class ApiService }, ); - if (this.nodeConfig.kyveEndpoint) { + if ( + this.nodeConfig.kyveEndpoint && + this.nodeConfig.kyveEndpoint !== 'false' + ) { try { this.kyveApi = await KyveApi.create( network.chainId, @@ -120,8 +123,10 @@ export class ApiService this.project.fileCacheDir, ); } catch (e) { - logger.warn(`Kyve Api is not connection. ${e}`); + logger.warn(`Kyve Api is not connected. ${e}`); } + } else { + logger.info(`Kyve not connected`); } return this; diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 9f64e146e..ab0365228 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -321,9 +321,21 @@ describe('KyveApi', () => { }); const files = await fs.promises.readdir(tmpPath); - expect(files).not.toContain('bundle_2_0.json'); }); + it('Able to clear stale files', async () => { + const bundlePath = (kyveApi as any).getBundleFilePath(0); + await fs.promises.writeFile(bundlePath, 'mock'); + await fs.promises.chmod(bundlePath, 0o200); + + await (KyveApi as any).clearStaleFiles(tmpPath, '2'); + + const isExist = await fs.promises + .access(bundlePath) + .then(() => true) + .catch(() => false); + expect(isExist).toBe(false); + }); it('Should increment bundleId when height exceeds cache', async () => { (kyveApi as any).cachedBundleDetails[0] = (kyveApi as any).getBundleById(0); jest.spyOn(kyveApi as any, 'getBundleData').mockResolvedValueOnce('{}'); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index ae4a0cfca..65b2cabd5 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -112,10 +112,17 @@ export class KyveApi { const isStaleBundle = async (file: string) => { try { + const bundlePath = path.join(fileCacheDir, file); + const isStale = - ((await fs.promises.stat(file)).mode & 0o777).toString(8) === '200'; + ((await fs.promises.stat(bundlePath)).mode & 0o777).toString(8) === + '200'; + if (isStale) { - await KyveApi.unlinkFile(file, `Removed stale bundle: ${file}`); + await KyveApi.unlinkFile( + bundlePath, + `Removed stale bundle: ${file}`, + ); } } catch (e) { if (e.code !== 'ENOENT') throw e; diff --git a/packages/node/src/yargs.ts b/packages/node/src/yargs.ts index ac77e1155..9592a197c 100644 --- a/packages/node/src/yargs.ts +++ b/packages/node/src/yargs.ts @@ -32,7 +32,7 @@ export const yargsOptions = yargsBuilder({ 'kyve-endpoint': { demandOption: false, describe: - 'If indexing a network that Kyve supports adding a Kyve LCD endpoint will fetch blocks from Kyve', + 'If indexing a network that Kyve supports adding a Kyve LCD endpoint will fetch blocks from Kyve. Use `false` to disable kyve.', type: 'string', default: 'https://api-us-1.kyve.network', }, From 81ff31be3a89fa4cdf16b1ce9bb689e2e2415f78 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 26 Apr 2024 12:00:20 +0800 Subject: [PATCH 73/81] update yarn.lock --- yarn.lock | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index 420c811f2..4b17e15fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3695,12 +3695,14 @@ __metadata: languageName: node linkType: hard -"@graphql-typed-document-node/core@npm:^3.1.1": - version: 3.2.0 - resolution: "@graphql-typed-document-node/core@npm:3.2.0" - peerDependencies: - graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 - checksum: fa44443accd28c8cf4cb96aaaf39d144a22e8b091b13366843f4e97d19c7bfeaf609ce3c7603a4aeffe385081eaf8ea245d078633a7324c11c5ec4b2011bb76d +"@ethersproject/bignumber@npm:5.7.0, @ethersproject/bignumber@npm:^5.7.0": + version: 5.7.0 + resolution: "@ethersproject/bignumber@npm:5.7.0" + dependencies: + "@ethersproject/bytes": ^5.7.0 + "@ethersproject/logger": ^5.7.0 + bn.js: ^5.2.1 + checksum: 8c9a134b76f3feb4ec26a5a27379efb4e156b8fb2de0678a67788a91c7f4e30abe9d948638458e4b20f2e42380da0adacc7c9389d05fce070692edc6ae9b4904 languageName: node linkType: hard @@ -4103,7 +4105,7 @@ __metadata: languageName: node linkType: hard -"@graphql-typed-document-node/core@npm:^3.0.0, @graphql-typed-document-node/core@npm:^3.1.1": +"@graphql-typed-document-node/core@npm:^3.1.1": version: 3.2.0 resolution: "@graphql-typed-document-node/core@npm:3.2.0" peerDependencies: From e5c0e670909227147c151b35784e90c34804668e Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 26 Apr 2024 18:19:37 +0800 Subject: [PATCH 74/81] update tests with non prune block --- packages/node/src/utils/kyve/kyve.spec.ts | 33 +- packages/node/test/block_3266772.json | 869 --- .../node/test/kyve_block/block_3856726.json | 3822 ------------- .../node/test/kyve_block/block_4326863.json | 4902 +++++++++++++++++ 4 files changed, 4912 insertions(+), 4714 deletions(-) delete mode 100644 packages/node/test/block_3266772.json delete mode 100644 packages/node/test/kyve_block/block_3856726.json create mode 100644 packages/node/test/kyve_block/block_4326863.json diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index ab0365228..29583a259 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -44,9 +44,9 @@ const wasmTypes: ReadonlyArray<[string, GeneratedType]> = [ const kyveBundlePath = path.join( __dirname, - '../../../test/kyve_block/block_3856726.json', + '../../../test/kyve_block/block_4326863.json', ); -const block_3856726 = require(kyveBundlePath); +const block_4326863 = require(kyveBundlePath); const KYVE_ENDPOINT = 'https://rpc-eu-1.kyve.network'; const KYVE_STORAGE_URL = 'https://arweave.net'; @@ -92,7 +92,7 @@ describe('KyveApi', () => { readerSpy = jest.spyOn(kyveApi as any, 'readFromFile'); getBundleDataSpy = jest.spyOn(kyveApi as any, 'getBundleData'); - zippedMockResp = gzipSync(Buffer.from(JSON.stringify(block_3856726))); + zippedMockResp = gzipSync(Buffer.from(JSON.stringify(block_4326863))); mockStream = new Readable({ read() { this.push(zippedMockResp); @@ -344,7 +344,7 @@ describe('KyveApi', () => { expect((kyveApi as any).cachedBundleDetails['1']).toBeDefined(); }); it('compare block info', async () => { - const height = 3901476; + const height = 4282099; const tendermintBlockInfo = await tendermint.block(height); const [kyveBlockInfo] = await kyveApi.getBlockByHeight(height); expect(isEqual(tendermintBlockInfo, kyveBlockInfo)).toBe(true); @@ -424,7 +424,7 @@ describe('KyveApi', () => { }); it('Able to poll with simulated workers', async () => { const mockCacheDetails = { - '130265': (kyveApi as any).getBundleById(130265), + '151003': (kyveApi as any).getBundleById(151003), }; (kyveApi as any).cachedBundleDetails = mockCacheDetails; @@ -464,10 +464,10 @@ describe('KyveApi', () => { expect(pollSpy).toHaveBeenCalledTimes(1); const r = await kyveApi.readFromFile( - (kyveApi as any).getBundleFilePath('130265'), + (kyveApi as any).getBundleFilePath('151003'), ); - expect(r).toEqual(JSON.stringify(block_3856726)); + expect(r).toEqual(JSON.stringify(block_4326863)); }); it('isBundle', () => { const bundle = 'bundle_2_0.json'; @@ -507,14 +507,14 @@ describe('KyveApi', () => { let tendermintBlockResult: BlockResultsResponse; beforeAll(async () => { - const height = 3856726; + const height = 4326863; [tendermintBlockInfo, tendermintBlockResult] = await Promise.all([ tendermint.block(height), tendermint.blockResults(height), ]); - const blockInfo = block_3856726[0].value.block; - const blockResults = block_3856726[0].value.block_results; + const blockInfo = block_4326863[0].value.block; + const blockResults = block_4326863[0].value.block_results; const bi = (kyveApi as any).decodeBlock(blockInfo); const br = (kyveApi as any).decodeBlockResult(blockResults); @@ -526,19 +526,6 @@ describe('KyveApi', () => { ); kyveLazyBlockContent = new LazyBlockContent(bi, br, registry); }); - it('compare kyve wrapped results with rpc results', () => { - const blockResults = block_3856726[0].value.block_results; - - const br = (kyveApi as any).decodeBlockResult(blockResults); - - const logs = (kyveApi as any).reconstructLogs(br); - expect(logs.length).toBe(2); - expect(logs[0].events.length).toBe(3); - expect(logs[1].events.length).toBe(5); - - const reconstructedKyveBlock = (kyveApi as any).injectLogs(br); - expect(reconstructedKyveBlock.results[0].log).toBeDefined(); - }); it('wrapTransaction', () => { expect(kyveLazyBlockContent.transactions[0].tx.data.length).toBe( rpcLazyBlockContent.transactions[0].tx.data.length, diff --git a/packages/node/test/block_3266772.json b/packages/node/test/block_3266772.json deleted file mode 100644 index 16963165d..000000000 --- a/packages/node/test/block_3266772.json +++ /dev/null @@ -1,869 +0,0 @@ -{ - "block_id": { - "hash": "9342E4F1D02326553D0BCCC4AEF78DB225A9A8CB1748B791A50DE29A6834B77A", - "parts": { - "total": 1, - "hash": "24D7190EA8364B629EA41C39766CC2A38D257E782500F320BA2368610ABEFCD3" - } - }, - "block": { - "header": { - "version": { - "block": "11" - }, - "chain_id": "juno-1", - "height": "3266772", - "time": "2022-05-27T07:37:37.536792362Z", - "last_block_id": { - "hash": "6403C5369ACD243F7AB01A7B577D41FC86C4E17131EB8B1ED58B1062A107A105", - "parts": { - "total": 1, - "hash": "FF9BCC40D3B805E30364C1576DD5A0C84ED4507CDA663BD8A50385B64601CC18" - } - }, - "last_commit_hash": "DBD1464F143E2C837D3B255973A4C7AAC6F84AD1AB11C48510A96EFE9B896745", - "data_hash": "E09806172DA252B7A14531C4BCB8F09A0E190C7F7C5C53487430D278289D91F8", - "validators_hash": "63FFEA17EF4CF4BCF1B64E682AB05D6C98BE63AA6B3BA74BD69E64EA5FCCF501", - "next_validators_hash": "63FFEA17EF4CF4BCF1B64E682AB05D6C98BE63AA6B3BA74BD69E64EA5FCCF501", - "consensus_hash": "1BF2556CA5D5D7EFFB540F34CB0FFC77A3202E32275557AFBD219882A9E42ACF", - "app_hash": "4BB3BFB8CA08F5A8B4C982D05D95F70CF6F803BF6A8588B502E12CC356CACBF1", - "last_results_hash": "6AADE361EA66579FE4F8041D941C1BC458B8377E11572F5996F0BCD2BEF9C75A", - "evidence_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", - "proposer_address": "1470B9237056641663CB4DFDEC86B064578B29BF" - }, - "data": { - "txs": [ - "CpkECpECCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QS6AEKK2p1bm8xc2hlM21wcDQza3E4ank5ZTkzOGV0dnByOXRrbmR2aHZ2ZnJhOXYSP2p1bm8xNXUzZHQ3OXQ2c3h4YTN4M2twa2h6c3k1NmVkYWE1YTY2d3Z0M2t4bXVrcWp6MnN4MGhlczVzbjM4Zxp4eyJpbmNyZWFzZV9hbGxvd2FuY2UiOnsiYW1vdW50IjoiMjgxNDAyOTMiLCJzcGVuZGVyIjoianVubzEyNGQwenltcmtkeHY3MmNjeXVxcnF1dXI4ZGtlc214bXgydW5mbjdkZWo5NXlxeDV5bjhzNzB4M3lqIn19CoICCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QS2QEKK2p1bm8xc2hlM21wcDQza3E4ank5ZTkzOGV0dnByOXRrbmR2aHZ2ZnJhOXYSP2p1bm8xMjRkMHp5bXJrZHh2NzJjY3l1cXJxdXVyOGRrZXNteG14MnVuZm43ZGVqOTV5cXg1eW44czcweDN5ahpYeyJhZGRfbGlxdWlkaXR5Ijp7InRva2VuMV9hbW91bnQiOiIyNDE3NTAiLCJtYXhfdG9rZW4yIjoiMjgxNDAyOTMiLCJtaW5fbGlxdWlkaXR5IjoiMCJ9fSoPCgV1anVubxIGMjQxNzUwEmgKUQpGCh8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQPHK/0pBtEjrIN1biFnVxvj3PR6apHG7qwe4g4GcyeEVBIECgIIARiGBRITCg0KBXVqdW5vEgQxODAwEID5KxpAu32UE+tECMXQvP31Hm6DyithJ82Rl6kP15n2tIAzyz1MyeSuJAoVAsng4MwIiUe/kovJKniC11qGNBTC+2/3EA==", - "CvEBCu4BCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QSxQEKK2p1bm8xNno5OTB4a2ZwaDh2aDR3eDkwNms1anplcmdyNHQ5Zmc5c3IzeTYSP2p1bm8xZThuNmNoN21za3M0ODdlY3pueWVhZ216ZDVtbDJwcTl0Z2VkcXQydTYzdnJhMHEwcjltcXJqeTZ5cxpHeyJzd2FwIjp7ImlucHV0X3Rva2VuIjoiVG9rZW4xIiwiaW5wdXRfYW1vdW50IjoiMTAwIiwibWluX291dHB1dCI6IjQifX0qDAoFdWp1bm8SAzEwMBJnClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiECgC0Vdt+zCEEUGBRpvGFMQhxGqzUdX1KYObVtMTq6Eo4SBAoCCAEYAxITCg0KBXVqdW5vEgQxMDAwEIC1GBpAI+iSRBZ1sJNXn6R92XogDBwgOj8aF6GahdLAqDxojiUqhb3ybTk7XRQqmSuBhF20fs4zkN8XScbx3lJHiy3xsw==", - "CvoBCvcBCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QSzgEKK2p1bm8xeDkwbTY1NXN1bWx1c2xzZnhtMjI5cGZhMmprM2NkY2hlMGp1OWoSP2p1bm8xeG1wZW56MHlreGZ5OHJ4cjN5YzNkNGR0cXE0ZHBhczR6ejN4bDZzaDg3M3VzM3Zhamxwc2h6cDY5ZBpeeyJ0cmFuc2ZlciI6eyJhbW91bnQiOiI1ODQwMjE2OTI1IiwicmVjaXBpZW50IjoianVubzE0d2twcG1mamZ3Y3J2czBzeTR3YzVwdXozdzQyYXBudWZ4dnh3bCJ9fRJpClIKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEDDxMUOri7iVe/ORUJnGKpYur8dYqeYHEGSmA991fKxkkSBAoCCAEY4qEBEhMKDQoFdWp1bm8SBDIwMDAQgOowGkBKDV4HJS+gfHHvr3d2ZpMmXPNslILmur8ZsfTX7XL5VEH+Kt6hWUyiQGiPpgKfoLWnPyx+rqlLAt9t5XUasPs0", - "CoECCv4BCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QS1QEKK2p1bm8xeXo1NG5jeGo5Y3NwN3VuM3hsZWQwM3E2dGhycmh5OWN1enh6bjcSP2p1bm8xZThuNmNoN21za3M0ODdlY3pueWVhZ216ZDVtbDJwcTl0Z2VkcXQydTYzdnJhMHEwcjltcXJqeTZ5cxpSeyJzd2FwIjp7ImlucHV0X3Rva2VuIjoiVG9rZW4xIiwiaW5wdXRfYW1vdW50IjoiMjY5NTkxMTMiLCJtaW5fb3V0cHV0IjoiMTYzMDkzMCJ9fSoRCgV1anVubxIIMjY5NTkxMTMSaQpSCkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohA16eCFm856LFH9b9Jlz3lpad8mRYOyqh++A++xKCl1NxEgQKAggBGIqiARITCg0KBXVqdW5vEgQxMDAwEJChDxpA+iJDRNIuOvegBpartp4kZTBaflEG+0jwATjklO8a6vwtzIl7lpHozrlgIkfdceKFDauYsU9JseJiSr7lpA3sBw==" - ] - }, - "evidence": { - "evidence": [] - }, - "last_commit": { - "height": "3266771", - "round": 0, - "block_id": { - "hash": "6403C5369ACD243F7AB01A7B577D41FC86C4E17131EB8B1ED58B1062A107A105", - "parts": { - "total": 1, - "hash": "FF9BCC40D3B805E30364C1576DD5A0C84ED4507CDA663BD8A50385B64601CC18" - } - }, - "signatures": [ - { - "block_id_flag": 2, - "validator_address": "80F24BFDA3E6A8C1BAC0517E7665AC9145D609F7", - "timestamp": "2022-05-27T07:37:37.511037302Z", - "signature": "oJL6bWXMlsteps0ZayRGQO35kEq3eDJAJVELO+bAcySBI9RKCKW6gTHqsITn5dSSM6XkUAfufUVUWtublZAbDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "1470B9237056641663CB4DFDEC86B064578B29BF", - "timestamp": "2022-05-27T07:37:37.569783772Z", - "signature": "Hm9O8pZschz7ifeuUabiErB002zrsTxUSq0jp0hizzhndheRkt5vJ4gp1reNkBLQhz+8/AfdGseTo3OC3qL1CA==" - }, - { - "block_id_flag": 2, - "validator_address": "D971748C41BD4B777502DCABE903A71A3669A77A", - "timestamp": "2022-05-27T07:37:37.576946579Z", - "signature": "0EUHWRwwUkwaef2pVSPuu7wlAVikfYMtv515tqNlhvxJlud/Qo3vUwkVWAQlGAfuImdc/mrGW8uDQlKziOU4AA==" - }, - { - "block_id_flag": 2, - "validator_address": "FDA77E3592437D1B06EEF7F858363587A38E1D12", - "timestamp": "2022-05-27T07:37:37.488642711Z", - "signature": "ZL6gFgKEO2eeG4YGaMuD/uWhCSxHiI7EgDQDs7uXNd3rZKV7LaJInPM6Tv6ZHLHk9I0mNFVB08pZPrnv0ZJgCA==" - }, - { - "block_id_flag": 2, - "validator_address": "9BE207CC004A3336DC527480141573DCE984FA59", - "timestamp": "2022-05-27T07:37:37.485260725Z", - "signature": "hjxABO9OiftdkJHs5ZfBaUgKvt+LlH47Rvt0kxRIMHJSOSIpwQaiK/YKY6gNF78AQ0fE+NECRd6hR2tcIWpSAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "F9D7C618E5E46C3B942EC35BCC8145BA3DB8423F", - "timestamp": "2022-05-27T07:37:37.506855859Z", - "signature": "N6bGuZlsSuWanlPm7mn/Hg0cvnsfMljuyx8u1/fXdfLJDVfxAP8E0B7WryBRPbCZZK6iJqBhqj87F1XbEMXlDw==" - }, - { - "block_id_flag": 2, - "validator_address": "1B431E63CC50C7BA283AC9E2F0A13FDD1FC86F74", - "timestamp": "2022-05-27T07:37:37.536792362Z", - "signature": "2WVkRcZUkmWYw1voV8qWWyzZoJ6wD+KFq6si/kMHZjxVqPo6lhLInk3ANze5oU4n4HdCOba+DWcg4k4I9FbKAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "A50CF609192A6CF1C6835D56274D18B30459425E", - "timestamp": "2022-05-27T07:37:37.52533792Z", - "signature": "Rl0nRhuYDMu6iC6un7lXWRWu0XG7D9tNMXZmgxRLyuAO42lOwcbUgG5pcgS4kwKzTVik2tgbiN34CY+d+xLhCA==" - }, - { - "block_id_flag": 2, - "validator_address": "82B52E238C9A4506E00CEDE1D6A167A2EF1EE4F5", - "timestamp": "2022-05-27T07:37:37.543338397Z", - "signature": "419Y2zHMjt7AsNouzDEiAKVvxSrDIvj+8FOsmvkwBtv7/TOkLnHgiXe+zwu6ki7QjrLLI4CrIw3ZMZMFuOBoAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "942EE4CEC79B9B74F95681A1C7FEC8A6C9C0389C", - "timestamp": "2022-05-27T07:37:37.621879349Z", - "signature": "IuSc/qFBg5qztJXnfSmENfYOnPH/81b/BmsKU80c7y5WMMFFxUTzY+dfoXX+wxNOXyxViHqNzCkMoIC8h79TCg==" - }, - { - "block_id_flag": 2, - "validator_address": "970C896E7C2CE31811E2BC784167108AFC1F44B0", - "timestamp": "2022-05-27T07:37:37.540494955Z", - "signature": "70+AKU2avG9KQSnYvlsehyp/zcqHLdnUdHgCHZN098DDqANXDm8WMEP/Rkx6eiBtMJ92a2ggsC1sCrohLmYICA==" - }, - { - "block_id_flag": 2, - "validator_address": "6D2B3AC0DEC4412CA87714E1F1B1BEE882E62F5A", - "timestamp": "2022-05-27T07:37:37.557864376Z", - "signature": "pt3wLu2d2lQAUL5UE7xngfn+ZPDzBCT28O39Yr4JzIja4dMVzSUp8YTygNnhszJOUQ2AZin1zX8bytUGzhFhDg==" - }, - { - "block_id_flag": 2, - "validator_address": "FCF0C1EAE20E3C808B4C3E5112AA49AE01C60F8C", - "timestamp": "2022-05-27T07:37:37.577691486Z", - "signature": "ZOS9Gi+4yoGg5BCR/DLt0u2WW6ltqHub0EZmIc0BPpgT5UWf7LzNqvzRN5JAGPt+gQSEVv1df5Nqvz51TRnHBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "26DD4D34B61136958ED2E7E0BE710291417F77E9", - "timestamp": "2022-05-27T07:37:37.572890859Z", - "signature": "6xBYLOouESglH7LiOUWpIxS9QRr2hvcjMu6ghfpIjjPywRAUAqzWZ+1GLvY6D74HofoBymQ+CWTpYptsXIjWCg==" - }, - { - "block_id_flag": 2, - "validator_address": "6EC804DBB72380D0AA5AC6A82650A1FA75FBABC5", - "timestamp": "2022-05-27T07:37:37.62432082Z", - "signature": "N36SLwVIzsVVkoGJT2SmobciJCAQG+48YLFdIJogjY2ycqP0mzltgcHbLwFbX+udGr+bQY3A8ts+9gGJPEoKDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "65974BBB920B9393C197F195FB7B214739DBEC70", - "timestamp": "2022-05-27T07:37:37.469951823Z", - "signature": "u1lLpRDnFlqIfWyhjJKk4sF2HTLM+KA1ujBty993d94Zv5bfewSazMQFAX3jCqj9s7EhyGKGxV8oSZHCFqgpBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "488AB967720358A2EFAEE5922617148978AF546C", - "timestamp": "2022-05-27T07:37:37.505516032Z", - "signature": "5tWEJsxjSYrGn5KaIi5NT+Ql/fQsIU50eC3MvCnjdzyotYeE8HFX0/FdHP0ob9O4mPGCzKL3g4SZfEcwepveAA==" - }, - { - "block_id_flag": 2, - "validator_address": "6678356FBEC44F52259BC8711B35400F440FC8EB", - "timestamp": "2022-05-27T07:37:37.469055297Z", - "signature": "dCiwUioXIGBbZjvAl54YDyyoUnjCzZAtMrRwg4K+9SAfYWSXcgrjmePR7VgH2oAguxvMVg+TFH3BwuqLSzJXDg==" - }, - { - "block_id_flag": 2, - "validator_address": "687E9D3B8DBC07E22DBA8A8FABBD1E7C51EB48C6", - "timestamp": "2022-05-27T07:37:37.497949369Z", - "signature": "MwS3nMJibGxrR0KqNv2Hs5kq0rmMYqD+AQrlsYrNHorA7gTRWqkSP4bBZZAxJq0fxK4Gy4OUOLPi4pv0pHmNDw==" - }, - { - "block_id_flag": 2, - "validator_address": "CB8E49AB7CC1F4F17E79B2C14D31A9C0EE8ABBA6", - "timestamp": "2022-05-27T07:37:37.61740533Z", - "signature": "BLzP+qE14tQEljse6SQKbbH0tQZfhcOlBbqReztQwHnz0MeHjfnyjVvMDMnUHGVeTY3JJHq2NYbhpVeBQMLRAw==" - }, - { - "block_id_flag": 2, - "validator_address": "8EE87E2FBCC518774574652AA8F82BFA3FCDFF9D", - "timestamp": "2022-05-27T07:37:37.474632791Z", - "signature": "lJB2yyVVhe+TlGSdupSCZszn+LtHg3WXCxdny6YJpQTTiPuudbyMMmtXMchNrUJmAEA/ApyMFCHP1Q1Xh4ghCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "64B93D226FD19BFFE48A802ED742D1DC427693EF", - "timestamp": "2022-05-27T07:37:37.502050309Z", - "signature": "w4cnSz8zUQm+f523uIK0L5ozhKdjCuhfWHvbwGI+ohCYoeEiNIwNE1Cs9XmbwQAC/sM2yoVoKQfCjGL/mqLnAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "33E7D788A563CF87FA86AA63817A198A43364EDE", - "timestamp": "2022-05-27T07:37:37.558923058Z", - "signature": "yhWcGbvZPCpAyxtHSVqFZ4p5ni9nmpY6sVFaA12hqjmOrRHyR2/Czw5b/UhQClhXOWfqjIMezYZKxmiwQ2FlAw==" - }, - { - "block_id_flag": 2, - "validator_address": "04A6A9DF0BE221876FAFDBF8DAAE94732484F14A", - "timestamp": "2022-05-27T07:37:37.479072497Z", - "signature": "18XDBby4hKwLi1k1soKJdQdfjesp7uC8Hndzu/b0WNmpx37O5TSjCBtdtCeEc8I7Rov7xKCov2r8YXk7CzjDAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "213643E026A49E93FAB4E53D54C18A77F9B651B1", - "timestamp": "2022-05-27T07:37:37.565691745Z", - "signature": "sAbe4DqDOMOA5upN+kLLbjxgzFS09m0Fi6MwQ2KcfJQce6iEf+wqooDHJQ2mTb1P5PsHaGGJBDu+4VxmUskYAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "A36CA0EC8C74C3F6774FE1DBCB66D77085A8B44D", - "timestamp": "2022-05-27T07:37:37.71257355Z", - "signature": "TooAL9d9Mrq9aDOuI0WGWKqvbAYiFt3r5hGhWRQLpC7bHX5RCWh1jCLEhj2/+BGb+7gs2JLAzBIi1Y8Eg8TdCA==" - }, - { - "block_id_flag": 2, - "validator_address": "0F1ED70645D475745565C702588BD1EEBA62C28B", - "timestamp": "2022-05-27T07:37:37.510265288Z", - "signature": "msO1P4xJQDNFcdEuzs3lxQURJzM58H/LZ7QV5klQpkOXPvmihTkHVhay8qDiSKqT6tVESC5L/T00uQlgWJhpBg==" - }, - { - "block_id_flag": 2, - "validator_address": "8118709AEA2CF6775E97021180F4F17FFF545523", - "timestamp": "2022-05-27T07:37:37.514006338Z", - "signature": "eqNkoGnhMqDMFg3OOTYRCz/8rc6F/A91KLl9l+fKt0rO0fPbgzvekSCpL/zmU/VboJeivf04VtMW+yZ9s4qRCw==" - }, - { - "block_id_flag": 2, - "validator_address": "7992AB6A4A94EB3EE9D5D3E6E4129D2F0AF5D2D3", - "timestamp": "2022-05-27T07:37:37.555936017Z", - "signature": "TKBQCFqm0Ac11fRkjldTqROygMy7Uitfw4f7jfQq+CYmwDHAiKxnXAakv5lSXTlF6ckx2BVI5Sq/G4Gb3WoLBw==" - }, - { - "block_id_flag": 2, - "validator_address": "31E927F677282369B7E57D39FF9C47E3845BFDEA", - "timestamp": "2022-05-27T07:37:37.493485796Z", - "signature": "MTqZMa78zZ2kKnouLwbWQ1PDaQYsWE4zFzFo8+8COMIXiYplwcIkMfgCfljSC1wRVVahXytwZB720tBgWAT+Bg==" - }, - { - "block_id_flag": 2, - "validator_address": "3876144FE42DD069E414F648A9FA2C933D4939DF", - "timestamp": "2022-05-27T07:37:37.552204213Z", - "signature": "2OrscTDd/3+6fT1TBtw8zq0t6Z9Ol0K+g17fnBbDUKtqaIvI5fjeM529bNPa2n0ScAt6qPVYbHqgjnIjxot7AA==" - }, - { - "block_id_flag": 2, - "validator_address": "05F1DCE023B7415274B8400D7D8B95AE95E625F3", - "timestamp": "2022-05-27T07:37:32.665653456Z", - "signature": "TZwkpe+bw4NkbzZFIZFGOjYgqyAYv0B6jtx5Ak18iVsz4l7wo07zgCZz6+fM76uv2EpmFBGYcoR31csktIQpCA==" - }, - { - "block_id_flag": 2, - "validator_address": "B57D60F0B3E0F9548D1C60385D46584356DD61DC", - "timestamp": "2022-05-27T07:37:37.511821012Z", - "signature": "ERg3QaO4W4Aw+1Xm5sKV03XuW9fL9Jx6G3ygNA10UKv2GO9OVPot3b0Fk24qeF67mR3uq14sRZtEMUiYANAUDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "EF5DC39DD40EFF73A2ACD4318812CAFF2EAAA2A9", - "timestamp": "2022-05-27T07:37:37.555277023Z", - "signature": "xQWFqJc7NH9nuME4ZgcMBYUxapKFsGCbeHHwC9D4F4cFXVRKFO6XPXj7gJKd8T1/4Qc6KP0+iRF6KOvpQ7MwCg==" - }, - { - "block_id_flag": 2, - "validator_address": "A958667703E4097A2A949F46321CAFFC794F52DD", - "timestamp": "2022-05-27T07:37:37.48821794Z", - "signature": "1nBsC+5k9FR8kmjbm7uJQfff6+zeBIODjYGEz76liV8zvaff3zSNmsXVDsy6GkfOEA4R06WrxTvTgAjNG0HqDA==" - }, - { - "block_id_flag": 2, - "validator_address": "6BAE36E65B4D487DAB771AE0BD6229795189C6D7", - "timestamp": "2022-05-27T07:37:37.507093792Z", - "signature": "cijbqflJuuQRIPbuEhb1XuKoRrPk5HQLMVnrks6DCkZPIZBRK99CSRt97hP5RKqBuRCus45dPLaC9T4XvFmcAg==" - }, - { - "block_id_flag": 2, - "validator_address": "1A3535BCDDE63C6620F13E5E558418C87C2A0E05", - "timestamp": "2022-05-27T07:37:37.591471269Z", - "signature": "hQ8hlZAs+ZrQnSUkO3mhESkFsQziduoZbj+ot7qGC/53mbjpKXHsfvTnLI58g+YMfDxO3Jwrx9LR+v3Tdkx/DA==" - }, - { - "block_id_flag": 2, - "validator_address": "4E59DD9BDC58EAEFC5057511EF116663A75221C7", - "timestamp": "2022-05-27T07:37:37.652492114Z", - "signature": "Vc0eHv+P7dbX7WS44Qs8A8SobPmxUe4cc2JI05woQJv8GfpCOrLiNd/U4xdOEIJd86yR4h5HVud5qlGUdoFuDg==" - }, - { - "block_id_flag": 2, - "validator_address": "FCB482F4E0111DF6C85DB7099B473608ED67248F", - "timestamp": "2022-05-27T07:37:37.474322381Z", - "signature": "awfTCHmCNSL/GLtPHcqf4P9tj3fDoHy2MqY3CIAiTaZgwj48i64B0QwE+sKs5R33/xXj5uKLEoEi7LVmHJGiBg==" - }, - { - "block_id_flag": 2, - "validator_address": "376258981B5C8270319BE5CD655C628903DC41C1", - "timestamp": "2022-05-27T07:37:37.820254888Z", - "signature": "/JS55OAj1w8/+BxLMQZ9VLtsLtzzHX2sSJlsbjUKbXNoXPZF1X7IUz4RxkdqrYDRlWgq7gapCZ/x5WXSIO82Dg==" - }, - { - "block_id_flag": 2, - "validator_address": "71D07A7BA468ABC50B234F93200F4D91B4AA784A", - "timestamp": "2022-05-27T07:37:37.613532334Z", - "signature": "j8U0kt/yTaX/vWSt/N8olgvxPIaE6VEo2qcNR9pGuDDgr9RlbWF3cAbDsoVHI30aLaJa67F/YRevHxzcyLCMAA==" - }, - { - "block_id_flag": 2, - "validator_address": "49CC3E18B688BE70AD1FB8D9AD7D18CA8F9628ED", - "timestamp": "2022-05-27T07:37:37.517961423Z", - "signature": "1tWvg7THJvEoAAqjbXxA1v+Xu77q1Pyyr8iBoVrF4IuSsdeITZWU7oERMpkvdPoCL/akWhPpQ8xmLJ6VwjqzDw==" - }, - { - "block_id_flag": 2, - "validator_address": "B67DDDDF3392C5980B4E0868CC1770BE9118FE65", - "timestamp": "2022-05-27T07:37:37.485814301Z", - "signature": "zi4FjYo68Q5j0NsSy/n8yBcdsAGMgE3ybEbNtIobLriE75glRby+HrB+xAocNDxwmYgQxBhZ/AwtSokWHFp/DA==" - }, - { - "block_id_flag": 2, - "validator_address": "27CA3B44886E4E2B33784D49E6EB60072B7788B1", - "timestamp": "2022-05-27T07:37:37.503900041Z", - "signature": "VOnyyRqwbdqwH4P3oyt7kCIcOLNDdN6Mhq+NmJoY7fc7sdfCWPuNKEwnGbpZmTrAA0lXcYex1dolPzlGzbBQDg==" - }, - { - "block_id_flag": 2, - "validator_address": "D21150DC3691E006B169748003944172CB4B0A74", - "timestamp": "2022-05-27T07:37:37.54972731Z", - "signature": "085QDrufitdQiWIBKuV7Oowtys9qmlpqhtIq1nObqdxbWE+SI9IYxdTkj1DzS0KY0tSBSGctni1l+fYnppnbBg==" - }, - { - "block_id_flag": 2, - "validator_address": "CEE07615BB3D2467E0982E9F6EEBCB4197AF041E", - "timestamp": "2022-05-27T07:37:37.545273811Z", - "signature": "O1/v3sCt+CLyIczeRkDBeTBZRXOOj6rRvQj8r/be3ez3jsZtauHNTRLzFKD3iA1+N5MI2VqzjAX43T7+OlExCg==" - }, - { - "block_id_flag": 2, - "validator_address": "889BE248D8CA73655A61BA48CF5EBBCC036DC183", - "timestamp": "2022-05-27T07:37:37.504048514Z", - "signature": "ddee3EQlUAcKbxWEpopBUhOqarUkaE2rwAQNQ6pvSILmLmKb9gZ+9vWMiIyJQJK7l7M5DJTQBB75UvIVL/dKBw==" - }, - { - "block_id_flag": 2, - "validator_address": "9945C4BCA1EFAD0E461EB84D79CC283130AD569E", - "timestamp": "2022-05-27T07:37:37.461611461Z", - "signature": "V+H6PLsUlODNfW7HgkviF3RZZVlIfWWNasijJD3GAM2v9zBxtaZ84krh+4XnjjBeZZRPQTjLcmFsMUZbwR1gCw==" - }, - { - "block_id_flag": 2, - "validator_address": "7A81D65970042457FA7E4A3DA96C4B73D52DBF8D", - "timestamp": "2022-05-27T07:37:37.56992617Z", - "signature": "Xqbuz3iRNUBuI84qzVz+9IWbUwC1JhCiwzWQFRfouGnGruMuWmpYcX5znI64dvXFembqMtORSkTmzqn6NliVBg==" - }, - { - "block_id_flag": 2, - "validator_address": "10DED706EFAE3E176E39559EB9927AC30DB1F0E8", - "timestamp": "2022-05-27T07:37:37.558555739Z", - "signature": "ZeVeAsb8AhxArrehpr8WFffUL3NUSbCnOL7sSV0NrYC9cJjB3Wp2AaMkyUyDlFSp7jhYyREnbQ/h9Seu0DeECw==" - }, - { - "block_id_flag": 2, - "validator_address": "D8D80BD5D6D758C3014374AA8EEC545F46686151", - "timestamp": "2022-05-27T07:37:37.503647636Z", - "signature": "LXoK2j3uNp2U8RU5R3DXitUD86k7yWGgDMlQ/SlWlVitL/8eK+TPj9X654BQog87fjK3b8Prrcm/NT9nnzxYAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "A758F131985687FE5F72DEC968B96C21C20DC93D", - "timestamp": "2022-05-27T07:37:37.460765743Z", - "signature": "WJ9hf6oVZyt8qOz5bm+5zD0idF3OE/p2PI/1lG/z6ZhCa1YVaX3iGlKbpRk2SssB0Fy94jvWwpAG2Uk3tD9CCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "E9874B0B0E95D84925928565222604549133B254", - "timestamp": "2022-05-27T07:37:37.507048086Z", - "signature": "/HtpPek8ysqejYgaQQE2yhRoyqAA4kvZFUP0z2UM6Ous+Ak3h6o0sccL+F+gzL8jWLVF1yBK0iNOTFkIhjmzCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "011CA32A120D5F8007BE9D2AA60C1C7AE8F02634", - "timestamp": "2022-05-27T07:37:37.495766891Z", - "signature": "tVr5K5jeqzCuPIV3Eg606XK1wefZnIBJSbViUNNSQFFZPKF/a36vrSsSVSAz/F/fOErBlI91vkCS/LRxRaQMBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "154B35F02A0881E71F45CDDC4AA46FD310E20812", - "timestamp": "2022-05-27T07:37:37.523558348Z", - "signature": "XQIxCZnyoM/uN9mYNhAZuLrfQbntmnWREKGgVrGuJOOpptNdoLOw45pd0zfueZ0b29+BeCyEVv9MJCrbrXiABw==" - }, - { - "block_id_flag": 2, - "validator_address": "1A0FB0B119DD4A7606EAA5ACE96C59A8EDA70734", - "timestamp": "2022-05-27T07:37:37.611094149Z", - "signature": "k1TG7EVBM9KWK1t+mCN6s8ejzCgSJk10K/dUrDAduOS/A1QzWKWEwQtzwx2/aJfLUmxlN90+LOwFU56F0EPgAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "BC5FDEE9EDB99B23AA43459488422CE7B0D17FC5", - "timestamp": "2022-05-27T07:37:37.559056576Z", - "signature": "ybLy9hkcYXjnp/uV+jSfWAfsrZoZ+gnJEvjp0PjXpPtHltAG/njw8g1ELym8r1bp/DqYyT6wnfWWjI4uqR6WAw==" - }, - { - "block_id_flag": 2, - "validator_address": "149825C294B6936AD8833F5F2055AFD64B6E260F", - "timestamp": "2022-05-27T07:37:37.633946566Z", - "signature": "goGFrYH+/CggBF9Kb9lywOskZ9DtMz2D3vovOQY5iJvyXK3h+hrAyxxzl7A3Aiwcy6M/fC818jT8j864IlsvCw==" - }, - { - "block_id_flag": 2, - "validator_address": "2A8023A1977E7C521107502B803AEC57FFAA6094", - "timestamp": "2022-05-27T07:37:37.517153084Z", - "signature": "YyuFA8EYxKW6NteER2Bz8+ssbGOxuKfDign+dU3CoI2ZFrtkfF3qOFJ4cKHHpkpd1AJ5huWNKoATH0BYRA0OAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "D3885E6EEAA87E1D4537C2D582E628A8E150F521", - "timestamp": "2022-05-27T07:37:37.53314768Z", - "signature": "PTrBEsmoucoEo/asOoQQZ77eDiPPHonglZMrR+TG0O2vuytlSqBW89wR19cN0npberPreZyAHornNn0owF8zDA==" - }, - { - "block_id_flag": 2, - "validator_address": "ED5A383F89D74B59E040E1D33E78C9EF5323FD53", - "timestamp": "2022-05-27T07:37:37.553442527Z", - "signature": "SL88ZhmLrLNpS04JxNsanP+xqmnfs7bgBeszU5Ai0dNy6J0pl85mm8u3idEllS/6OmPL/Dg+xsbzJCL9ZHd5AA==" - }, - { - "block_id_flag": 2, - "validator_address": "8C8AAF3D135AA21DB51EA0A82D7B2FEF79E56281", - "timestamp": "2022-05-27T07:37:37.538970611Z", - "signature": "ri3F/7CrlyjYMk+QtEYOZ0sVXPdwEoYNJIUXBaivfOA8E7PurDOS16Q9iq0xQ0T5cDt4zbISXnY8y57YcJNFDw==" - }, - { - "block_id_flag": 2, - "validator_address": "FEE0233B3771EAEB26617E367138A0A6EFAA79B1", - "timestamp": "2022-05-27T07:37:37.493296728Z", - "signature": "J0e9Zmrer0mbFiuMoBtoE65fJQWJJhRa3/mgA0DT8P7C7gova1rwceDanhQQpXPQJlVsOhXFgCfDbqTaufueDw==" - }, - { - "block_id_flag": 2, - "validator_address": "C0CA289D913689AC0A9450375E4208F473FD5A2D", - "timestamp": "2022-05-27T07:37:37.63698882Z", - "signature": "EtwCW69d8Nx+MyBROiYiQBhCB4OmbSUDqURFEYEiSMzmoA+R3dZdmmOblIRtrVT8IGjZddfRhuJPAH7byztOAA==" - }, - { - "block_id_flag": 2, - "validator_address": "39C506F01CD03BE7E9470D439356744737669761", - "timestamp": "2022-05-27T07:37:37.503557253Z", - "signature": "JXyWD7iZULkNrUHL+2TJ/l/xE7a6evuoU64YyumibkmuClisjkcwvxCll/CYDlRosJr7i7KJH+gRCuhuTAyyDg==" - }, - { - "block_id_flag": 2, - "validator_address": "2C06679174476CFE44D3699A05505360FF0DC6CD", - "timestamp": "2022-05-27T07:37:37.562640142Z", - "signature": "1zL7LqrMqyzRudEP37wZSElRV2kZRoid9Ryrir2ERmstUOoRb9d8qRXv9/yE72Kw5+YSnxd+L1DvaCXMqpQ5AA==" - }, - { - "block_id_flag": 2, - "validator_address": "4ADDB982E2AB4C80ED5523416979FB8DE6F8212F", - "timestamp": "2022-05-27T07:37:37.545761505Z", - "signature": "IYcLKy+tlW+K0wEWsYEGZtTib9025SbXJuOFeFeQGHtNXY3okbN7zGwTeA0FIk5p4QQE/cK3viutYG6vxOMfBA==" - }, - { - "block_id_flag": 2, - "validator_address": "3E1DEB86DB0748495A5C7D0E3D89AEDB68BDBD32", - "timestamp": "2022-05-27T07:37:37.827215394Z", - "signature": "pVUGoWvzXPmxgiUMaUv6IKBbEmHBTUhlf3F2D4+BiFaB/MWpitwxISrwQIvJJcyKh6zS+dRsN06bHGNCS4DqBg==" - }, - { - "block_id_flag": 2, - "validator_address": "7E36265106A258FEA7940B0F5E7103C83919D7EB", - "timestamp": "2022-05-27T07:37:37.615605459Z", - "signature": "DPDnl6XuWUlECO4ETYcrhenvFxIv3CF+HXZ6TZF705/rXAuvDyXQ+MfCYI+pq6yloIPpcLuwUoIZ7p8vofn8Cw==" - }, - { - "block_id_flag": 2, - "validator_address": "706AED795780D65B06127B2CB7BF08961116C9FF", - "timestamp": "2022-05-27T07:37:37.516262094Z", - "signature": "vHHfdK+BPCzbM7KeRaUSo/HcC8yOIbQqomxtufnZM5YYlx9uFVRcR5mWdzYeH/YDQT76J7qWSFXHwdvaSq1oDA==" - }, - { - "block_id_flag": 2, - "validator_address": "5D9A2D9666D5E9360A384858584398CB6ACEBCBE", - "timestamp": "2022-05-27T07:37:37.550161023Z", - "signature": "QgoX4eUknEA3yjoNWuvHlFK/NO3GszJfkbpScs4NOxxJuJXHBQy4Qnw9kHZWhcoQfmtK6VEQvJTCDCfOfaq7AA==" - }, - { - "block_id_flag": 2, - "validator_address": "3B7925E257959679621E750F69FE97277B8DD9FC", - "timestamp": "2022-05-27T07:37:37.545360344Z", - "signature": "byFZLljQk1E87QWR3Y5TsOsneW8Y/JiHH8+HFHUe5g8bKl+i2VnLAOlzBweLf2ydaaEmqXPaIZuytf4qF8l9DQ==" - }, - { - "block_id_flag": 2, - "validator_address": "059C81DA7BC445A170F356779894257D2A587A6D", - "timestamp": "2022-05-27T07:37:37.681592139Z", - "signature": "9WvR3CH9rExkPEdmBSHKNeNmhESDuFd3VMeGsJ8OXW0C7m92ZAZZfxMwu0IgrVNU33q5ilwTBL+BGU7XMrOZAA==" - }, - { - "block_id_flag": 2, - "validator_address": "BF480EF88DB244A6DEFC6EF6C739720124CB8AFE", - "timestamp": "2022-05-27T07:37:37.553762485Z", - "signature": "tZWyN+YyW63S8VuVYSt9J0/kqJlGExL+9kzxx+7E53OR8u/+1XHVpHbo2Y1iF+ySh9hqyDhyNmzQR9zKITZyCg==" - }, - { - "block_id_flag": 2, - "validator_address": "0C64C97FA93202F4655BFE4B971EC6B75E0D90F9", - "timestamp": "2022-05-27T07:37:37.54664688Z", - "signature": "ltNz98tWBXY/rbWs9jL4bwW+EDcB1F+Oeh2atUgi2tMic3EJV10HVCzTo6t8b68yLh8OxvWb9YU7TXb9b8KdBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "BA9653E03DA56F88BC1C79B091227AE9DE9D30A7", - "timestamp": "2022-05-27T07:37:37.460690667Z", - "signature": "woZFscCWdNFUC9cmXBMqVvpC7jp/uC6o9BRVL2qPn+jXMPiXGbNlX2MI6gcYEom1Srj7scUNuhXXNb3cmgP5DA==" - }, - { - "block_id_flag": 2, - "validator_address": "9764A129141805A79703E9AEEFC1D0ABCDB35F86", - "timestamp": "2022-05-27T07:37:37.560919187Z", - "signature": "EQGC+0WhzwuXR94F3XpLTf6a8Yl/TcaEHGS0dw6qwv34B0Cjn587CHR47P0GkNCN2pQ43DLWtOlP+ORWS6/GBw==" - }, - { - "block_id_flag": 2, - "validator_address": "B2F50E82D354517E17E37178A0D4A8A9644C4D4D", - "timestamp": "2022-05-27T07:37:37.562313072Z", - "signature": "jN6yfXwI6e82Ln5gBp9g5rNXnd0RBcY98Hti+4ZsfhkrHdQ3UCl3VgKjYlhA1QzMpPpsgqLT2o3H8vrRehLGAA==" - }, - { - "block_id_flag": 2, - "validator_address": "729C998ADA302CBA74B0F8887A9E23B49E0EF5B1", - "timestamp": "2022-05-27T07:37:37.557411408Z", - "signature": "ZCQH5cGb/sA88sZj26A4N898bVPJAj8/5lmrXhso5jEZWdEE5t/eBuwh90mqvEkaAIliSSz+wTRlfZas3T0uBw==" - }, - { - "block_id_flag": 2, - "validator_address": "3D680F8EF25FCF01FCD24957C665E8F23D07EA66", - "timestamp": "2022-05-27T07:37:37.583482207Z", - "signature": "x7SRmG6S70cUsgGPIVbgXUyDRpCi+ad6x5QJmCG14rXZ0hwn5zlZCwV/FVCcDGybpM8upc9hl3etTc927OXHAA==" - }, - { - "block_id_flag": 2, - "validator_address": "640B7E370FE54961870389E2BE27F616E72CDB16", - "timestamp": "2022-05-27T07:37:37.543766155Z", - "signature": "lXsgLHfU721GA2JZFHtWWLtmDgpjzuoo2c/Eci/U/kbcvuxqLIC7/jXIyPiYclq1lTiqBlFJQjAmo34Ss3WbAg==" - }, - { - "block_id_flag": 2, - "validator_address": "2C4671AC70314659E307C510876484D2920F2358", - "timestamp": "2022-05-27T07:37:37.583971081Z", - "signature": "LMM6plktdN/ua3Sl7unpzfXR/eH3i/NSMrpYCwrwi3tu3loBBLL+KIwLdrGqzQjIRWVBQpZUZXeRApKCdbyNAg==" - }, - { - "block_id_flag": 2, - "validator_address": "83F286870F6AD40171663EAB308ADA7770550EBC", - "timestamp": "2022-05-27T07:37:37.523962961Z", - "signature": "0BFyEFZczlbnQk/kL6wQB83hGHJ9ZcRgdeASJRUGKnKsS6SjXOVZRnPFdQhbLsBRQ3ICXgOiOmT3LOe0XlkVCw==" - }, - { - "block_id_flag": 2, - "validator_address": "3393EB61A267BBAFBE93E1494B498D24BDC7B9F7", - "timestamp": "2022-05-27T07:37:37.535026813Z", - "signature": "BfNy7nV5y5Jzwhb3jgBXnmhUokhO6rNaOfhVFJEeRDJ2Xk2k021cp5dZkmhFkCWlvBxbH4IrT13giCeIwPhjAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "D24AA323EF77312855D4266F6D40723514733C89", - "timestamp": "2022-05-27T07:37:37.556064886Z", - "signature": "I6PSS4lrSwnWOFYJF+uLAFTjUcb11Db4AJ4q1iL76m2oOk4ysyRzB8iVRhxwFe2iCiR7YeswHr89k2cT0QSLAA==" - }, - { - "block_id_flag": 2, - "validator_address": "7ABD48C0559A2F1C0157AFE17ADE7D6178A1A26F", - "timestamp": "2022-05-27T07:37:37.562406734Z", - "signature": "y2SFiwtARCIz1pZcy7BVlLrNYYwzmNg9Yup30LBSvQ8m4lXOIRJvuIc+YI2+bUM0nbbiAwFEn/nUcpynQchRAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "87EB79967FEE5FC636AF59391AB5B6DA6E5FF253", - "timestamp": "2022-05-27T07:37:37.498418301Z", - "signature": "FynjqwQN0dlAiJarS7ipLoYNzmgNEQj9Q+uoK7q+r8adbIsX63aOhZT4WxwmtZq3xx5dy2JI3bm5GC7QijYIDA==" - }, - { - "block_id_flag": 2, - "validator_address": "0EA2C640858FE3DED7DF3C1FCAD15CF1A4DD8D22", - "timestamp": "2022-05-27T07:37:37.601482545Z", - "signature": "ziKlZu5aUBoJ1OmBd3NZa+VwqykcTa6y3tTfo0mDE7jB2MZzPj190O9EViFAcEGrzo8+3fryswc0xx5xIYwaDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "01AA3C530811032ED2395ED3C8B0122DEABA3DBD", - "timestamp": "2022-05-27T07:37:37.555352107Z", - "signature": "lg25sSf6ZeF0k3v3l5OVAUyEfthDnPG3SoIYuDXWrcATEIxrt0wapMBeTAv6QCsi/dbYqWfUfOsrVT+6JIr6Aw==" - }, - { - "block_id_flag": 2, - "validator_address": "891B7D6D28C39786EA4FF974231D3856EB3E27F6", - "timestamp": "2022-05-27T07:37:37.523263605Z", - "signature": "QG7ojZHRspjdYZ5e5onwKNQxYofkKddUoajAgcqe7TYN4yrOCDHh6MHuH1STo9ZxVbn6kGdXRDovzRYZ/buQAg==" - }, - { - "block_id_flag": 2, - "validator_address": "042CA91A597C492082FEFCE5D022035F106C71EB", - "timestamp": "2022-05-27T07:37:37.548827277Z", - "signature": "+X83L1Wh0GebwfFvpxffxg8z516DWyqEdusiX2NQOy5VUMcJ2+m+ItZlZ/sBU2MJHXX4mzDxTgSkb8/8ONcBBA==" - }, - { - "block_id_flag": 2, - "validator_address": "CA329DA9589ACDC1C32DAB6541F49577F306118E", - "timestamp": "2022-05-27T07:37:37.568278581Z", - "signature": "8ZeoKVbFrBz24bRRudik+xAv/rgx3QSfFi0Th7j3NqJIAnCKSiZAL3NPXXS5H2285vyuUNzOjSrRRT8TB35ACw==" - }, - { - "block_id_flag": 2, - "validator_address": "1E07465E9E4EDF4C225B1C617E95C82E9163848A", - "timestamp": "2022-05-27T07:37:37.563653262Z", - "signature": "cENdfAgih77r6EHxk2wqNDx22E3/hDVWBLWGFiIpqpJ8ikYYZsIwpsN4VLOsesWA5vizeF1LcpI8ILOK+76bBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "CE7B52696BC06193E36BFB10E6CC0A3561D837D4", - "timestamp": "2022-05-27T07:37:37.522617917Z", - "signature": "uO45hqAkzteFG+lDXML2WdTks56Rb6xsU8HgLLowpJsoD83s5+Ri/ClQC5QADxd11wEPI/LB5ccvgbpbczAbAg==" - }, - { - "block_id_flag": 2, - "validator_address": "42706A040AB648A3D298025AEAB6B82F80A152D8", - "timestamp": "2022-05-27T07:37:37.542528109Z", - "signature": "e6Xg++l5YaM+D268pXzCxjOkXq6Hwm/fVZ9UyGy6QnhECOvOKEuEb7RsVl5i5VJLHEpa9KribUeTyFfoU5tGCw==" - }, - { - "block_id_flag": 2, - "validator_address": "45127DE87972C6E2648BEBABD31304542C8DF0D0", - "timestamp": "2022-05-27T07:37:37.509792692Z", - "signature": "no0mBZsZUCuFDn9qSJpYuFM+M2RxI1zwrT0iiG7fOl2xPEnpKmcI+3AJj1ec2aI/pIW2Pdci+tWQ1BuEIaFeAA==" - }, - { - "block_id_flag": 2, - "validator_address": "B7466FE6CB3118D8FD4E5F57717024E435CC0B1A", - "timestamp": "2022-05-27T07:37:37.487392281Z", - "signature": "8dkGubKDAN8Sjb3m9M6L1mAokeXMxlo7QdlsH0dHEKOLMRkmvkmqTXXw3omXVjH0hoz5gnLqQEj2IW3l+2zgCw==" - }, - { - "block_id_flag": 2, - "validator_address": "BD499BD54FDABBA28EEC8B31E657F3284351DEF0", - "timestamp": "2022-05-27T07:37:37.567760805Z", - "signature": "gzdSAm/VWWkt0vfnP53Q6HbYqCRn4yTW0mSfXAl7k7iq42+m5EGkvnx5iky3SmftNKyugqwFBXfEcbdHbq9QAA==" - }, - { - "block_id_flag": 2, - "validator_address": "482B8D3344C8F5B9FB65E697A273E6EB0D162C23", - "timestamp": "2022-05-27T07:37:37.559894591Z", - "signature": "FVmTCmLgVVnKxBvCXJ9KVD0qwlu1c2Gz1a6KfEqE64fOVeaShqHLwkZseEjCE/89BQzK4dE21bZuymRxo/vbDg==" - }, - { - "block_id_flag": 2, - "validator_address": "E9D4585FE1FEC3B317A9C69F233A19A0281F3C43", - "timestamp": "2022-05-27T07:37:37.587402559Z", - "signature": "tGNUTqxJN5rPZDD8aWjvJ21r1QBT49eSU8793wedPg/3+T3fLSOCvIs32QCttxpDPHPj/VVu2aC2u92BMplcAw==" - }, - { - "block_id_flag": 2, - "validator_address": "21F2E30ECC6F02B6BDCDF7B50F6CA8C28D527AE8", - "timestamp": "2022-05-27T07:37:37.552800371Z", - "signature": "047RXX0LxB0rPOJtgImndo62JfioNnHogQHH+fEkjLTTH6KxsP8I4pU+JJ204O4nLxArYpB+sW4odpZcAJo4Dw==" - }, - { - "block_id_flag": 2, - "validator_address": "AC4122002F3EF3D6FFBF4B84234E7F0B417B3132", - "timestamp": "2022-05-27T07:37:37.583357035Z", - "signature": "5RQLQ4aW2uAuRIuCnZzrvvD9lhDH9hghTkrqHmq8Wa/Drtn45tPjAoTuawKo5dC1SV69cjKZbtA/BNbdhtDyDA==" - }, - { - "block_id_flag": 2, - "validator_address": "2D71CB60236372A63DBB1444D6F1BD83A22D6D87", - "timestamp": "2022-05-27T07:37:37.497566658Z", - "signature": "WznKlvFs3WWFMpzxSjHY/KlAYJ0ycHiGP2HluV+y09yT2h/Hk7KdZmgAlXYTGazy/P+WMu5LLii1HO6GEELpBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "554CC1217B3BA242C5F3BD11DC377C2800147EA5", - "timestamp": "2022-05-27T07:37:37.462058506Z", - "signature": "XYrZc4AItIAo1mU82MfWKLM/cffYgpNLieBWEA2Z/7Zt0VPStBF8cvOIu2gKtv6ZOn5BiH+/K4pVUXkwRLTvAg==" - }, - { - "block_id_flag": 2, - "validator_address": "71BDF6B1FBF997AD1875B74F4796CD3D6A5F6D69", - "timestamp": "2022-05-27T07:37:37.55488336Z", - "signature": "SV23Yj3d6oDwYKCaMnX0mVCT2DsFtbd4AfAKC/QEdXNLT8XjoWBFRIN35F3aHt2hjMj8q4c0cgARoZ1aZIwmDg==" - }, - { - "block_id_flag": 2, - "validator_address": "36308901CC216719B512D4EF13E1A7C6588EEE4B", - "timestamp": "2022-05-27T07:37:37.556500192Z", - "signature": "7asJMMgsmN8ti5Prs90j7JdVscV6AuqddIzn8vXvymLPOu7QwfL4Xj56MGKRl3EsVhyv6JVyxYd1wM0qwZzxAA==" - }, - { - "block_id_flag": 2, - "validator_address": "D87730AAF169362894C9EA7AA423B96D1EA957D9", - "timestamp": "2022-05-27T07:37:37.58204733Z", - "signature": "XP7B8pfNBjAbdCM9GMzbPT4WSBqAmkoUJ8+xhaxOtUYdqzEGlfKPyTPWz6jlM/9wRlH92f7tKphHchL8M/2NAA==" - }, - { - "block_id_flag": 2, - "validator_address": "F4C65C2B8D8BD96037652F375E789E2EEA4305DB", - "timestamp": "2022-05-27T07:37:37.501778362Z", - "signature": "+GIBcD8gu+tKiwtVpTvn6wSbZoknb8P2EcfsL1WcWNzz+c5++4RLq8abw2MO3rY9puBXH3dtfu0lEcjCWHUwAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "A5A57699ED5519B2B1521EBBD4B5E4E49397A898", - "timestamp": "2022-05-27T07:37:37.482967594Z", - "signature": "CWXb1eWNqvmLmvkWlES48dNDzar1v4yra7s6jU/HrvK93cXlGEA95MDv3HnBR1WKRybhyAe1lfvIo6Y8PsGWAA==" - }, - { - "block_id_flag": 2, - "validator_address": "144A5AE055C986FFE593DD90FFCB93C96A957C5D", - "timestamp": "2022-05-27T07:37:37.709721758Z", - "signature": "2iSj1c3WTZLJ3EhTxgoL6JxZclBdtj+2ajI/E4Z/Lu4SbVCA1ZbLSMJDYP3rgL8E/ZT47hnXrNFRZDppOmmSCA==" - }, - { - "block_id_flag": 2, - "validator_address": "530D85C6F9691EE68D834AE9EF95887537906183", - "timestamp": "2022-05-27T07:37:37.592106053Z", - "signature": "ZbA7o4FKVc39GwcFlyCw5A8ZOygT20E+mouNBGYy9qB2a7C6tJg7+dMQ9cJ8VvUxZdSAPdv8uiES/QVzp5b1Cw==" - }, - { - "block_id_flag": 2, - "validator_address": "9F0045CDD323BD2384203115D44D6D16C915E5FC", - "timestamp": "2022-05-27T07:37:37.491014936Z", - "signature": "SobAKcHBn+NJIjP/PpfRVC4twQsL6oEj0uUVO/DDbg+YqCAraUHsnmNQRyvmuHG8FZ3PliEIA2pmgWxzfejLCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "1E2AD3EFCB84B3484D33F9F171DDC389C5FABC69", - "timestamp": "2022-05-27T07:37:37.544638139Z", - "signature": "7pv2t0rYMROnQlwF2eSB7HbiwFzGuS8TfYZl5lVbZ8zr4b+1kDgcZfY7u5rede/g/1+rS1IM3FceEOm29sFkDw==" - }, - { - "block_id_flag": 2, - "validator_address": "7926DCCFF4CD77DD8F842BB79FB96679C1635AF4", - "timestamp": "2022-05-27T07:37:37.55575801Z", - "signature": "w7cZvAue63hm2kpxYyaeMnum9I2dBCbVOEa61d81b0M0GP9VqbvtRufjMe01kOIfMWL/DbBGkNBpVxaVG2LpDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "A6C8D279FCC4A4525B72137531CC5EBC31D7A175", - "timestamp": "2022-05-27T07:37:37.532416451Z", - "signature": "ryv4lIYskLlVJTMzyuZp8uTrIuL0CpVot9OU60H8CJTuKQdzizjD6fkgfckbpG+xNBD6gyQ3llE3pRPvr8flDw==" - }, - { - "block_id_flag": 2, - "validator_address": "083C4506AA1315D8DDF8A0CD59E67714A101C05B", - "timestamp": "2022-05-27T07:37:37.50750066Z", - "signature": "019d+oV5yAyOes0AhnhslvVPVLYZFQVLtJTUVUYnHllgg8jTpBodwPU3IJXIbgdD9dB+ECF5HzbpHfhOJZsnCA==" - }, - { - "block_id_flag": 2, - "validator_address": "15BBFCA9F07F8AD7D40D657157C3E7F824C02C25", - "timestamp": "2022-05-27T07:37:37.476308218Z", - "signature": "LST62NFIOVUlh6jDts2ohxCnWzB/9Fe/GrY0BuRCilPvdiHPYAILEjXY8j8kHajD3AbvXVRL4f5OSfDfMMSVDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "EAB33CDAD8D5B57DB5BCD0F176CB9D170A6DA200", - "timestamp": "2022-05-27T07:37:37.475112018Z", - "signature": "6xL+l1+Fow1GYStA+ENqBCv+CG4cO4rj53YJ+s1KDaWT6cWX++Oim8WvOkHVLrLBuslpa2ZM+C7VBSxVWVswCw==" - }, - { - "block_id_flag": 2, - "validator_address": "E23E2D4F46F7A3A079633F81BA5CD77D42A74E48", - "timestamp": "2022-05-27T07:37:37.54422528Z", - "signature": "a6Qwm0+gPflqkkCF99n1bFBhhz0BM9lw+fKY2RBeljWoo4yjK/jsJcReBuENcHSMYLZuw1uAIMyVgp+sG85vAw==" - }, - { - "block_id_flag": 2, - "validator_address": "175DF90C23CDAB4965DBE0433AF7E850FAF9E4DC", - "timestamp": "2022-05-27T07:37:37.493294115Z", - "signature": "rKk1y1Mz0j3F9sKFWr2/1dVWD+nHDssDjSZhcpYzGgDP191CQSitc9LM7cRCepgEhIcHR8SR+Yj5nmgUsdjrBg==" - }, - { - "block_id_flag": 2, - "validator_address": "45F6C4DF42C56876B4FD7B26CD79981EDE6472E6", - "timestamp": "2022-05-27T07:37:37.54127019Z", - "signature": "XrQqNx4PEj55a+l7SuDtDDf73Q705ex1Q4lTTm9IJ2Ozj0rUNCRbqerG8lU40TB7MbHArZtjFLDFPYOyecr1Cw==" - }, - { - "block_id_flag": 2, - "validator_address": "6B56C304343B1171BB9849DCA325376F1C2DF7FC", - "timestamp": "2022-05-27T07:37:37.649398642Z", - "signature": "QiRh1+DoZBUnhon4fVJXMPoTFmtZ9juDZXTpaySN4I2STQiVoLV/IpGOyadCBOP5GkPit1l4gbXpu8symY6ACg==" - }, - { - "block_id_flag": 2, - "validator_address": "D2C08B4DB6CC564701FA562DA96E54F04BE5857C", - "timestamp": "2022-05-27T07:37:37.571623763Z", - "signature": "LKoR29CrxGZt0zW5up08bkzk7YB8nvoU3bbk/wh+GL04AhNrV2/5jHDkyXC6h6+g/Yuj04vO+PfRSSQTXFAQDg==" - }, - { - "block_id_flag": 2, - "validator_address": "A19F8CA134065BDBC764D53A5A024F091F8D58F0", - "timestamp": "2022-05-27T07:37:37.518390122Z", - "signature": "xYstcwpOv2fbA6gug/rU51AiC8XdeK3wV9VtgWM/dLJkBRH8DLl+5PoNEsYu3CRiBr+NYjXRSYUImbYMEtXaDw==" - }, - { - "block_id_flag": 2, - "validator_address": "3C882F62D072CA22CF996B3EFC9E889D14DA56EC", - "timestamp": "2022-05-27T07:37:37.544084492Z", - "signature": "uyZXc6izKszc9DNDPLdO9QlaeqYrvw0Yue0ieDGge7VGeV8uqEw5AbpvjZ/TrRMzvVhJH5qLbahITvMtA7XUAA==" - }, - { - "block_id_flag": 2, - "validator_address": "82594A20244F29C881CDE573F82D7A334BB54770", - "timestamp": "2022-05-27T07:37:37.589860854Z", - "signature": "KU/khM7vkGyl3MuqbnVratPvrRV/VQkTUZ7QL4iBB2nRoxX5vP/agqfmVwDUhi3CbcSVEVzbIsi3seXmuWtSDw==" - }, - { - "block_id_flag": 2, - "validator_address": "0855A780C7EABDAB44FC31341278D7B41ED9CE96", - "timestamp": "2022-05-27T07:37:37.603757827Z", - "signature": "9dpqTs0ntNWHrptjqdKHhOwlEJKfyfIVXULbSHbbhoxSqNT6LaC+ZSTjAuJVfrGcIj/UjweNp8zgNDg/EgnqDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "E85369365EFAF2003506117F8BEC27AD5B03D4A6", - "timestamp": "2022-05-27T07:37:37.561170886Z", - "signature": "407nffTg2A0ZqpwA/IesmsuxQJ7WphR4h0CXCGQ+koywesz+5e8ObdcQ+ZU0TCpg/PBCcV8aqX+BqQJae6q2BQ==" - }, - { - "block_id_flag": 2, - "validator_address": "D88899651B0E78D95A01B696D616584AB2A17836", - "timestamp": "2022-05-27T07:37:37.495969127Z", - "signature": "guCKdYjHKZ+UthtIaMB71isPUdRzRQh/KH+1wtL69EFSZi+uRwaz5Wliy98tJ9/hiycEPBzOJq4oSnuThXliCA==" - }, - { - "block_id_flag": 2, - "validator_address": "5769ACC80F37286F65AB75D03F659506DAC4EB8E", - "timestamp": "2022-05-27T07:37:37.713899664Z", - "signature": "zWXQ73h5yMRBh//PVcUVqv2uCU1ssVMRoYLmi0n1PhOUOZ6qApuxek2lPiRKncpRdxnRsqdYMOz2aOCjjVCDCg==" - }, - { - "block_id_flag": 2, - "validator_address": "8F5A8A0899E031318C7BE2651223F9898E84677C", - "timestamp": "2022-05-27T07:37:37.57372014Z", - "signature": "eca9IvyYIzFWcQnVz5lfAtJSbmTXoMdX0UXV8fi13fOOzBjf2Q6S4FgxMvURTAUohMeIjIJSzrVWMEQmEwJ/Ag==" - }, - { - "block_id_flag": 2, - "validator_address": "33A5CC28558845925923E8B5492E5064DB8A8D90", - "timestamp": "2022-05-27T07:37:37.5039887Z", - "signature": "Pb2pebmIAYUNnT0Dct4unwe4OfHorl7piraLNkFva2b4POYPObXzkWcMmEISZR4Gi8Jaj80O/MRufwbgwaKiAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "CF0FAE85885EFE00C2990761578E8FF8D5454369", - "timestamp": "2022-05-27T07:37:37.51839177Z", - "signature": "ttKK/ZU6dRf3nZ+8I12RxHT4qRoiwD6J9XVGGRIt10p3TGgD8AZXGWBOnSjHrcQeyLSs7RNoIEfo3SQYXzq4AA==" - }, - { - "block_id_flag": 2, - "validator_address": "09C809054D9CCEDB5594CBFC96CFFA053D7DD02E", - "timestamp": "2022-05-27T07:37:37.487113587Z", - "signature": "C8RyrqY8OysoJTM3Gj6PxcdyByyqs226ehbzI6WruVw5I+FTkwZ27+mCNSRmoaCh44yukUkA/VHlWi8W+VuDCg==" - }, - { - "block_id_flag": 2, - "validator_address": "6510479A7C51F07FD37625F6D1CD94484EF26AB3", - "timestamp": "2022-05-27T07:37:37.496317022Z", - "signature": "MzW6zRRrvsJSomwZGl6s5TO1Um1+yS/TFUAWhVXJeeXErv7Dsh019F+PNvIjKm1zr0SiTtJbMwUpV8+IuWixCg==" - } - ] - } - } -} diff --git a/packages/node/test/kyve_block/block_3856726.json b/packages/node/test/kyve_block/block_3856726.json deleted file mode 100644 index 9ca2441b5..000000000 --- a/packages/node/test/kyve_block/block_3856726.json +++ /dev/null @@ -1,3822 +0,0 @@ -[ - { - "key": "3856726", - "value": { - "block": { - "block_id": { - "hash": "51223D03D35E04476553C309FA4094E8EE09570178B4B77EB5D663F2BF72AB9E", - "parts": { - "total": 1, - "hash": "2D95CC59E4000651933F9E1D3C63BBC06480C9B6BDD201CB8B1FB08E5354AE7D" - } - }, - "block": { - "header": { - "version": { - "block": "11" - }, - "chain_id": "archway-1", - "height": "3856726", - "time": "2024-03-25T06:14:27.24295008Z", - "last_block_id": { - "hash": "C9C081761B20353325F5C2D8A53068F0DD59BD739D562F1017D047825928DF0D", - "parts": { - "total": 1, - "hash": "B645EAA4F54247468C1BA020A71AFCEFB72EAF900E1F3D219EB3FBA5756E4F16" - } - }, - "last_commit_hash": "935D03A37FF6C9C7BF1C89F6DB1A65AC70FA4A0F7CCFC248ED25251E4151423A", - "data_hash": "CE02B6109F04A6C01EB71819F9D8EF1CE28C3D8B1E37B8EFBFF2A1134BF409C0", - "validators_hash": "BE08D7C9A03E52687DB305B8CEF14F96D353FD6DC66F694C0D21FB2BF4C9C4DB", - "next_validators_hash": "BE08D7C9A03E52687DB305B8CEF14F96D353FD6DC66F694C0D21FB2BF4C9C4DB", - "consensus_hash": "22E3FA2D1695AE7DB62E55677BF0C914B1EC88D64CD8D280CF2E29B2E06D0965", - "app_hash": "4F36440223B8AA53C357A9203054C4CC54F669E59714A5F587AD308C5BD4141C", - "last_results_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", - "evidence_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", - "proposer_address": "F183805F63AD6C429B7157D90D7199F2075280AA" - }, - "data": { - "txs": [ - "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" - ] - }, - "evidence": { - "evidence": [] - }, - "last_commit": { - "height": "3856725", - "round": 0, - "block_id": { - "hash": "C9C081761B20353325F5C2D8A53068F0DD59BD739D562F1017D047825928DF0D", - "parts": { - "total": 1, - "hash": "B645EAA4F54247468C1BA020A71AFCEFB72EAF900E1F3D219EB3FBA5756E4F16" - } - }, - "signatures": [ - { - "block_id_flag": 2, - "validator_address": "454BA446172211B1CB7A08E14161FB3BA1493F73", - "timestamp": "2024-03-25T06:14:27.198711863Z", - "signature": "2e8XvUA4Tbn1wEbARGH8NB1UmMK6MS5vMlZjNBV1x4K1+SOGkqSfMdm/ulWngwiOygqBwLgsvmq/rhikwa2rDw==" - }, - { - "block_id_flag": 2, - "validator_address": "5E026F83F8DDC51308008A80518530E9C03C7771", - "timestamp": "2024-03-25T06:14:27.302921022Z", - "signature": "lq2SyHxljxPnLImJIS2/fPAKqyyP4pmhdx3Zs3mAt6gjK6mZUCkTQ1GVF3GAAzDmQplkbnIT5/Vehi31pja5Ag==" - }, - { - "block_id_flag": 2, - "validator_address": "C64F7CF03BBB07B80E1B557A185032114C1F0201", - "timestamp": "2024-03-25T06:14:27.268900037Z", - "signature": "lY9GJMAD7/zGk0S3Kc7VhE80xggXs68AXiYhiJnG5aB+IhpdEorKdGxXWrw/Tl7V/NNGwfM1DM+naq6e3rBeBg==" - }, - { - "block_id_flag": 2, - "validator_address": "9396A4ECDC186B5F92600579AEC5E04D1059642D", - "timestamp": "2024-03-25T06:14:27.292183475Z", - "signature": "ndgHemJ5qlwxgpfQ/6Y2PqFRNfOkS58jJC1up4gQ5ZYUggDBIVxYdNSqWscmvgpBZkz6IrIfUukO/JnZqcpJDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "192D17EFD1F6012E52A8833717D8621178168264", - "timestamp": "2024-03-25T06:14:27.21504644Z", - "signature": "n2jli5HiR7rDMEI36JqQvUem3RNarjPr1N0tqTQReYslCn8m9r2KRvj13WpaWx1nyc9bjF4/tEBhTmn3DUuRAg==" - }, - { - "block_id_flag": 2, - "validator_address": "56AE16561016ECD1B64540DCE711C588F06E2DBA", - "timestamp": "2024-03-25T06:14:27.204804746Z", - "signature": "SgF01ZGHIwwNjmyGYhSnzf6+xgTJRAozD2c0C76zCHnU7b3lo/7Xg29fJh4AZZw4c4ol8CstNBDh2CCcMSWwAg==" - }, - { - "block_id_flag": 2, - "validator_address": "3ABC887FAAB038EBB82506305FD928270AD2867C", - "timestamp": "2024-03-25T06:14:27.359862997Z", - "signature": "60Jc13MrHdG1zk2OFXEx39n0VfXvRD4rSvsu6gqNJ9FqNM+TcnZGN6nhLQFJ9ijFhqZhJwODI31B+zWJzv+yAg==" - }, - { - "block_id_flag": 2, - "validator_address": "7CF3A6E06DA02BF700E33372951EA2E95AF6A7C6", - "timestamp": "2024-03-25T06:14:27.243732794Z", - "signature": "uYOWyHr8KmR7rsrvgzKo7LJOvP0bPnzA0s3yVePxt6JlzAK+bvOuV1HJ6GBm7cg7BBhJQUzB5YUZbUdGbqwGCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "E89799B6440988A1AAEE14ADA7050FCFBCBE31B5", - "timestamp": "2024-03-25T06:14:27.28412331Z", - "signature": "oz0OU8f0jpbkMPye9psiy+qnE+Hpa9fkh+IlFN8u80Mgi3pB1ABAn4SAt08qGQu3eu/Gnuv21tWnDnmUpGo+AQ==" - }, - { - "block_id_flag": 2, - "validator_address": "E840B5676A5DA43F7ECA8385B461FA6BF0BE2CCB", - "timestamp": "2024-03-25T06:14:27.229527079Z", - "signature": "OY/V9y9gwWgKLgWPW6P4W73BPNAdcGR8KB+XnkM72My81/8NmzCh0F2OBysNRxYZ5qoV0TheXqc2WdVp2/SiDw==" - }, - { - "block_id_flag": 2, - "validator_address": "90FAA31CA9BE4E4BB8E4C9732EB69575F4C5B626", - "timestamp": "2024-03-25T06:14:27.251424274Z", - "signature": "25v4oL8wp+MbgxYl7V9LsCOvoohPeMejbim173bPKvmz9M8pKieyb5LoBO/9I0nHYvmLXuwLYTjj+iksIRy9Bw==" - }, - { - "block_id_flag": 2, - "validator_address": "CB8D061C7D78BAE099C50D6857B97AD4A9218776", - "timestamp": "2024-03-25T06:14:27.24295008Z", - "signature": "vUBPYARoWvUjAEqgp+UwXQSSmIGaW5Gajhi/E7PMOivzpY3trjjknomq3hzR9Jw4B0OQplviiJnRCn9voF/yAA==" - }, - { - "block_id_flag": 2, - "validator_address": "4630574528AEF5F2CE3BEA1BE9E092927E311F0E", - "timestamp": "2024-03-25T06:14:27.18719406Z", - "signature": "HwRudquc1x2MWz8e8a1B8EBhGYQIBMAFM24svk+SfjL/DMESJ2bEQwZvylYdNtRcuHsw6x17EfIHNuVNOAI3DA==" - }, - { - "block_id_flag": 2, - "validator_address": "B2FF86CCBBA2DB501E828E0E9D15EC14D50E0214", - "timestamp": "2024-03-25T06:14:27.191671125Z", - "signature": "y1shsVEvnmu7wPAcycLcpyqwsm2ZWyhpw/biuxFycx0/fhh+BlEX9QUIsJz1LDo52tPRIrbVNpmmTQ+9t4mBBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "CFBD265B3AB49045D2AEE7D001199ABD30BD1E5C", - "timestamp": "2024-03-25T06:14:27.209181671Z", - "signature": "IGfa6KghvryZkbonMVj/pXMQ6A+tsBDVN9OC1+KNBRl35eDe552hRjK07r1To4tMHM5+Fnz59a85ft7hconBCA==" - }, - { - "block_id_flag": 2, - "validator_address": "2348415EAAEAE89FE5A9412F2F45CA9AA5E73BBA", - "timestamp": "2024-03-25T06:14:27.348597083Z", - "signature": "MDv8yml9BxpRdKo/lTnhHfz/mCo9yeIEBbt5KjARvvTXlka5cwGwMW/hdCpNXMPqHqEv/I72mVQo/84tqyROCw==" - }, - { - "block_id_flag": 2, - "validator_address": "E4983569DBE9E32DC1C9C69CBE4DCF1CB82899AA", - "timestamp": "2024-03-25T06:14:27.242449608Z", - "signature": "43gXDvJMGoNR39pQdtx/w1moo3iGxEJM6CLxobXOx76WmtV0lT8izEqHXYOpPJFzd1alGpvmDWzFp7YAk5EuCw==" - }, - { - "block_id_flag": 2, - "validator_address": "F183805F63AD6C429B7157D90D7199F2075280AA", - "timestamp": "2024-03-25T06:14:27.205952311Z", - "signature": "ZotOXk+V0oh5eJFv0E/9l3oMnmLfdsrIu7+C1/Ufhl6W06g+Qx+FlGG6OcoJA4KKym/E7gLmkegZUKCz2B+DCA==" - }, - { - "block_id_flag": 2, - "validator_address": "5F647EE2AA22982E897765117160DA27BD8DD1AE", - "timestamp": "2024-03-25T06:14:27.21051342Z", - "signature": "SQuChlSd/54IYo9N4KAsUeoaXX21lD9Gvbq4tbSqa0QP8awWaav6S8pd0d5UN3Q5DaoJdgmP8JPNOWAowkNZDA==" - }, - { - "block_id_flag": 2, - "validator_address": "C6216B74B71AD3DD522E00D28BF1E7D7B9145869", - "timestamp": "2024-03-25T06:14:27.260030577Z", - "signature": "2ZBx8rLaNazZ93iQhmpAkYABtx424OfrXrDssBhZO3Cs+bO9StVeQOU06WXI0AQqtHD24Aw+Q5EqVAOBAWPNAg==" - }, - { - "block_id_flag": 2, - "validator_address": "31323915F9B0CBC60B4F371E454B5FB19B0AD26D", - "timestamp": "2024-03-25T06:14:27.296428597Z", - "signature": "gR96bGxmM/Xu5MBNPftimPjjgQDGagvG9tK4PA0UKARwf0wb3t4WspRcdv7sf8x05LWbx7CBb3DFoY5jcYA9AQ==" - }, - { - "block_id_flag": 2, - "validator_address": "90F0753D72B15384CD536B1FAE023BD7FF7D250E", - "timestamp": "2024-03-25T06:14:27.294846688Z", - "signature": "urgxmnMfREsnkRtkhs6JaLTnY35UlkabmVDFnmB3qGfOfDeVurLUcBWIe2pAdJAsu5NGqYiKhWwRjPlNxbSHCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "9417D3AA3F23E9D96CDCBA2045A07B401C1E11DC", - "timestamp": "2024-03-25T06:14:27.21561313Z", - "signature": "DQWOigfi6ey6I1U9VGIb5gjEDY/QKXtRqGdxxUVnAPlI0Az+QpHXQ3FzhMj6ChteqVWg/OzIpU8YencUPT0/AQ==" - }, - { - "block_id_flag": 2, - "validator_address": "38303246077ABA69E2782CB2C71C89DE9E2B7BCC", - "timestamp": "2024-03-25T06:14:27.273058159Z", - "signature": "ETdEehLafzgsITa1hBtEjKUcIg5SVPcrGUAmpW64Dju2AcfFoX7u0Hh8M3YW1JHb0ad0cZNC93q2Wm6NWtStBw==" - }, - { - "block_id_flag": 2, - "validator_address": "1D143C66358013DFA42A05A3BD9D00397AFDD6D4", - "timestamp": "2024-03-25T06:14:27.26998412Z", - "signature": "Xbhtj+DbTXVOLXc/eCszWFHCun34INCAn1OC9IxSM+pj261HVnUauh001rnFxzBjD52mxl7Wi2i4KoFd+TXxCA==" - }, - { - "block_id_flag": 2, - "validator_address": "8F41A1631BC7D5ED4915B673297D2F60A22C6E34", - "timestamp": "2024-03-25T06:14:27.208788012Z", - "signature": "vJts89t3tXLBb6LB/CF5UO1/l+gQP4teCQIOVj9Q3trUHB3SE4u1T9IPeQL5gblXTiwARrwkbccCuI0NUztlCw==" - }, - { - "block_id_flag": 2, - "validator_address": "8B714B0E76353D945D98D4974C8BD0B0748EC196", - "timestamp": "2024-03-25T06:14:27.233740258Z", - "signature": "hkqqwoCiTCNDURwo/9Pj4KqQ4cWKSnFnlqktW9wsohfmNdEZWjBCuFPfO7Etr2pfh0Cv5DVe7yTc5Sm4Nok8DQ==" - }, - { - "block_id_flag": 2, - "validator_address": "94B06CE54895A6138DB5D3E406E5914ED41445D9", - "timestamp": "2024-03-25T06:14:27.249889348Z", - "signature": "Fn/3ESz0Z8c79L37hKlyeSI3RR8ztarlrCmK8HLnU9CD7jaO1O9MJziqE56vATpHGAkDZEKPOSCbwJGu+cdgCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "ADADEE9B97C69600FEA8911323F3F5CB28906EE5", - "timestamp": "2024-03-25T06:14:27.399513013Z", - "signature": "Xb+eLvN/0KMqjCcYlq20t/gdR2tRf4f6p9w3IlcCseoR6F4p3RyHAV2RZ2TszcjUP8VYIAdCgukukIxofZhFCg==" - }, - { - "block_id_flag": 2, - "validator_address": "FD1E562DD7FA1296ACA834EF29AA0685A8AD8F33", - "timestamp": "2024-03-25T06:14:27.201830902Z", - "signature": "OMhImUqKrB6sbsBfDRcr5+F/+L4oNH8KuP+nBLmwp8RSXvW65oxMEyR/O9KqMtUl5Ib12TwI0BIHxNUWHDwaBA==" - }, - { - "block_id_flag": 2, - "validator_address": "A0212325DA0D8E777AA60AC5DA61DE409072726A", - "timestamp": "2024-03-25T06:14:27.208975888Z", - "signature": "nFEzQvXWCQzfQO1g7CAp5Qr8dgy2eOfF3WeWgcolIxq/2HSbLDO3uB+iIWMEkSTSkh9Zk/H1yCkeNfzMaFIuAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "CF65D933DAAD0646727C76795AAB0DE423B8C0E5", - "timestamp": "2024-03-25T06:14:27.216374782Z", - "signature": "GQZAf4We2Q3mKY1F8AVEirKOU/VXo/Ia1JJfkx0VreBDXqhAeJ0h/q64G7oXdw02Ed11Kc3CoqK7CtXuVAJBBg==" - }, - { - "block_id_flag": 2, - "validator_address": "80FF2FDD961F707F3C005A7FD41D55A74F076AA0", - "timestamp": "2024-03-25T06:14:27.224969374Z", - "signature": "tXcyjOQTYwoyhvsDhfAamhPjpLDytPKFsUIbVYeZO/hwmgnrZS8G6IH50gSS4BfhcMPQ6Bp0oRF0R8bBwldyAg==" - }, - { - "block_id_flag": 2, - "validator_address": "FF592BF088B8ADABFA6080AA820F7903F0F02046", - "timestamp": "2024-03-25T06:14:27.306082208Z", - "signature": "mqIIRczB6lyk6j5CqUK+VIun34fVFA/50fV6qcHZkJcCaYxZC+CKu88/KVPXfsCOHEEBxnvCC0d/AGpTPVbWAg==" - }, - { - "block_id_flag": 2, - "validator_address": "C5047A5B0C008A531993140151F3E54C1308A86F", - "timestamp": "2024-03-25T06:14:27.211417554Z", - "signature": "0qJEczrpIYdF8sdNT3p0gYivAFT/NeUvbml7mOkyDA/bsHGeXVDX+n5aLrkx/fYyqhs+rCB7bv23j7mI+Mn1Dw==" - }, - { - "block_id_flag": 2, - "validator_address": "43EAC69067530360F849375487ADA1F26FC026FE", - "timestamp": "2024-03-25T06:14:27.221068884Z", - "signature": "doK0ZlUgFFtnPJLgEXTp8W10EGXBBZC+u3YNYe1SD33W9LG4uTXfj0t0db4XsD7KIaZ7QWmdBP33ew0mStwKBg==" - }, - { - "block_id_flag": 2, - "validator_address": "5894E2D8B68C01CBC835985BADBF0AE378A5A6B6", - "timestamp": "2024-03-25T06:14:27.262841804Z", - "signature": "aQDifQtR7PY8mmujd353OZGJRJozbbPg9BpZP/WmjXQDLI/vuDDTMUJUfw0/JE9cDra42hnPQ5pf/8aarGWCCw==" - }, - { - "block_id_flag": 2, - "validator_address": "94A81ED9CF1EFE9672501231F0255F0C54A4F411", - "timestamp": "2024-03-25T06:14:27.213546159Z", - "signature": "SUpF6JTYtVLUX3QDVS5qNlSiJg8Nco3+3tO+XZ9ehfUFHqQ7hqchj4OFBHNbtF6KOZbolGz04ZSZrEaV6PTyDw==" - }, - { - "block_id_flag": 2, - "validator_address": "D78997B5A01D2D4E80C5189D930A14055002B478", - "timestamp": "2024-03-25T06:14:27.209686721Z", - "signature": "AiEAtstORITGefKUuruXaVLMV2PddgE+MvNgoefPNnaeTVRPRsgcMYCfk6TsLGDCkih4uTpGJIKyly/h1NIGCg==" - }, - { - "block_id_flag": 2, - "validator_address": "69C38FB90624F19356482DAA89E64D9957A37C00", - "timestamp": "2024-03-25T06:14:27.197381186Z", - "signature": "0zJHwlFfrnEX88Yhjwr7Mp/2UCaL66KY9K1H5DXwGjgBb6O7ozW5Ku36+RmT8/QFM+pQmQHUHf32De5nrpzIBw==" - }, - { - "block_id_flag": 2, - "validator_address": "2D63B9079FCAF8CEE74B072665A04599064BCB09", - "timestamp": "2024-03-25T06:14:27.187860932Z", - "signature": "FTIy7zamXLA6S/NzmMDHv7sy5/FGcIpChtLmNgzFhUz59P7uV2OT1RRVD56nWabrqCMOV6Qio1DEIdiptFoBDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "1AF66CF8C90E5D334FB095B4983210FDC2E2815F", - "timestamp": "2024-03-25T06:14:27.2934702Z", - "signature": "BmKsz5Lt6sxLRyv8UQDsYKuyTRJeuyG9NjAMzXgw5T1Da3Vx6EpRqhm5lY4ZpBzVLagXGD072Ix4q8Z56wV/DA==" - }, - { - "block_id_flag": 2, - "validator_address": "159424CD4756CBEF88083C1A11B6033423537A3A", - "timestamp": "2024-03-25T06:14:27.395386931Z", - "signature": "LP+S1UnorS51jwWhLUbepP/sgezYL1CJInFhR2c4oTc+k5iabeFofw04ZW/zQMNebDHXNF6oyWubaD2KnGc4CQ==" - }, - { - "block_id_flag": 2, - "validator_address": "C406A6BFB29F36979ADA959B917DD4A2A780E519", - "timestamp": "2024-03-25T06:14:27.299496138Z", - "signature": "7HTkVqMSkgQc3PqfW7twXSI9sIrkgwfyn16KML7y6gB677rk2Wn3YvVL2rn7JfC2Cnbj5PS17o53y7+76wY6CQ==" - }, - { - "block_id_flag": 2, - "validator_address": "92C0FD982DEC037B295494DC7ACF25FBB8E3EE5C", - "timestamp": "2024-03-25T06:14:21.339631074Z", - "signature": "9vtjqiTYXLoP6728kPDuJnt5Dq5cwauRcXs942pBJFw3go0TP2hWojpO5ljf9XqaUDdffIHqSsyclALtIqi5Bg==" - }, - { - "block_id_flag": 2, - "validator_address": "5883CB9214B4FE1A0CE68774D714425DC6024D52", - "timestamp": "2024-03-25T06:14:27.241979083Z", - "signature": "ILVsPy44TCgUW+VCQLazvEma7Knr/G9TgZF5UBHqRCkMu1loWS4WhfaLUeXYxWJ/oTzSt0B0eD1hoSYtJP3xAw==" - }, - { - "block_id_flag": 2, - "validator_address": "6C6412282FB32525FD92617157F154579434F9FC", - "timestamp": "2024-03-25T06:14:27.204271239Z", - "signature": "snrhUC6Qa3dhiQeIaI41CYAS41k91X544LpEnk24LHzEwSR0u9Qbrfum3ocvxfldTuC6N4S2URuGGIUfjU+0Cw==" - }, - { - "block_id_flag": 2, - "validator_address": "EEB553125D331715F799680FE763B33D4D8EC063", - "timestamp": "2024-03-25T06:14:27.233977273Z", - "signature": "gctjdRc+zF9OEV3xa6X/cjIaOoOVyOwWwumCbbomNmlv4VRyi6ctBJHVHtbrnampkDdT4EF1jwRriAznffzfDQ==" - }, - { - "block_id_flag": 2, - "validator_address": "DB2D66F06C70A06818910685E8A51C73E6EF3324", - "timestamp": "2024-03-25T06:14:27.226749145Z", - "signature": "BIOK4yc3z8qjpeFyCAQ9deVWFd+N/JWBtyJCM3WoP6oeaCdImZlz1GMZpFdu/q910OlJ5ovLeVEPgKm2ygYeCA==" - }, - { - "block_id_flag": 2, - "validator_address": "07F4F6BEAC490B1508E93E38D9E5B3DC50716200", - "timestamp": "2024-03-25T06:14:27.325335199Z", - "signature": "PngsVhXlpeFwn/0SxHolgxNkKH5lXWkJKskaYJ6XlexUPImbJNT0dbHoWGqeMmaaHONyhvTL6rJZgZ+/SJtvAA==" - }, - { - "block_id_flag": 2, - "validator_address": "32F529A962B3F9D7896BD858D9970E3C1392570E", - "timestamp": "2024-03-25T06:14:27.435809271Z", - "signature": "P3b/VPqrxBgxf1uBMd+3oNssgAWvzJTYzSHTL+msiTEGNvXWJWO/iuzds59daZO5ZktKHLeebX/8hSO0LHPUCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "223BD658ADC0BE9E1A318EAEE26A927E9B782DFB", - "timestamp": "2024-03-25T06:14:27.298543778Z", - "signature": "22Ci/5gtqsUekp6U1XIPDU/6a4f9XJNuwPu5lNuU2GLcAeW5ztZqMHphb4kT0AHGdn04g41UFlKGaRMUmybbAA==" - }, - { - "block_id_flag": 2, - "validator_address": "B155936FBF30A4A21C2FD9B2A3CC1C2CACA9DDE7", - "timestamp": "2024-03-25T06:14:27.314051454Z", - "signature": "6DoBNRasJfqp5eTsWkX99hSTtq8aFYg7h1jydaYpB5DQAL/J5Tie0w1jd8gq981rZBOVUgfNuPkpl7OonwgsBw==" - }, - { - "block_id_flag": 2, - "validator_address": "D0810844A5202004AE1249CE17610A4AA5A1684E", - "timestamp": "2024-03-25T06:14:27.504915992Z", - "signature": "yB9nGNImbiz1x/fc/wMEnmbT5vahaPEWolorzE35PhOW+JveeTH5wXVfc8V2+PKIflFPn2ftbR/j7Jvns96GCw==" - }, - { - "block_id_flag": 2, - "validator_address": "0C170D04155D212B97B3D33AD24D0076053E70C2", - "timestamp": "2024-03-25T06:14:27.282067495Z", - "signature": "5S/h/C2XHP70XYO7WXAzOOHZCz0eyO+RLNO59c7VVfZcPloEomvwrVlyG+UOL1cHV0BxTqHOmy82+V0TE3tZAw==" - }, - { - "block_id_flag": 2, - "validator_address": "2859D4F84CABF0136BEAF3EFA339F5BF6F6CD39C", - "timestamp": "2024-03-25T06:14:27.229881613Z", - "signature": "GljjGBNXjaJdU3yObE7h58jJwbCoAoNLMtjvpMYG/UHtrk3vBvxiILksgS3nKxXnLYv+8UDqNaM9BYRs3cKlCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "195623E1DDC7F85D8E5015D79B9D0DA47A7F59C2", - "timestamp": "2024-03-25T06:14:27.238487848Z", - "signature": "UFjUdS/aJgk2DPWC/BJKgMmqIuGGQMrNwdAdLFKcRjHfjNmBS2JanaSt43Hrlrpha0USzAOUYecVp8Qnif+8Dw==" - }, - { - "block_id_flag": 2, - "validator_address": "7B0411064960AD679FC4A64A7066B401DF3C7F52", - "timestamp": "2024-03-25T06:14:27.294517354Z", - "signature": "xuSuad88AM2c9Jp3n3Q/tERfFoZrxBPv0I59ZJl1rLvqPE3nZBOuCBMwZPUCEa9136QsNfpXEemt/4jlliN5Cw==" - }, - { - "block_id_flag": 2, - "validator_address": "8066E3C72BE72F9CD84439FFB59D79B2C316C01D", - "timestamp": "2024-03-25T06:14:27.297025738Z", - "signature": "SsE4E3QYw+1rk9uhObCu3YUlHQSoREfMeVX456rSeQLhU+Lppat69YtxnG4FWGeBBzgMZ+jg+s+GyWhVOIjDBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "8CB1BE337D1427136EB8EDDD9232735E2405C50C", - "timestamp": "2024-03-25T06:14:27.248658018Z", - "signature": "SOO5yhm/Zs/qgTMYbId1yn44P4Bo/88BtNvJBEmziJeOwrpwV0So5q1FDQ2pK+ddAsc9ampt2pIA3gdlNimgDw==" - }, - { - "block_id_flag": 2, - "validator_address": "83CC77F0F60F418B9DE2A24642645777D2FBCC02", - "timestamp": "2024-03-25T06:14:27.254563507Z", - "signature": "aEt+2hSYgJibHGrvCK47cq4NOFSYyQR2lBn2qK7V9KJSRN0ccB5Bp/iM/OyhlJ7PrLOWanQghCqzotcQQb0KAQ==" - }, - { - "block_id_flag": 2, - "validator_address": "D83516A8B94EA1DB899B7C80C76C05D0BE204004", - "timestamp": "2024-03-25T06:14:27.250738609Z", - "signature": "20E5FZHX7sCgykdz7wpaMpt/xCCUPy/3joMlb3vqagUT1OqVgFj5IonKpFPz8WDcZCDv2CEAjc2qzSb0zNAYCw==" - }, - { - "block_id_flag": 2, - "validator_address": "DBDE432B755C38F3136A75D2D3F530B5A74FBDF2", - "timestamp": "2024-03-25T06:14:27.226292884Z", - "signature": "OampF/a5bMIBndboMuM+rsJBoa6rDS1AKYQLf4QV3elgVSxYBPaWh32NGzKI0FvKtfNCo82GiWNyKKvBTXfiCA==" - }, - { - "block_id_flag": 2, - "validator_address": "8F9C9F4EC28C7E06F3D348394270FCA69DBA116B", - "timestamp": "2024-03-25T06:14:27.294859322Z", - "signature": "Aid0oQvPLKP2Ab78Nj2jnw/2TVc7ojnh8oi2q/dETrip9eEH8XSeQJ9+bKnFU2oKnmcK1FYkKwGzi5m2EfpEBg==" - }, - { - "block_id_flag": 2, - "validator_address": "F9F61FD65FB010A8C9365032D83CCAB9FEF69BFA", - "timestamp": "2024-03-25T06:14:27.20862173Z", - "signature": "Raa83ztno5967q1aeVw+SKas6WPNJz0xHOb3z4fAxrAZemNR5rkrEcBK5Dah6l8nQ70m0Y1OYRUEV1GE93e5Aw==" - }, - { - "block_id_flag": 2, - "validator_address": "02425C209B7A5BFDA29FEEC5876E12AEC64D4C81", - "timestamp": "2024-03-25T06:14:27.198883431Z", - "signature": "aFf3eD567PWOwcSWeKXFD156lM9AngvM6w738tUQGj9sI3sLLj+qHFDe2f54ZDx3ybBt01bpvk0Td1isEDhQBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "37CBD9EAD6B6632851646323C2D9127E79B1C37C", - "timestamp": "2024-03-25T06:14:27.250703418Z", - "signature": "aslqoF8TjiCalfO48S98TW5mdfUZ1IP3MK6JWupdwxaVwcEhDcr4wffSK5nqXSHdPhdFmSJsY16jN+4YfyCeAA==" - }, - { - "block_id_flag": 2, - "validator_address": "1DA762F8A91B63B90817D5D3A20D0A3E8CB240C9", - "timestamp": "2024-03-25T06:14:27.20908433Z", - "signature": "9kdJRK8+r0RRZ+q5eQQJPaP+17PKYyImLyHd5XOJqWU4JKS93eqQT6JHKJnTBGo0WAubVV90PI9DvgiWNtrpCw==" - }, - { - "block_id_flag": 2, - "validator_address": "012ED7FDCAFD53E87DBC4F98DCC93B73E30FFA2D", - "timestamp": "2024-03-25T06:14:27.270230258Z", - "signature": "gqwtVHmUbqy5DRDGg6eJjFS4nQgWmmM6e6t4Yx421IF/8/oWZeeMcjjFzlMxX4NonrEB8VBGHvY9hKL20/r2AQ==" - }, - { - "block_id_flag": 2, - "validator_address": "E27C9D446FA6A9CFCE43802136CF958E7F939226", - "timestamp": "2024-03-25T06:14:27.216205479Z", - "signature": "PC05d40CuIxreCOcSWZ4mLm34hTYPWMMpBdcSHxOsQ/IU3MLP3PTikl8j2ugL3umg8OCxnxT2ef80z9df388BQ==" - }, - { - "block_id_flag": 2, - "validator_address": "0B854339BDCC14B85FB8711E41C2942377476F70", - "timestamp": "2024-03-25T06:14:27.209033257Z", - "signature": "l95YxnFCwAt1QuqXomDAkzc1Mo6R9j62BHT0tCSpj98rm6PCjsfIRvEP/+j+gQEqB4jJvqq2U6ZYosm3950NDg==" - }, - { - "block_id_flag": 2, - "validator_address": "ECEE73D95A77E41A4AC3148D75BE7AEB02CC147D", - "timestamp": "2024-03-25T06:14:27.300665187Z", - "signature": "X4XT2w9MkSXRn5NDElBwstWc9nhGGh5NJzO68WUXbZGH87DJlR+V2NdEtYz1/2gfaHw2DH1CLbVN9O9xL0zZDw==" - }, - { - "block_id_flag": 2, - "validator_address": "E3DE542C5573C78253BF5DA6F20E2119C0F1BA48", - "timestamp": "2024-03-25T06:14:27.240320031Z", - "signature": "HeMVDGr5kMtKJe0QRFy/CR3CcfY/xzYb1zawQtvfMb2G7gc06jJ4fd+4OM2JjUrZzG8W7wNx9EWYBzg3wHtwCg==" - }, - { - "block_id_flag": 2, - "validator_address": "1A0DD1BA9B3EF21F6414210D0AA35EE0F9A12BE0", - "timestamp": "2024-03-25T06:14:27.248713782Z", - "signature": "Q9bKIijvXNhhpTJw8GYCn4L6v91/pU6Zc1DjhEofzSkQCzn514glSpn6xs+WQxZw6br6Dn35k42jkdQ8fdT3Ag==" - }, - { - "block_id_flag": 2, - "validator_address": "3E01DF5EF729ABFB3CB4E8CBAE5062D685009FB7", - "timestamp": "2024-03-25T06:14:27.216058329Z", - "signature": "qUlOsW7hLc4RkBFDR2vSqGtpqRsaY2S4c0kr5qgR0rdCVwfOrkVjhBDrtM23nBiRmvzffpsYEUZm687WXmrgBg==" - }, - { - "block_id_flag": 2, - "validator_address": "10AC1B41D924B67539EA8D755FB0158D57B0F555", - "timestamp": "2024-03-25T06:14:27.260938966Z", - "signature": "QG/5BZ+4eq7sJkbrSeiQf41c+yZqbKanwFkIYGD/wiiNMYEhq1b3iZwS5bJKKRLb4zGprDKQ9vaohyN0eSdJDw==" - }, - { - "block_id_flag": 2, - "validator_address": "F5EFDE8E7BF30A548B847ACD250407CF0CC0539E", - "timestamp": "2024-03-25T06:14:27.211301742Z", - "signature": "1fdvlOuPcdAzrMFJxUgUGbRqX8OP1pb+PvxBUFGqaIFtxn+juxFXF15fvHiGjzG+MSF8w9SDzWjHBM323+0ZDA==" - }, - { - "block_id_flag": 2, - "validator_address": "E42A113076FE41D20780BC6F2FA1C700B2756193", - "timestamp": "2024-03-25T06:14:27.304878958Z", - "signature": "LiS/Ncw9LZpOZ7eSxl3mrflu4EFoK+92+81btwv8OH1112OLCcuoUP8FkukKyD2A3eP9asEmnFoGYecMxU/YAw==" - }, - { - "block_id_flag": 2, - "validator_address": "A468764E5AC834870F79453F1CA26060DEBFA629", - "timestamp": "2024-03-25T06:14:27.232074527Z", - "signature": "owk9vcDs3qppskTOF5ukfV40YvWd3uKT2O5OpB+RkvUhsN49HeUCBN+twoNN2yE99F2M0SEitXRdKD/0rqQZCw==" - }, - { - "block_id_flag": 2, - "validator_address": "7991CF87E4FF6C6D46376939E6E7214FA7473AE0", - "timestamp": "2024-03-25T06:14:27.24642099Z", - "signature": "5ekIibouYY03U0xtyEJH3b2DY5rBsQmmujd4q+P/Hz7Hu6fjqsDVe5r/w5Y+SyJW4Dpeu3IUBlHRLtMdWrU6CQ==" - }, - { - "block_id_flag": 2, - "validator_address": "132A20818488C9362C9E37E529B879CBCD6FBDF3", - "timestamp": "2024-03-25T06:14:27.252922227Z", - "signature": "6XS3kXciqm/vyY5bILQ8+OIqNitOvmjcoTFECvuSwxQXonh3oLl9qDYMetl6TZzBfmWxOTwrvETU0YKanRP1Bg==" - }, - { - "block_id_flag": 2, - "validator_address": "4C10504F2614BE17668FB7EE4CCDC9BDBDC5E94D", - "timestamp": "2024-03-25T06:14:27.198949987Z", - "signature": "x0mukdGORqepq+INtUB8sifZ0EtHqhzXFZIgA1OMHyMEx3vg+m8qHdrxjfbN7QQcdkJGblG2UO9EMjQO5Tl6Bw==" - }, - { - "block_id_flag": 2, - "validator_address": "152DBAD504AF9B1C103D3D4BBBB472C45758F301", - "timestamp": "2024-03-25T06:14:27.301151981Z", - "signature": "JJ3DoJqBz2YjqdYElJT39L+viwFYy+svDpzgRBCflUGYDy41YyejvI7EoN21M3AbRylYVQrR3kF32aTvccTxDA==" - }, - { - "block_id_flag": 2, - "validator_address": "2191940572E2B2E4F477DA155AE95FA3697AF3D3", - "timestamp": "2024-03-25T06:14:27.222339495Z", - "signature": "RCpNsDllj2GCQ/wkgPlXPMB4a1b52U/kdFlasvR84uaZKhbf5vZKlQTlNMRk1UQ8OEduRfWuUUuVAnc8te+ICA==" - }, - { - "block_id_flag": 2, - "validator_address": "AF28D38FEA9D6F1A8559AE134EDA0F1FE1509768", - "timestamp": "2024-03-25T06:14:27.2892123Z", - "signature": "YvuPNZ2Pop9TeQjP231tgShezvdoIYj617baGJbRBfNxnuxzU2ZuouJOO2AtTgOr3yxxLmuntl7j21OYUugCBQ==" - }, - { - "block_id_flag": 2, - "validator_address": "8D0008FE0C7A6EE7BDD1D59CAFFF96AE369C303F", - "timestamp": "2024-03-25T06:14:27.318615916Z", - "signature": "TMQnpCOmCG/XciqY1H1X+DRZn9d9a9ODBOgZAmGY1z98z3Le6ftIOtV4nBLNYbOw7JscKCy8HMTGOfUQTB32Ag==" - }, - { - "block_id_flag": 2, - "validator_address": "88102131B351CE7719EED9CADB15330217A9D038", - "timestamp": "2024-03-25T06:14:27.239020415Z", - "signature": "94mJSDK5AcChfp2Rs6w/LCl2Oa37J+S1wuqJD9MNDsSv8nx3ysxh7QkBqQrJmlO6z6zHQUw/H5frCFsAXqy9BA==" - }, - { - "block_id_flag": 2, - "validator_address": "9C3BFE7B68E53DFF9D3CF7B70E3B8115AFD42411", - "timestamp": "2024-03-25T06:14:27.402701022Z", - "signature": "8Pk9YesjiQUC9bTxL83CeDtofxEm6YesuPWfN3luxaBFY9crRetMZq6dVizo/lJz/teN2uLlVaKK4wmlivapDA==" - }, - { - "block_id_flag": 2, - "validator_address": "39BB490F1B1554AF3FB524CC89D1533EC5A02E2D", - "timestamp": "2024-03-25T06:14:27.203968116Z", - "signature": "tNL9c9RvIDEZr3sxrFzxxuzVnGZLFGNFabqtyEhDGzYp6fRtXHtcLOWkZoZVTBZsQ9TXRGADsNhxJbcTElenCA==" - }, - { - "block_id_flag": 2, - "validator_address": "750CA8CEE4ABA1CA93D1E0A524F26DA8A64EF7F7", - "timestamp": "2024-03-25T06:14:27.23364418Z", - "signature": "R318nz6/+S8PoN/2C/wHiT4zQdyqe5PlPP0C0ArZJ3DnK1NfM4O073tWOcQ/CTh24690+xhWRjOx32QfduEFBA==" - }, - { - "block_id_flag": 2, - "validator_address": "DBAC8BF532C03354ED8BCA5FB7992EA14C1B62C1", - "timestamp": "2024-03-25T06:14:27.263448028Z", - "signature": "1NFURpxVZOD3gXu9E7Bg77suvhIeJg6D5i+fVUTReoQnE38aJJwfCqrKPpnzkDOycHZlkONg/VkfMK0Cr5oVBg==" - }, - { - "block_id_flag": 2, - "validator_address": "E7F7CE3DC63D23B2AC7A233A432F8C7ED74B23B7", - "timestamp": "2024-03-25T06:14:27.192866526Z", - "signature": "n385e1IR/y0OfFgT/8284XFo+DP7hLA+LvNse0IhMnpZQpfn0z9Zwv5a6S16pcKGLtGcSS8bmTMgmifHOBb1Dg==" - }, - { - "block_id_flag": 2, - "validator_address": "23D911027C3A30470D63EBC2EDA4D71C91412543", - "timestamp": "2024-03-25T06:14:27.318050596Z", - "signature": "4ReDzyty2bN7bgbm5gqa+oHxL4oaxDzCOjqUIsbutxk+ydUQVoncqEbjVwn7xT69k6R5ZiHjzVrslJdGO72sCQ==" - }, - { - "block_id_flag": 2, - "validator_address": "4B71B41D7DC82C7F44FADB7D527011678B14693D", - "timestamp": "2024-03-25T06:14:21.339631074Z", - "signature": "IGYRX6oOdKREREx+EmWDVYy4w7qsg3oaganYXH26V0S4hJLDb+ZbCDwIb1YNaolm2ASnA8ebbSf3eVwc7IkRAg==" - }, - { - "block_id_flag": 2, - "validator_address": "3A0C2AED56A4E76E52616CD336FBC311B3799322", - "timestamp": "2024-03-25T06:14:27.250498816Z", - "signature": "E2g6oC0ASeqUU8lUNRjGTkq6Nh7OjzjHgJAk2w9j44Xfl/iY0h1XClsASLOYBU5mi0jcwHtNGDiSebYszwhDCg==" - }, - { - "block_id_flag": 2, - "validator_address": "C071D8A87D78969620BC2D1AB55DCE5B683851ED", - "timestamp": "2024-03-25T06:14:27.217216828Z", - "signature": "/UaOablXzYlqttOw+DpJleRa2RbkOlFL+810RkWnMCN/kOKfaLXs283LOVVXcpfq3FL55m9/Se6WVysZZWoHBw==" - }, - { - "block_id_flag": 2, - "validator_address": "180049B647B4CE71C46D70E1AAAB869B2114D0A5", - "timestamp": "2024-03-25T06:14:27.276196465Z", - "signature": "0aUNZyRMWarl5PmjBpFFoZC0NQDIc9DWiVujKc/12VRpK7q2B8pmTRazKSKIPpCHyhccGuT8ZCnmzNXugG9fAw==" - }, - { - "block_id_flag": 2, - "validator_address": "C875B64A69611343F68BD7F1B81C16F971876720", - "timestamp": "2024-03-25T06:14:27.201976056Z", - "signature": "zt1C0dJQ2VM5LbntMfBNlo4FG45DoAJSydKY+siyF55pqdsxG3QW8lZY+QS/xNIDvB1zLce2d2pKNnqXiYmvDA==" - }, - { - "block_id_flag": 2, - "validator_address": "B6411041F5AA0C6E38612CC8E75BB70E74D0704E", - "timestamp": "2024-03-25T06:14:27.232543158Z", - "signature": "Q7HCCILuaWqAyYvcCLZAJ1Y0/K9DjXK3vi2ULYnBPLAUIMzK+6Vpqlf5qKwzyAyOJmFvg/iyGQp9SUgmTUunCA==" - }, - { - "block_id_flag": 2, - "validator_address": "ABE6553C7FCAB8753E1E2E0FCE046473F93CD6C3", - "timestamp": "2024-03-25T06:14:27.243673233Z", - "signature": "7jeKeynSTUFmxYOOWPXATSiL0Cw8aNY7zqyNqULCWANXBjrMIOOAFQi4MsUUxycX5fY+1bgWV/MWZvbq5UqOAw==" - } - ] - } - } - }, - "block_results": { - "height": "3856726", - "txs_results": [ - { - "code": 0, - "data": "Ei0KKy9pYmMuY29yZS5jbGllbnQudjEuTXNnVXBkYXRlQ2xpZW50UmVzcG9uc2USNQovL2liYy5jb3JlLmNoYW5uZWwudjEuTXNnQWNrbm93bGVkZ2VtZW50UmVzcG9uc2USAggC", - "info": "", - "gas_wanted": "484467", - "gas_used": "403673", - "events": [ - { - "type": "use_feegrant", - "attributes": [ - { - "key": "grantee", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" - }, - { - "key": "granter", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "update_feegrant", - "attributes": [ - { - "key": "grantee", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" - }, - { - "key": "granter", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "436020300000000000aarch" - }, - { - "key": "spender", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "436020300000000000aarch" - }, - { - "key": "receiver", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "436020300000000000aarch" - }, - { - "key": "recipient", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - }, - { - "key": "sender", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" - } - ] - }, - { - "type": "tx", - "attributes": [ - { - "key": "fee", - "value": "436020300000000000aarch" - } - ] - }, - { - "type": "tx", - "attributes": [ - { - "key": "acc_seq", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4/16618" - } - ] - }, - { - "type": "tx", - "attributes": [ - { - "key": "signature", - "value": "BumjcrR0vVFIKuVEKGTGEiunbHUhBwxCvRP/Xx1ZSstpmRuWGYXspOe1yhyOtjG3hGpDu21Tj4Pho2sPDwqAwA==" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "action", - "value": "/ibc.core.client.v1.MsgUpdateClient" - }, - { - "key": "sender", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" - } - ] - }, - { - "type": "update_client", - "attributes": [ - { - "key": "client_id", - "value": "07-tendermint-70" - }, - { - "key": "client_type", - "value": "07-tendermint" - }, - { - "key": "consensus_height", - "value": "2-15581441" - }, - { - "key": "consensus_heights", - "value": "2-15581441" - }, - { - "key": "header", - "value": "0a262f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e48656164657212c5a4010afd3e0a92030a02080b120a616b6173686e65742d32188182b707220b08c0ac84b00610c79bc8022a480a20922d44f2f302a137e504e1e13c5db35bcaee72048cad6c938c973a3a88cba31e122408041220e3a4c96bfb381a352849de7f701d75a65756fd247e2b66bca84c0486bade38b93220ff89aeb30b95970271355e66c5cf6f5a3759b8f98140b304e229da94be82aa2d3a20b00698a377c95210ab27810302fd90a4b3c92e7965e6e6ed0787d3f2740e2d1f4220e8d022f1af4597974007b2d1bb08b67c53b16a751b6c7c7f110adee60a6b433c4a2017bed346ba6ba721b8eda75e77e94874c944bf1a5c2a09b047ecbe62fa4d293e5220048091bc7ddc283f77bfbf91d73c44da58c3df8a9cbc867405d8b7f3daada22f5a20360989c22a580cf79524f65c84c33c84a19b148131ed545a8abbecc4f4cdd883622092ae11933d53f4bcf0f988bf0ded0a23182ef48b2b9737d9aeeb1522e044ae6b6a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b85572148fca7539afd32000bf2c928fc69737483c49b75b12e53b088182b7071a480a202aba4963d64d21e23de083b5628fa44af519509483a780126e8f683be0fcc4d9122408011220b8756df795d8a350b875893cc8d125dd48ea6a89a8547fcf44b81a25b5a3a6bd226808021214b1852d17fa66b5382a8f770725cc5b228b3577501a0c08c5ac84b00610cde3c89a032240859df3a1a0bded57a0c491cb2ff75fa76a9a7483d74105c558cbcfc6f7892f57791a8f3bc1f142e916a23ee75a3bc03f314b8b9a0d7bad967a3e351f21f844042268080212142abc4854b1a1c5aa8403c4ea853a81aca901cc761a0c08c5ac84b00610fb96c2a4032240cb64bc7eb090214ae00aedbe9752e66f7997fce1933142b8a7949ec747dcdd89e8e8d0019bb720344def6d4dff02ed0f176059489101dcb4a1792600d7a40a0322680802121425b40fd5ae2ac26b4382b746f6cddb8c73ce60251a0c08c5ac84b00610d1fcf8a6032240dab2c9cce83842bdce9d53819555f416f29077b0bad03d7f656c1ac3dc4ad3bc6c357d556eb9da5223f9edd47753804eb6f04a6a84e8745257edaedefbe5bb05220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212140549633adf0dd5e91ec75458cbeec35ae4331ad11a0c08c5ac84b006109189e1a3032240fb4af079d53daad6894e66eff8f5d8be255e30b59407ebdf106c66f004cdd5943b0cf8d22d088047d58be23dc5e39cf29615659aaa0f5f2f29009dd6ed7b7408220f08011a0b088092b8c398feffffff01226808021214fe1d612fc9c346e51fa20ed491ebd81162c0e1101a0c08c5ac84b0061095cacaa903224012903fa5ab2717225df16e12c51e01335c54fa5f6baf5e81d2bd273c9553e201799687f10f844067ff94683c05a51520766b2ac1993b6102025a3e632dcdb604220f08011a0b088092b8c398feffffff0122680802121439d8e563c1af1285095ff5bee373e235d63d0cae1a0c08c5ac84b00610df94e7a4032240d321a1c03391bcb663c0d1483015cacd1d82a30158a88b5a7e16e09dbaa0f28a994ad1ba549846994927a8eaa26cbfd3485a1c223c9f2cc356d404ce48f65d0922680802121459835dcbb6ce79f1d12b86702e8690e5f5c514e51a0c08c5ac84b006108cb3a29c032240502a742634bb3dfaf9698a12b679b9c5a376529d28c0bd96543a9f97b39e64ba67b45e025ebe7f69f295ad2c571f5b09f29f01ffc973877f8db84ba8b45f830a2268080212147bd85b0a30cfae183af900b65bc0ec0a28063c991a0c08c5ac84b00610beabdfa00322404cee5b1f3333a536b6a2ee8a88dab1bb8f9bb96a7adef3017d91bef73e4ee68b7cdcfb17a9a81c22072590e0751b3f1d38dc3c85b266ab7b27f015b180d2ef012268080212140218a7a051c04fec85b4f92bfb00a8c4da1a9bd51a0c08c5ac84b006109d9fb1a4032240e065dbd8ba81c1edc4b734364cd4508e1e13bf635f55b0cd960ab638eca7d0c4ee9bc71add507465589417cba9743b7a36eda7b762bf39e80fe450b25aedcf01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214fe849f301b09dacebd2dce15d3ca34d6ba4ca4731a0c08c5ac84b00610cfe9fca9032240de372dbf43b1d6eb45f0d7c7b883e7c6f12d135aa048d6d6591606bd612b97dee6d39c5d212f71d5e53e27b583dd7380368f40f1231f24f1ef749d7a3dfa44092268080212142d9790447341f3371ad11b4b706332313cce33c31a0c08c5ac84b00610f49eba8d032240c4d9b5c20c4c6f1eeadcd03276fe835d71d0f671da5922755156995b91c9e5b484c3e9e3f00f60fcf0832c54a73792d14b6744f7a70ec2c64689008f88d47e0c226808021214dfe3e4385652c2f176ebe59c3dbe4198fd30da901a0c08c5ac84b00610f1f88fa4032240905089e3124740c3af81f36139a014193d6409a7302f1968113156df7f8a84dde0b2da23a6d407c4c0b73db858a0d6a501128545fe81b76239ffcdf61af55709220f08011a0b088092b8c398feffffff012268080212148fca7539afd32000bf2c928fc69737483c49b75b1a0c08c5ac84b006108dddf6a403224072b6a0e54c29d81467082fdd2509e2956f769fb6abe7c8bf84264504f36d3b7318cf74461e70725aa1cef8b219a9c97d535728a8add54fd835e1d6a083a5fe07226808021214eab91d7b40213e14e850a90d7c28e662466dd7c61a0c08c5ac84b00610c9d3db850322402e6bff1624a5953964863100c0d131ed93497c893d3bc967bef501846941e89259b549de34ea6d0cf83b1e72f483397ea5bb88e4f06b1f096f76f6d1c18ac8082268080212142bded3e9a310eeedfb7d4db1778a9413e29d97b11a0c08c5ac84b00610adb8d1a60322407e25144dfcc7af4f7fbbecba576e504a739f7148904c38e697fe5147e5a6d52d701b04b32e133662e2eb89a777a4e84eadd465edf732bec01a3b3f42a4ac040c2268080212141856685db8ac33cb29b9b1d35c034f16511d48501a0c08c5ac84b00610c0c6d2aa032240d7aba48b01d06f8a6a9d99a414e9c09703fbec6a1d1fb933ce4feb17034b1a6786e27b379399403ae69a30f0673a2e7c4fa8f6753a15726529d81dedd0f35704226808021214fac8f77451006668f58b8937a73ae86aee68e2531a0c08c5ac84b00610b784c99a032240a70c848545d669d2e8ea4e9c9bc57ac15fd5b008d8cad2241c5f32e14f44279232874ec8689e121e57b48a79e8d3ce952f4ac3612f486f4939843d7d1557b404226808021214f8bf2150619f6d553ec0ee4427e09ae4cf085aef1a0c08c5ac84b00610cca5aeaa0322408b2fd4a1d57abede09f226812790555a95d3ed43c1ded2c82bb6b424563ff7b554538fa4338e2d9ca7e9432fd1425d70f6f16ed5f802b011a926c1cd384c3c08226808021214ebaaecf31ec18dc4234e01c82b749ae2cd7a95771a0c08c5ac84b0061083abb0b20322408e624290f7816ef1552e51cbe6f94cab4c113276b8ad50bd2280408f9e3e35b4e400677f8db92024ce9fe0d777bb605be7a777fd3fbd76223daf5b83b524da09226808021214c3c730090bf75fc5bfdfbb4bd26589cf1c7b74871a0c08c5ac84b00610c9a6b7850322402fffe20e969254879e78defaefe87a43efa3578bc3ec3727f31667995bc5ee239fdb7a3334a29d92bc3f247c06059fcd8c05b522c71772905f9b7bcb552c7103220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214706fab402d748242cd0a22b49012a6c039feec651a0c08c5ac84b00610f6b49aa90322405a598006423467706d4806c454bdc8e101bc58ad24286bec38964c29447767f93e0b3fe8beca13a9ee57935c05cd01b536282a8e23c1fb7e96723795dd4a5007226808021214b4fd96d19a44fe4b6b05370f200d89251fb68b401a0c08c5ac84b00610f8fc81a50322402c23e85d098e4c8efb6c3dd40a0b52dcf5e47e1a226a5dbaa0482032253732b0eb59de81a8c2e3b8443697f94c71cc6e2e577367ca4b711b6bd08c332f6af100220f08011a0b088092b8c398feffffff012268080212149c29fe719923138d4a27bde5704563e45afc705d1a0c08c5ac84b00610ca9fecaa03224039125eabe6237dbcf691370a9ececacc1b38e5204ca9654ada8325631bbae9741f6c79fd4694cb0bdc461f26b97ca82b7970a5a21f83bc1497787f719cd12c0c220f08011a0b088092b8c398feffffff012268080212144451050fc63430d28fedd2a37f3ba16353c7e60a1a0c08c5ac84b00610809893a70322409fcb186b8cf687398b6a3776f57dd70f7146a4b0be0ed1523ff577be61ea10460fb1eed891a7ad5f02802b9ce018d6cda0f432199e661f75ea27b161bc547f0d226808021214a6e68f4720f047480f3bee8502304baf0faaa7a71a0c08c5ac84b00610ece1e5820322408870aeba3646534181cd016e7631af3d0c486e8822f67ef10856609557fb6532afbd775284f59a50af6b2869b7ca5cb5da0b26f36e41b7f4a3361371750a70052268080212144249abbc6cccb87ef36b481b3016ec33912901891a0c08c5ac84b00610a5faafb3032240a834a3efb9619ac1db9685bbc521baeb9813d1dad7682fcf006cd58c2ef45c8eacc9b9385751913a3e98951db1b1398dbc91f66cbf17a80814b15a0e2824e409226808021214c3266367ddf27040547dc92d5ebb1623caf2903d1a0c08c5ac84b00610dad3ceaa032240188e056696305f22a67d9904a067f0be7f87f1124ade527ef5d3060591379dba30fe57fc4aadf802104e6a2ca50f6a223f867c0fde5de2a7bb24ec21ccb3840422680802121483ee1db3ddc3112b91ee8d6e652cd5eef38c46e01a0c08c5ac84b00610e9db958b03224058a25bdb113d463cd40e59db67510699410caeb3bbef857db839aade920089259d4e941056c92e580295efec5ba048c8ac9a55d50d10de70276527cef1c3d50a2268080212145e56a5d935a9529b8999e1291c64b0ba3f9fd6631a0c08c5ac84b00610f7ac85ab032240da8b69eb538c660dbefb1efd4ecaf28d57867597666b1b2f6540c75b9d536c1484d28c6540f5c485b4ecc20b47f16631ebefd3375d7060fb1c74cba4f4d4e100226808021214fed8e547546670aa5256f64ea16d8bf1a340a5a31a0c08c5ac84b00610c4828da60322406d123b9e2f8162ce671174e124cb77b5f6ac23b7c540b1fe3c09f1dd38a700f2b43d2653c036fd3332e74484e917862a18880fc49c9a4590173c91bc89126a0f22680802121438fbd1eaedfbb5791314bc0661e3b9d145074d901a0c08c5ac84b0061093c98085032240af406ed28fcdbf4f6e1ad92519b72d170dc22bfc82771efd350780df40526811fddeabe3793007ef978b631bdf00ab7161833ca036d143da4e638edc39d80e0922680802121484b7580e977f1fd0448c4cbab82a7d3719367d571a0c08c5ac84b00610eb8d86b40322402f1a1d6f8af2949868ad0bd77365c4f6c24350b676882e523936a47faeac781fbe6d53222f6dd042a78423b7e7d2d3cd90ddb5fb6ffe141f8bae6ad2a70c930d226808021214c24fc0f3780141b5124c8a3bec39de645fb385e41a0c08c5ac84b00610a3e9fba7032240ef1ff6b813753376af4b67e184ee3fed97431a0e5c5696a99cc3a09e336ff714f00140f954960f5962b04e686902f9e420951ff44eaab73e079465fadb905b082268080212146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af81a0c08c5ac84b00610bcb9d4a20322403cba7354f25c17e980c55459ce5de1ac71f210e134d460642e422162e1dd8b692a86ac491ab562268b34e9a4859672d5cf7997903a5cb2ba94814982741b8203220f08011a0b088092b8c398feffffff01226808021214da250934d695a5a2457708f417f688ff8d9cc3261a0c08c5ac84b00610c0d7daac032240f9b9069ec79d2db8c9da98076d1512498c409f57d9d9df96ab7e3e1f8dab47d09cabdf75057f0f18c5953abfde4d16313cfb970d8156eb42dae960580e0f580a220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d21a0c08c5ac84b00610b0c5cea70322407154c18b984e0f75389b45f95d954e69348f63409bf051fb9cbb64649213602e294f9dfadbba3d46281473bb9a9ad01ad499a7539eee51d3bf1b165dbc24110e22680802121462683a7647539e61d001866edb1fb7152e1f79631a0c08c5ac84b00610a3ced5ad0322405d568927456830e6d1bac28dc454175f69993c2ae140fda1739ee1a12498fd8eeff23c636de597d703d1a3fc728c7139426b1634627ce9f0783458e7ba96ac0f226808021214b15aeec05b39196f3a972f5ab8b7c822e3336c3a1a0c08c5ac84b00610dae48ab00322404fd1cab90aa77443f1c7f16cfe829f6f53ffbbd1f2a0b7be4c1d1009b4a1fc433dc9cf40bc91ee6a054d92dc8805a977989d86f34f0d906bf8cf277550e7d50c226808021214f8933325d7838f9f70bf3ad2d8054ed2826cece51a0c08c5ac84b006109aeaa2a803224011a410d587d561a90d5ecd9d794c8c2b83ffcd4edadb5a0dffa5e9dc3b483193e9b760fc5d6ae85f05b1fc3302386a7ee7b06e89b719f1922e18b1c53ed9540a220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214a5af3f1e0814ef41b0613da1a8bafa20513723201a0c08c5ac84b0061085d3cfa703224022bc591f0043a4f15107ffcea4a3100aed1b27bea45541b59773ac2f4d9b1dc73db3158a5a128b7abd9741002207f58bba56027f2c769f97f6d6875a51d98a0b220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214fad3de3292c242997bf4000af8ffd4551272eb621a0c08c5ac84b00610d5f595fe022240a018672598c67c9ea1d14862e4f2c1fe84abc56724b5f855bd7582f8bce34081e11a8ce09d4d2bf08aacb28b39bb2d39dc541662aecd2e3df6ee228f286ffc00226808021214812dc4bd67175c2c4a74a13a4c6990fe41037a5b1a0c08c5ac84b00610d9a692b5032240384f5d91dd77fea058585a881b16c7ce31c19effb85304af002904b86987666f83e853263f3c46fdbdc2c8897a8ba2b6c9d8e0bdc945121385620da79c213b04220f08011a0b088092b8c398feffffff0122680802121430412ba7032186c3a2b1a6b440272e1d4780ab981a0c08c5ac84b00610e0b1e68d03224028370eb4cfb5dcd9aed66fc6db8dbe789a4025fb07aaf1f5b5f4a34463ca49ba2d18effada1b6751e8997709b7c6aff34b4c736c03264652b597558185d061002268080212148d5e2c42b5d2f9d8203f2a7e9173b5358952576a1a0c08c5ac84b00610c1d3bc9f0322400601d8877836d4e7508255146c1398b7627f3935235c9d13a00f2203e83cce64a90484dad6d6d4fb14f43232a7118e92f5cab96b7f5b3074d2ec9a7aad85050b220f08011a0b088092b8c398feffffff01226808021214330b0dee27003d8e8b24be39f82159f375127d321a0c08c5ac84b006109a81c0a603224042ee5c09a22b86a32cba7a5cff74b7e0dbc9cfbbb37faf41921c16af5592e32fd11bde5b1a86237bbfa786456e927de4940a2489e23b4bc5a4f34f82f17b330422680802121458b9f2517dbf8c55573fcfa9853fff27066d86ed1a0c08c5ac84b00610bb908ea20322403d32ba4d917430f76f20a50172bd47221c6359e3ecf4da5a098ba6dc99d1e558f3023e640b2d5cad9cce5857177745241ee9d459927cc5b2a4d79420eb639e0e220f08011a0b088092b8c398feffffff0122680802121458aff9ec275a66e7ad086d31e30fc59e02b94b921a0c08c5ac84b00610948887b20322400e70a330ba99a86d5419e4ed893ebed6aa62067c8cef32f17d4b200c1358f48d0d27106e1f3720146da4f423262a216d3f0f1b70b71c73c53b35f341c07fbd02220f08011a0b088092b8c398feffffff01226808021214ee2a8b5958586c495b1e7bf7ecfc284d83136c151a0c08c5ac84b00610f092ab8703224059e2e0d4331ec786e542c950b6da7dd0e757ba790a3beeba849bb9be2e979d06901b4fbd5dbd3be985cf85374f7367cbbb0376acd7640c867ff9f99854747f092268080212146d8f5894ab17dc6821a7d82c31a05d81b71c17391a0c08c5ac84b00610bfabfaa0032240f2c30fe5b8a0a4d64171ebf508ebbdc63a48110066a2dfb7f0d3c23d17b6738af902d6f8c337bc28c595ded70d2b2ca8049e68714974720400b8c2e2ff4f55092268080212143096bed304a51710ccde2dcdeb5c364c7559e7351a0c08c5ac84b0061086a690ab03224095d1ad85bea361349e57ec4fd4e10dbc1648e679c06d7ecc3b907fb33e342228e664ca182e9110b50175d6d6a21a2dc291437c1d24adfc5427d149d94617e30c226808021214c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f1a0c08c5ac84b00610f4dde9fe0222402233bd14a55b315bacbb57de5091a6948628851a1e630c9188967419b58745852dd0a73d8ceff4d7db35939c992b15a2993eaa435da4e6e2c9c8a3cba01e2109226808021214784cd03b935c7c3e75419b1f35b283e03faa7c0c1a0c08c5ac84b006108f81899c0322400ea212a580087311d4e13d4862d2957b448b31ec5ea34db1092076448f1701b5b23fe8e265aba9148e46205beb663d0c64d97252429338a8388e90b5a2fab70b220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212145245f51eeb87311e0544086e64df6e737afa01521a0c08c5ac84b00610f7f1faa50322401e147cd0d6d40d9fc280001c792b1b027179bda63ae43019256b1796ee8a40c06cd462887b2a1fd68935c3ee2981dc1a98cabc61ae71491d26abd3968886f004226808021214e7dc29639166155dc9ef5d562e44cefec2d169ca1a0c08c5ac84b00610dde093ab032240bac3c333026946c6cef7b263f9ee2a8834a45b7a366b09d1a126b211683a518586d71cf2752c4fa2e52cb6f0d77489db550be12e20caaf82dd789a47144b1803220f08011a0b088092b8c398feffffff0122680802121483a05569feb3c027db1f5e85c48073d6994040ee1a0c08c5ac84b00610c29ee5b30322403523860032e460064bc7a274826dbf67e4577967644266114696cd1ca01bcde0f1a029c53caee332e7ae620a202c1ed4dc7e44c5c5509598efe3ec1dc200e40f226808021214618ca0614c7ea885243f3580790708979be7bd451a0c08c5ac84b00610afa485a5032240973420c1533fb165fe2cc2b345eca839ef3cd3e98b6df638601fb0a64619f31c66dea36915962583f4f78d7742ea386b2702f15624bd4000c6da55782928b902226808021214f8426ee2307c31165cce1cc4da9762ae74f84ec11a0c08c5ac84b00610f7fed0b303224099a1ea5beea3f8f9afb8766f797fb65f71a4bad207ea275077fd4e37c54c31c4de63fc52536dbe4d69986f72da593bc081069e3f42f976a5014435fd96092804226808021214f063a67840c7d6411bd0c4b9603a1c6c7440d3f91a0c08c5ac84b0061082f3b58303224049f91e2c1a96f7675715b2347b9e2fe04c0c7f6b1f5fa66c3e77667caf8d327765f57f6c74bb08395a9e32b05faba764f4289eb44c107efafbc8f8e2c2b83504226808021214c7ed8e58ed8bbc7c0e9911bfaa38c725c00383641a0c08c5ac84b00610bac6e299032240b3c8e95e5b76ab342e1059bae1eec41f572492383c16592a9b09c74d80dfd800555489cb7e0f4697673dadc52237e49ecb69731e2a0368a6a6b239d6156cd406226808021214bdc269f2f62e3b02d6eb049bd2a11a425cfe3f291a0c08c5ac84b00610f182d9a70322402cc04249565c79527bf8a2784351eed93d111aaa111aea25a689ec924adbd55021afd1799fcd2fc9e560536204da4a25f095e651f527695bcc19c1d5106af40d220f08011a0b088092b8c398feffffff012268080212140808a48a93fba44a17029c17b16ad5cb1ccccfce1a0c08c5ac84b00610bd81ad8b032240912941700df39f699fc34b21faed36ce15627db84dde35cf78ca722cbbce6d874ea36d3575cbe8f747cae1dbb9b4d4136f876c5f719bb98cbbae40d0f82acd0b22680802121465a73fb6a5b297299393c8cc9a342242b13697441a0c08c5ac84b00610acdd889e032240752a924c7393e9ffab930c86f04f1655fe1e741ee7f82012bba78fe3e3d4f95457a28eff334a17e51f7b4d53499c852ef6950224f79b133a2c18303808778a03220f08011a0b088092b8c398feffffff0122680802121472f92fd75727431194c7129be2411a9093e6d57c1a0c08c5ac84b00610d6f0aec60322403ae6ed72d3224c9d276162630709ef68412e77a29c4c234ccdde0afcf97d74c7c22ba7d5f2743bea49a766008b3f8211289b76178f636e0bb4e8320d28b0130422680802121411c30fd0a3bda953d88a2157a69b2cab52b41f051a0c08c5ac84b00610cafeed860322402f5d7772ce53445c16156edddf5f2e2590fd089d3d4d8be0761a686b4c658b46ad4f856180ff59bb0098ab01a47e366ec6f42b5a6db83ebf824aa0cd712ad80b22680802121409d7dd253fe3ea53eb16a5c4492166688b3c65801a0c08c5ac84b0061080d8e5ac03224069ddedc5a33917d6a39d334acc752e318bc84c968b473ff769d895f1f6e1d0649d91a2ff141bcca83a7f62a157595d9d569c25029ada94cfaf9efe053e8bc304226808021214f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a1a0c08c5ac84b00610e5a0eea3032240324a9848b8a67cb786a7783b490d6698f4a0e793defcef6e572d5e4b03d6e9d1ce04fe78555eedc6376e7007382bfc3a41c29124a3760170d300688f81591b05220f08011a0b088092b8c398feffffff0112db320a3f0a14b1852d17fa66b5382a8f770725cc5b228b35775012220a20ec06936d55936aca5c041b091c7a311b1f3065bd2b65b60be25ed09104feb8f318f4d3aa060a3f0a142abc4854b1a1c5aa8403c4ea853a81aca901cc7612220a201addaecd87a7fdaf28bb67bc3533bc705bdfb52007365b7d67685f1d65030dde18a8eea8030a3f0a1425b40fd5ae2ac26b4382b746f6cddb8c73ce602512220a203183f39d70ce25f0a8ea02a762e43dd6fa8ec4037e1bd210acfb49570cd0666f18be80f7020a3f0a148dab929d392163909bfc1b2c8be1d4ff5b058f8612220a20e75d7c6c4a161f130000560c02ad4bfb70709ec2b625d3157a19c50a2987cf8e1896b3ed020a3f0a14408b9882eaa1e636bd48998340babe0153050cc312220a20b0d65ae97827e39346b7e0c6390d116301139a6e2d9a189c4edf26782621a38e18f18ad2020a3f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f3010a3f0a140549633adf0dd5e91ec75458cbeec35ae4331ad112220a20cdb58d6d7fa134d2dac24605a3d616d48fe41f8ed872f8e4c98e9037666db16918daf7ea010a3f0a14fd46533e10d45d8fbfda2588c70f927d2e44bc7912220a20e7de761f86056b4946d8d50100da0515061465b0b26cfafd5ddf97f71b41a86e18e7b9e8010a3f0a14fe1d612fc9c346e51fa20ed491ebd81162c0e11012220a20b017d03e09d1d7283fc27775ad243788236939851a5a326ea084fa62a80bbae618c2fac9010a3f0a1483337fa8c2a5bf1283a58384c0ccee0811919e0a12220a20147ee0dd6069170d26c95238e5a979a0ad370b68178926e806b17775cb5d38e018beb8c7010a3f0a1439d8e563c1af1285095ff5bee373e235d63d0cae12220a20e383ebbe5ff6bd0539f2e8618dbd95dd5da15a4147575da0215cf14f3f386b8c18f1a6c1010a3f0a1459835dcbb6ce79f1d12b86702e8690e5f5c514e512220a20e2e8b19d9012cbd9b00e9bdbd3195ea5107d730d5beb9eb771efaf4e0b3a1dee18bb93bd010a3f0a147bd85b0a30cfae183af900b65bc0ec0a28063c9912220a20c68b2e6e48b7049594cf7e6f24a4f2323d7356233a614e7cf7fd5101cc9be97f18edacb6010a3f0a140218a7a051c04fec85b4f92bfb00a8c4da1a9bd512220a203d94dcb94e8d15630e1934ae4fa0bb644f962bfc81b9d9be368882c1017f983e1885afad010a3f0a143596e89e65d41be8200b436c2986e97e9dd1ecce12220a2003512e3640974bc65e350e91c68b130e769ee58eef0f68eff9fd0763a08d441a18c6bb9d010a3f0a14923b8fcd3097ba253408cf32f8a77da355bbc86312220a204137811e4eaf4874c7d64915b28c174eeb7a1be95d314c7b7822f6f93ec5470518f18198010a3f0a14fe849f301b09dacebd2dce15d3ca34d6ba4ca47312220a20a6322cef180e269ebc624714d13c4955dbba0f408cd8e10d997dc7024494f80418f49c95010a3f0a142d9790447341f3371ad11b4b706332313cce33c312220a20d927b9a6b67b352b9c5747c6595766c1ad25c7708d04264aa17e3c580fd98b2718929894010a3f0a14dfe3e4385652c2f176ebe59c3dbe4198fd30da9012220a2072e20f388f16bae585240348109645b102e2f29ab77cbbce7817b5d123bd0df018f2fb92010a3f0a14536c4cc1cf97c4df693b3e7e6604bf0b14f4257e12220a2003c83e556021016aaaffc2f6aa48fdf788d033c3da0924cd21ccdf6dd5cf32d518f7868c010a3f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018e6ad8b010a3f0a14eab91d7b40213e14e850a90d7c28e662466dd7c612220a20d683dd49bf1096490b5ef089100917f040751afd2f698f161e1f80bc2db9511a18e58384010a3e0a142bded3e9a310eeedfb7d4db1778a9413e29d97b112220a20d854ff20e923fd27aeaea258d784afcb9d87c9fe3927d9ad5ae0b1669d1c2d751892bd780a3e0a141856685db8ac33cb29b9b1d35c034f16511d485012220a20e8527069a1e7bfbe25eaafafad88a1ed0f32db8e4e0a1669972c796f6cad6a4e1889a16b0a3e0a14fac8f77451006668f58b8937a73ae86aee68e25312220a20e408946e01267bc86fb50deacc86dafdaedb3a805a9c45eba47810700fadd18618cbd6610a3e0a14f8bf2150619f6d553ec0ee4427e09ae4cf085aef12220a20c7c5ffac225b15476f87b43d652e06304a965e7491d18fb0d9a0a6a208dbf8e818fffa5f0a3e0a14ebaaecf31ec18dc4234e01c82b749ae2cd7a957712220a20755b3e61036e77ae0f9d8b69df1a9cfc0e47c1fcc6bfdb15a675d47def8061fb18bdef5e0a3e0a14c3c730090bf75fc5bfdfbb4bd26589cf1c7b748712220a20f9bbb0bd1d1e5502d4c4c35da60e4f4a738e18ee28455c77888aac7fc3114a7a18a9ec530a3e0a14b4058eebe8da7015a6c0c29f3c53451563478fb712220a20f45743b9d87fdab24ccd8d07f917679c2d29d0f1e1d71113a5d4d93961fc4ea118f0b5500a3e0a14795ad41bb274e23b8d82b32b4f878c30ff76f3ee12220a202687ca37348621f6f0d7bb0d8181b6d7036887940813b7061ca7999a48bd1f8c1895a54c0a3e0a14fabfce1baa453eaf8255bedc5ee8eff464aa37b512220a208ba26509d1dbd124081bef7bde188ede90cb2ade0f6aefe1fe71193800ba962a18b381410a3e0a14706fab402d748242cd0a22b49012a6c039feec6512220a20243bafe50ae8db47bb23976a2aa10d8e60fbf66a6b3400239bfbf6709aad11d518e3d83d0a3e0a14b4fd96d19a44fe4b6b05370f200d89251fb68b4012220a20e738929a9dd600112b677dfee30227dc396c0683beb26cf7ad1c4d439ee972e31899da390a3e0a14aa6786a7b42270295639f5980e8c3648286caea212220a2096a759920df5363c9aee820cd5220ae927c60b510ec497653d3dbf6ec63c8a9f18a5bd390a3e0a149c29fe719923138d4a27bde5704563e45afc705d12220a207017fbc65e3fb62fbebc1b894125a9cd147a8f5cf87bd37590d70a64c7f6401218818e380a3e0a14a21ccd762306bb2651b2a24cfa15ae537c8c633f12220a207ac3ae3da8ea25e443879b5c1b321c3fb05a5c8f793925eec64aa650629e362418ee8b380a3e0a144451050fc63430d28fedd2a37f3ba16353c7e60a12220a204b534106cdefad4f0da9ee1eec2d7c2985ce1c0cfbd47d9461382afd729dc2bb18cd88360a3e0a14a6e68f4720f047480f3bee8502304baf0faaa7a712220a20b217c1303ec5ae61af90f6a8a72caa57b6e59c416f12e8d256dd904b429998ca18e3ce350a3e0a144249abbc6cccb87ef36b481b3016ec339129018912220a203b9674d593af41c481890f6e1fc3aa279cbe5d58eac58671f35734c59f3743c118d1e1330a3e0a14c3266367ddf27040547dc92d5ebb1623caf2903d12220a203aa92f59e180f35d9419add9a3ce6ad0a608541b811424aa85df565d2032c3af189aa3320a3e0a1483ee1db3ddc3112b91ee8d6e652cd5eef38c46e012220a20d6af075513a9e2d25972bc4893c4807336f3a00d98ebd3749980b1afedef30dc18e3b62e0a3e0a145e56a5d935a9529b8999e1291c64b0ba3f9fd66312220a2008983fbb9c4eeb900ad180158ca77242a29063669ae1a4a32641572ddfda83c91888a32d0a3e0a14fed8e547546670aa5256f64ea16d8bf1a340a5a312220a20f89aeac801b13028472b4733dde75e161b1bfc186b587c469097c0a66b431aba18fb872d0a3e0a1438fbd1eaedfbb5791314bc0661e3b9d145074d9012220a208db395073ffa6278e1c05481ad6a52d50468a90d94efa80b42348f3c62eb0e05189ba52c0a3e0a1484b7580e977f1fd0448c4cbab82a7d3719367d5712220a20eea097ce993a3c7a4e47141404bf14c149be585520e763c22f5cb34909cfbad418dcd4290a3e0a14c24fc0f3780141b5124c8a3bec39de645fb385e412220a20047bbb54c5e59a5b740162e0fa02d35efdde81994b5317100fd79214de3529001891e2270a3e0a146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af812220a20ed9d6aa7a16df68792b42371f386b5308c347f3e8e2f9301a857dfc3f1e72e4718b4d2270a3e0a14373328b487c327e51cb513e60a8a1c5fdaff5b3012220a20647bc426173aa99f2a5bcac2145078d050c7eb72d3b361a4aedf21ac0e5ebb9618aff9250a3e0a14da250934d695a5a2457708f417f688ff8d9cc32612220a20a5bc8d67cf595fe8d576257a97d3832df9fc480216a7df493366f92f8736a0ed18f696240a3e0a144198498bc2c20053e5aaaa4ce9cb7e3b93b8e85e12220a20f69e8798c93227eefb3ccf7efc20c3bd96cae139281f2e699f5b4de17878756c18bd99230a3e0a14e28bf9e8ff9ef17268d26a50f7cd998bee4db3f012220a20ea21311aa1f222afdaf21a2c5cfac248ac8fbe816354e466ac4fafb4f60a513218c8b1220a3e0a14fb2ef7e3b80bf63f9ddc9e2431addbcdc6e7644a12220a203f282143c907b1ef86202f71ffd761693a40748b26961ef5c94930b7cde0812118f1af210a3e0a1479efa8b65cb1f1aa69373ad3d01f442dcfcf938112220a20c85bd96888a6971f1bb95ca0f354f681584c883d7746a7fb312239bc1322d48318f1ac200a3e0a1480524f180664c5a1ac66bdd30bcedb36bbac096a12220a20b00c9552aa825e3e8d0bb9e230fb8e558eb54a0c6fc2b6dde7ea466199e954e018bca8200a3e0a14b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d212220a2030534ef00c64b39ab07df356961b4b6420733389a599242ee26e94de6c76dd7a18daa2200a3e0a1462683a7647539e61d001866edb1fb7152e1f796312220a205040fe5690b8fb12333f1d1b85180a52a9deffa01cf759b6d0efa4e420cdf33018bb9a200a3e0a14b15aeec05b39196f3a972f5ab8b7c822e3336c3a12220a203b9adeab28a2e7165d38299fe0eeb6fb0b6aba7cc201fd5d4955b1fcb56cf9e4189981200a3e0a14f8933325d7838f9f70bf3ad2d8054ed2826cece512220a200a3812c57d816fb4a3ec3686c3b306938d6c72bfce34a23154acd414fa37c5f7189deb1f0a3e0a140d97b64748720fe5d1ddf647ef06eba901caee8612220a20d395877c653467006556d1476ac4b68c9902364ab7fb6507a1a7758f56863cda18f8bf1f0a3e0a145b205289e6d60f7bf3fb4a15db5343da30a2509e12220a200b37c2a9a04bc6a04a68cee15624ced60f603b0939fa9c3ae3c7ddebe96140b5188dab1f0a3e0a14a5af3f1e0814ef41b0613da1a8bafa205137232012220a208ae4723213b340fb244a0d54f6d316aec71776d0fe2cc36d32436f752a1fd44018eca31f0a3e0a149dc49bd022e7e81dbcead966fff4f9af77052f2a12220a207a12ce70a7e988b9ec8ffe03d3ed4758875105bbf15ae78d5d2f46ae67464afd18efcf1e0a3e0a14fd1df5c5f5ea867fb21aa05c00926fabd2639e1612220a20dbb0e5b2016dd75f871ff64f4c8d472fc0da4289690f515f5f173aba8892ab3518d1ec1d0a3e0a14f7a35051ba1ce4f9d5b43157c522275dd90a454212220a2035e4cd35fd12e58f067b8852369bded41708336daca6c176bcbc7cdd8161057818ebab1d0a3e0a14fad3de3292c242997bf4000af8ffd4551272eb6212220a207024974db2eac3a6d3b1106acb52b39e21506c7e26c9f5a61fa86a45e86ce832188eba1c0a3e0a14812dc4bd67175c2c4a74a13a4c6990fe41037a5b12220a20458370b1f37e8de7fa4bae977b90a569285ffe1d37c0460e5b138ad2ecdd738518d6a21b0a3e0a143ded012b42f48947bbb2bd8eef7c0d69d217dce012220a20c2a41771f5e9612ed358c08e997f94be52a4486b6567816e9f50e9f686899b7e18eec5190a3e0a1430412ba7032186c3a2b1a6b440272e1d4780ab9812220a2032307c624e438a213e57ac577044cf328cbb305cc604693611092f77dfe13adf18ce99190a3e0a148d5e2c42b5d2f9d8203f2a7e9173b5358952576a12220a206afd4890886c667d79ee871ae1c1b2b83fdcc26c6fb1cda40695e2091157b152189087190a3e0a143c70fac7857389b869696e8f3e1f48be0be0242912220a20dfdd72d0732e60bf39286432b6b41fb10c0d8905d70897bf2291989e1eeac26518cbda170a3e0a14330b0dee27003d8e8b24be39f82159f375127d3212220a203db48acea4cb759b208b418b3e826ab9c75a77ca3fc7eeb647b84b1ea422308a18bbdc160a3e0a1458b9f2517dbf8c55573fcfa9853fff27066d86ed12220a20d0fa86b1e1eca13d135c07d3dc25814367bff1fafe25e8d8872897d6a0bde59018d79d140a3e0a146f23af09898a93352392cd0977bd5be5c74ef70912220a205ae5773928fed10cbf6f4d5f80d6533501b66736864a3b50e96c58021389b20818a3bc120a3e0a1458aff9ec275a66e7ad086d31e30fc59e02b94b9212220a20640499f5afeeb7ab49c601221c44fb762f3c02d05d5032bde7bab27823a5827718a7a4120a3e0a14e357f35a66a72eb8162f5a66ea221b9025ff56bc12220a20ac38b9ef0c5f7314dec03f8ad4d2fedd35f9d49bc5bb9de48832b55c00d6571518c3f3110a3e0a14ee2a8b5958586c495b1e7bf7ecfc284d83136c1512220a2099a8eeb2d17d0dff6b915cf6c65ffd563606dfd60640a35b8e082d40f67dca3318a683110a3e0a146d8f5894ab17dc6821a7d82c31a05d81b71c173912220a2065348bed02c217dacb610d4c8b7ae45d00389078b18df73e644174a0752c3c8418ceac100a3e0a143096bed304a51710ccde2dcdeb5c364c7559e73512220a20d77807b7263fd82cd116f733f78d7415eb08ac78be46a5e31d20b5285565bfee18ecf70e0a3e0a14c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f12220a20d61e7cdcfae95db114e7dce184ca3b11d59fc64b9163bc02bc8728631b4b5f5718c9e40e0a3e0a14784cd03b935c7c3e75419b1f35b283e03faa7c0c12220a205364bf153a2c5eb3e916bf62c327bbe782ee6b275863c9a11f8af39f7bef4eed18a2e00c0a3e0a142640a32bf68b7f9723e001c2e4b4e32e00b9467912220a209e5d22a072e232bf5c277dffa170ebc80db49d5496c0b638b6af2c01ea993c0c18b1dd0c0a3e0a14caab75b9c6d41e924cd1b526f5e2d123db756bc412220a2091da6ce3e1debed393e42c02a9641e42e965fe5b4095699c3db096049b29b4ea18d9c10c0a3e0a145245f51eeb87311e0544086e64df6e737afa015212220a203df173fba4427fd0acd8bc0f6c83f8f13a7944e5ad20c5f365c7390e5382313918acc00b0a3e0a14e7dc29639166155dc9ef5d562e44cefec2d169ca12220a203f0eb2d5e935320f269d5ab878104d36be1a2bc38d5ef1b2fe66760814a93c9818affd0a0a3e0a1457f61959ff8a08562bb0aba4921c5ef1b307dc6312220a20f5d18e7d52e05100d55e2f5fd0aa9fa8ba710f0801d7f605985b9732063b1c58188fee0a0a3e0a1483a05569feb3c027db1f5e85c48073d6994040ee12220a2087e931b901b4fb3d4733e821ad082d39d13930a1705baf4f5876a941e12f22dd18e3b30a0a3e0a14618ca0614c7ea885243f3580790708979be7bd4512220a200ec759549c85f6a5a4dbc79f7b112de4592dff74e9562d71c45a8fd3161dc9f318fbfc090a3e0a14f8426ee2307c31165cce1cc4da9762ae74f84ec112220a202cb896fc05f2f31a15a470963122fad880de8d26bff2a259291fb18af4d5914418dcf7090a3e0a14f063a67840c7d6411bd0c4b9603a1c6c7440d3f912220a20f9b393d098812877c926b72ffb2acea890ef4e8d321595c8b3f6d2b6ad92dff118a5ac090a3e0a14c7ed8e58ed8bbc7c0e9911bfaa38c725c003836412220a2060d20c0dd3ac3a21ffdbb7a4f0e6e704ff5fc0a6d11b10d1ee194b1a1fedbf7518e788090a3e0a14bdc269f2f62e3b02d6eb049bd2a11a425cfe3f2912220a203cb375c0722fd44d8da62db992e0bb34036e931ab217862892eca2cbcfbb2e9218eff9080a3e0a14c1976fefd48939e2327cbf83f367841028b95e0e12220a208aaa1c11dc4b43e95603cb10d9d24b6215e0232c5d87bb80539d440d6792e22618bb88080a3e0a140808a48a93fba44a17029c17b16ad5cb1ccccfce12220a20cdee5cd83bf3e85634a60f171c51cabba3fe76257605782eeb11d3a9d735c31a1899fd070a3e0a1465a73fb6a5b297299393c8cc9a342242b136974412220a207887710424a3375409f13d31bfed217c1524fb0db7c4f64db96671a5bdcebbc418e48d070a3e0a140c714e67a83273e3c3e35b17ca8ee140551a536012220a203452cde83ab0a21e43c9b749851e03b2ed0421aea710281711ca57d448af7bc218fc90060a3e0a1472f92fd75727431194c7129be2411a9093e6d57c12220a208ed5b1abd4aa4593dcb9c790927ac89f866e54c73d593554e13ef1efd86ab66918c0eb050a3e0a1411c30fd0a3bda953d88a2157a69b2cab52b41f0512220a2079e66631b3171534f3bce2430e6f9a87d83b94d0fcc4d21068dfcd3e2002df3e18d788040a3e0a1409d7dd253fe3ea53eb16a5c4492166688b3c658012220a20a24599a1f46bad5422ffb0d05e83a4394b602ffa007fe3393c985569ee7aa07f18acff030a3e0a14f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a12220a205556636b3bbc09f22e546840fa79d6628e36b4e4ff8d6978d9b274a5a92d932b18abfe020a3d0a1413a56fa6f11adaa2b09d97e57b36277319f22df012220a20315f78bea93b18884bab79e68711a9c05c67953b78788979e80c7fb1fc4caad618ab73123f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018e6ad8b0118d988be3e1a07080210c080b70722db320a3f0a14b1852d17fa66b5382a8f770725cc5b228b35775012220a20ec06936d55936aca5c041b091c7a311b1f3065bd2b65b60be25ed09104feb8f318edd3aa060a3f0a142abc4854b1a1c5aa8403c4ea853a81aca901cc7612220a201addaecd87a7fdaf28bb67bc3533bc705bdfb52007365b7d67685f1d65030dde1894eea8030a3f0a1425b40fd5ae2ac26b4382b746f6cddb8c73ce602512220a203183f39d70ce25f0a8ea02a762e43dd6fa8ec4037e1bd210acfb49570cd0666f189d80f7020a3f0a148dab929d392163909bfc1b2c8be1d4ff5b058f8612220a20e75d7c6c4a161f130000560c02ad4bfb70709ec2b625d3157a19c50a2987cf8e1891b3ed020a3f0a14408b9882eaa1e636bd48998340babe0153050cc312220a20b0d65ae97827e39346b7e0c6390d116301139a6e2d9a189c4edf26782621a38e18dc8ad2020a3f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f3010a3f0a140549633adf0dd5e91ec75458cbeec35ae4331ad112220a20cdb58d6d7fa134d2dac24605a3d616d48fe41f8ed872f8e4c98e9037666db16918daf7ea010a3f0a14fd46533e10d45d8fbfda2588c70f927d2e44bc7912220a20e7de761f86056b4946d8d50100da0515061465b0b26cfafd5ddf97f71b41a86e18dab9e8010a3f0a14fe1d612fc9c346e51fa20ed491ebd81162c0e11012220a20b017d03e09d1d7283fc27775ad243788236939851a5a326ea084fa62a80bbae618c2fac9010a3f0a1483337fa8c2a5bf1283a58384c0ccee0811919e0a12220a20147ee0dd6069170d26c95238e5a979a0ad370b68178926e806b17775cb5d38e018beb8c7010a3f0a1439d8e563c1af1285095ff5bee373e235d63d0cae12220a20e383ebbe5ff6bd0539f2e8618dbd95dd5da15a4147575da0215cf14f3f386b8c18f1a6c1010a3f0a1459835dcbb6ce79f1d12b86702e8690e5f5c514e512220a20e2e8b19d9012cbd9b00e9bdbd3195ea5107d730d5beb9eb771efaf4e0b3a1dee18b593bd010a3f0a147bd85b0a30cfae183af900b65bc0ec0a28063c9912220a20c68b2e6e48b7049594cf7e6f24a4f2323d7356233a614e7cf7fd5101cc9be97f18edacb6010a3f0a140218a7a051c04fec85b4f92bfb00a8c4da1a9bd512220a203d94dcb94e8d15630e1934ae4fa0bb644f962bfc81b9d9be368882c1017f983e1885afad010a3f0a143596e89e65d41be8200b436c2986e97e9dd1ecce12220a2003512e3640974bc65e350e91c68b130e769ee58eef0f68eff9fd0763a08d441a18c6bb9d010a3f0a14923b8fcd3097ba253408cf32f8a77da355bbc86312220a204137811e4eaf4874c7d64915b28c174eeb7a1be95d314c7b7822f6f93ec5470518f18198010a3f0a14fe849f301b09dacebd2dce15d3ca34d6ba4ca47312220a20a6322cef180e269ebc624714d13c4955dbba0f408cd8e10d997dc7024494f80418f49c95010a3f0a142d9790447341f3371ad11b4b706332313cce33c312220a20d927b9a6b67b352b9c5747c6595766c1ad25c7708d04264aa17e3c580fd98b2718f29794010a3f0a14dfe3e4385652c2f176ebe59c3dbe4198fd30da9012220a2072e20f388f16bae585240348109645b102e2f29ab77cbbce7817b5d123bd0df018f2fb92010a3f0a14536c4cc1cf97c4df693b3e7e6604bf0b14f4257e12220a2003c83e556021016aaaffc2f6aa48fdf788d033c3da0924cd21ccdf6dd5cf32d518f7868c010a3f0a148fca7539afd32000bf2c928fc69737483c49b75b12220a200a5cccc562df390aa57ed6e5515f0d769495c9ed79017dc432ae955afb136a9018ddad8b010a3f0a14eab91d7b40213e14e850a90d7c28e662466dd7c612220a20d683dd49bf1096490b5ef089100917f040751afd2f698f161e1f80bc2db9511a18e58384010a3e0a142bded3e9a310eeedfb7d4db1778a9413e29d97b112220a20d854ff20e923fd27aeaea258d784afcb9d87c9fe3927d9ad5ae0b1669d1c2d751892bd780a3e0a141856685db8ac33cb29b9b1d35c034f16511d485012220a20e8527069a1e7bfbe25eaafafad88a1ed0f32db8e4e0a1669972c796f6cad6a4e1889a16b0a3e0a14fac8f77451006668f58b8937a73ae86aee68e25312220a20e408946e01267bc86fb50deacc86dafdaedb3a805a9c45eba47810700fadd18618cbd6610a3e0a14f8bf2150619f6d553ec0ee4427e09ae4cf085aef12220a20c7c5ffac225b15476f87b43d652e06304a965e7491d18fb0d9a0a6a208dbf8e818fefa5f0a3e0a14ebaaecf31ec18dc4234e01c82b749ae2cd7a957712220a20755b3e61036e77ae0f9d8b69df1a9cfc0e47c1fcc6bfdb15a675d47def8061fb18bdef5e0a3e0a14c3c730090bf75fc5bfdfbb4bd26589cf1c7b748712220a20f9bbb0bd1d1e5502d4c4c35da60e4f4a738e18ee28455c77888aac7fc3114a7a18a7ec530a3e0a14b4058eebe8da7015a6c0c29f3c53451563478fb712220a20f45743b9d87fdab24ccd8d07f917679c2d29d0f1e1d71113a5d4d93961fc4ea118f0b5500a3e0a14795ad41bb274e23b8d82b32b4f878c30ff76f3ee12220a202687ca37348621f6f0d7bb0d8181b6d7036887940813b7061ca7999a48bd1f8c1895a54c0a3e0a14fabfce1baa453eaf8255bedc5ee8eff464aa37b512220a208ba26509d1dbd124081bef7bde188ede90cb2ade0f6aefe1fe71193800ba962a18b381410a3e0a14706fab402d748242cd0a22b49012a6c039feec6512220a20243bafe50ae8db47bb23976a2aa10d8e60fbf66a6b3400239bfbf6709aad11d518e3d83d0a3e0a14b4fd96d19a44fe4b6b05370f200d89251fb68b4012220a20e738929a9dd600112b677dfee30227dc396c0683beb26cf7ad1c4d439ee972e31898da390a3e0a14aa6786a7b42270295639f5980e8c3648286caea212220a2096a759920df5363c9aee820cd5220ae927c60b510ec497653d3dbf6ec63c8a9f18a5bd390a3e0a149c29fe719923138d4a27bde5704563e45afc705d12220a207017fbc65e3fb62fbebc1b894125a9cd147a8f5cf87bd37590d70a64c7f6401218808e380a3e0a14a21ccd762306bb2651b2a24cfa15ae537c8c633f12220a207ac3ae3da8ea25e443879b5c1b321c3fb05a5c8f793925eec64aa650629e362418ee8b380a3e0a144451050fc63430d28fedd2a37f3ba16353c7e60a12220a204b534106cdefad4f0da9ee1eec2d7c2985ce1c0cfbd47d9461382afd729dc2bb18cd88360a3e0a14a6e68f4720f047480f3bee8502304baf0faaa7a712220a20b217c1303ec5ae61af90f6a8a72caa57b6e59c416f12e8d256dd904b429998ca18e3ce350a3e0a144249abbc6cccb87ef36b481b3016ec339129018912220a203b9674d593af41c481890f6e1fc3aa279cbe5d58eac58671f35734c59f3743c118d1e1330a3e0a14c3266367ddf27040547dc92d5ebb1623caf2903d12220a203aa92f59e180f35d9419add9a3ce6ad0a608541b811424aa85df565d2032c3af189aa3320a3e0a1483ee1db3ddc3112b91ee8d6e652cd5eef38c46e012220a20d6af075513a9e2d25972bc4893c4807336f3a00d98ebd3749980b1afedef30dc18e3b62e0a3e0a145e56a5d935a9529b8999e1291c64b0ba3f9fd66312220a2008983fbb9c4eeb900ad180158ca77242a29063669ae1a4a32641572ddfda83c91888a32d0a3e0a14fed8e547546670aa5256f64ea16d8bf1a340a5a312220a20f89aeac801b13028472b4733dde75e161b1bfc186b587c469097c0a66b431aba18fb872d0a3e0a1438fbd1eaedfbb5791314bc0661e3b9d145074d9012220a208db395073ffa6278e1c05481ad6a52d50468a90d94efa80b42348f3c62eb0e05189ba52c0a3e0a1484b7580e977f1fd0448c4cbab82a7d3719367d5712220a20eea097ce993a3c7a4e47141404bf14c149be585520e763c22f5cb34909cfbad418dcd4290a3e0a14c24fc0f3780141b5124c8a3bec39de645fb385e412220a20047bbb54c5e59a5b740162e0fa02d35efdde81994b5317100fd79214de3529001891e2270a3e0a146d5ffc2b78d31f0e50a2bdfc5b25858efaaa6af812220a20ed9d6aa7a16df68792b42371f386b5308c347f3e8e2f9301a857dfc3f1e72e4718b4d2270a3e0a14373328b487c327e51cb513e60a8a1c5fdaff5b3012220a20647bc426173aa99f2a5bcac2145078d050c7eb72d3b361a4aedf21ac0e5ebb9618aff9250a3e0a14da250934d695a5a2457708f417f688ff8d9cc32612220a20a5bc8d67cf595fe8d576257a97d3832df9fc480216a7df493366f92f8736a0ed18f696240a3e0a144198498bc2c20053e5aaaa4ce9cb7e3b93b8e85e12220a20f69e8798c93227eefb3ccf7efc20c3bd96cae139281f2e699f5b4de17878756c18bd99230a3e0a14e28bf9e8ff9ef17268d26a50f7cd998bee4db3f012220a20ea21311aa1f222afdaf21a2c5cfac248ac8fbe816354e466ac4fafb4f60a513218c8b1220a3e0a14fb2ef7e3b80bf63f9ddc9e2431addbcdc6e7644a12220a203f282143c907b1ef86202f71ffd761693a40748b26961ef5c94930b7cde0812118f1af210a3e0a1479efa8b65cb1f1aa69373ad3d01f442dcfcf938112220a20c85bd96888a6971f1bb95ca0f354f681584c883d7746a7fb312239bc1322d48318f1ac200a3e0a1480524f180664c5a1ac66bdd30bcedb36bbac096a12220a20b00c9552aa825e3e8d0bb9e230fb8e558eb54a0c6fc2b6dde7ea466199e954e018aba8200a3e0a14b5e7c21e61ca3d892607bfbf49d2fbc16f5ad1d212220a2030534ef00c64b39ab07df356961b4b6420733389a599242ee26e94de6c76dd7a18daa2200a3e0a1462683a7647539e61d001866edb1fb7152e1f796312220a205040fe5690b8fb12333f1d1b85180a52a9deffa01cf759b6d0efa4e420cdf33018bb9a200a3e0a14b15aeec05b39196f3a972f5ab8b7c822e3336c3a12220a203b9adeab28a2e7165d38299fe0eeb6fb0b6aba7cc201fd5d4955b1fcb56cf9e4189981200a3e0a14f8933325d7838f9f70bf3ad2d8054ed2826cece512220a200a3812c57d816fb4a3ec3686c3b306938d6c72bfce34a23154acd414fa37c5f7189deb1f0a3e0a140d97b64748720fe5d1ddf647ef06eba901caee8612220a20d395877c653467006556d1476ac4b68c9902364ab7fb6507a1a7758f56863cda18f8bf1f0a3e0a145b205289e6d60f7bf3fb4a15db5343da30a2509e12220a200b37c2a9a04bc6a04a68cee15624ced60f603b0939fa9c3ae3c7ddebe96140b5188dab1f0a3e0a14a5af3f1e0814ef41b0613da1a8bafa205137232012220a208ae4723213b340fb244a0d54f6d316aec71776d0fe2cc36d32436f752a1fd44018eca31f0a3e0a149dc49bd022e7e81dbcead966fff4f9af77052f2a12220a207a12ce70a7e988b9ec8ffe03d3ed4758875105bbf15ae78d5d2f46ae67464afd18efcf1e0a3e0a14fd1df5c5f5ea867fb21aa05c00926fabd2639e1612220a20dbb0e5b2016dd75f871ff64f4c8d472fc0da4289690f515f5f173aba8892ab3518d0ec1d0a3e0a14f7a35051ba1ce4f9d5b43157c522275dd90a454212220a2035e4cd35fd12e58f067b8852369bded41708336daca6c176bcbc7cdd8161057818ebab1d0a3e0a14fad3de3292c242997bf4000af8ffd4551272eb6212220a207024974db2eac3a6d3b1106acb52b39e21506c7e26c9f5a61fa86a45e86ce832188eba1c0a3e0a14812dc4bd67175c2c4a74a13a4c6990fe41037a5b12220a20458370b1f37e8de7fa4bae977b90a569285ffe1d37c0460e5b138ad2ecdd738518d6a21b0a3e0a143ded012b42f48947bbb2bd8eef7c0d69d217dce012220a20c2a41771f5e9612ed358c08e997f94be52a4486b6567816e9f50e9f686899b7e18eec5190a3e0a1430412ba7032186c3a2b1a6b440272e1d4780ab9812220a2032307c624e438a213e57ac577044cf328cbb305cc604693611092f77dfe13adf18ce99190a3e0a148d5e2c42b5d2f9d8203f2a7e9173b5358952576a12220a206afd4890886c667d79ee871ae1c1b2b83fdcc26c6fb1cda40695e2091157b152189087190a3e0a143c70fac7857389b869696e8f3e1f48be0be0242912220a20dfdd72d0732e60bf39286432b6b41fb10c0d8905d70897bf2291989e1eeac26518cbda170a3e0a14330b0dee27003d8e8b24be39f82159f375127d3212220a203db48acea4cb759b208b418b3e826ab9c75a77ca3fc7eeb647b84b1ea422308a18bbdc160a3e0a1458b9f2517dbf8c55573fcfa9853fff27066d86ed12220a20d0fa86b1e1eca13d135c07d3dc25814367bff1fafe25e8d8872897d6a0bde59018d79d140a3e0a146f23af09898a93352392cd0977bd5be5c74ef70912220a205ae5773928fed10cbf6f4d5f80d6533501b66736864a3b50e96c58021389b20818a3bc120a3e0a1458aff9ec275a66e7ad086d31e30fc59e02b94b9212220a20640499f5afeeb7ab49c601221c44fb762f3c02d05d5032bde7bab27823a5827718a7a4120a3e0a14e357f35a66a72eb8162f5a66ea221b9025ff56bc12220a20ac38b9ef0c5f7314dec03f8ad4d2fedd35f9d49bc5bb9de48832b55c00d6571518c3f3110a3e0a14ee2a8b5958586c495b1e7bf7ecfc284d83136c1512220a2099a8eeb2d17d0dff6b915cf6c65ffd563606dfd60640a35b8e082d40f67dca3318a683110a3e0a146d8f5894ab17dc6821a7d82c31a05d81b71c173912220a2065348bed02c217dacb610d4c8b7ae45d00389078b18df73e644174a0752c3c8418ceac100a3e0a143096bed304a51710ccde2dcdeb5c364c7559e73512220a20d77807b7263fd82cd116f733f78d7415eb08ac78be46a5e31d20b5285565bfee18ecf70e0a3e0a14c9e9ba93f5a68c989d6fdd0d5b3cdb62e225c90f12220a20d61e7cdcfae95db114e7dce184ca3b11d59fc64b9163bc02bc8728631b4b5f5718c9e40e0a3e0a14784cd03b935c7c3e75419b1f35b283e03faa7c0c12220a205364bf153a2c5eb3e916bf62c327bbe782ee6b275863c9a11f8af39f7bef4eed18a2e00c0a3e0a142640a32bf68b7f9723e001c2e4b4e32e00b9467912220a209e5d22a072e232bf5c277dffa170ebc80db49d5496c0b638b6af2c01ea993c0c18b1dd0c0a3e0a14caab75b9c6d41e924cd1b526f5e2d123db756bc412220a2091da6ce3e1debed393e42c02a9641e42e965fe5b4095699c3db096049b29b4ea18d9c10c0a3e0a145245f51eeb87311e0544086e64df6e737afa015212220a203df173fba4427fd0acd8bc0f6c83f8f13a7944e5ad20c5f365c7390e5382313918acc00b0a3e0a14e7dc29639166155dc9ef5d562e44cefec2d169ca12220a203f0eb2d5e935320f269d5ab878104d36be1a2bc38d5ef1b2fe66760814a93c9818affd0a0a3e0a1457f61959ff8a08562bb0aba4921c5ef1b307dc6312220a20f5d18e7d52e05100d55e2f5fd0aa9fa8ba710f0801d7f605985b9732063b1c58188fee0a0a3e0a1483a05569feb3c027db1f5e85c48073d6994040ee12220a2087e931b901b4fb3d4733e821ad082d39d13930a1705baf4f5876a941e12f22dd18e3b30a0a3e0a14618ca0614c7ea885243f3580790708979be7bd4512220a200ec759549c85f6a5a4dbc79f7b112de4592dff74e9562d71c45a8fd3161dc9f318fbfc090a3e0a14f8426ee2307c31165cce1cc4da9762ae74f84ec112220a202cb896fc05f2f31a15a470963122fad880de8d26bff2a259291fb18af4d5914418dcf7090a3e0a14f063a67840c7d6411bd0c4b9603a1c6c7440d3f912220a20f9b393d098812877c926b72ffb2acea890ef4e8d321595c8b3f6d2b6ad92dff118a5ac090a3e0a14c7ed8e58ed8bbc7c0e9911bfaa38c725c003836412220a2060d20c0dd3ac3a21ffdbb7a4f0e6e704ff5fc0a6d11b10d1ee194b1a1fedbf7518e788090a3e0a14bdc269f2f62e3b02d6eb049bd2a11a425cfe3f2912220a203cb375c0722fd44d8da62db992e0bb34036e931ab217862892eca2cbcfbb2e9218eff9080a3e0a14c1976fefd48939e2327cbf83f367841028b95e0e12220a208aaa1c11dc4b43e95603cb10d9d24b6215e0232c5d87bb80539d440d6792e22618bb88080a3e0a140808a48a93fba44a17029c17b16ad5cb1ccccfce12220a20cdee5cd83bf3e85634a60f171c51cabba3fe76257605782eeb11d3a9d735c31a1899fd070a3e0a1465a73fb6a5b297299393c8cc9a342242b136974412220a207887710424a3375409f13d31bfed217c1524fb0db7c4f64db96671a5bdcebbc418da8d070a3e0a140c714e67a83273e3c3e35b17ca8ee140551a536012220a203452cde83ab0a21e43c9b749851e03b2ed0421aea710281711ca57d448af7bc218fc90060a3e0a1472f92fd75727431194c7129be2411a9093e6d57c12220a208ed5b1abd4aa4593dcb9c790927ac89f866e54c73d593554e13ef1efd86ab66918bceb050a3e0a1411c30fd0a3bda953d88a2157a69b2cab52b41f0512220a2079e66631b3171534f3bce2430e6f9a87d83b94d0fcc4d21068dfcd3e2002df3e18d788040a3e0a1409d7dd253fe3ea53eb16a5c4492166688b3c658012220a20a24599a1f46bad5422ffb0d05e83a4394b602ffa007fe3393c985569ee7aa07f18acff030a3e0a14f7db3ca3fdf105cb9a2f4060d0dca3728632fa7a12220a205556636b3bbc09f22e546840fa79d6628e36b4e4ff8d6978d9b274a5a92d932b18abfe020a3d0a1413a56fa6f11adaa2b09d97e57b36277319f22df012220a20315f78bea93b18884bab79e68711a9c05c67953b78788979e80c7fb1fc4caad618ab73123f0a145de72cbf82ef92e1042f0d5d52c4a94ba366adfc12220a20233d12d59fef3392bcc26bc9899ff2f4a0e54002ec89be62f7eb31871518b32318ce81f30118a287be3e" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "module", - "value": "ibc_client" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "action", - "value": "/ibc.core.channel.v1.MsgAcknowledgement" - }, - { - "key": "sender", - "value": "archway1ejkj6ssfuwsea0lj9g84n0fsdzkzs28v9p7ju4" - } - ] - }, - { - "type": "acknowledge_packet", - "attributes": [ - { - "key": "connection_id", - "value": "connection-75" - }, - { - "key": "packet_channel_ordering", - "value": "ORDER_UNORDERED" - }, - { - "key": "packet_connection", - "value": "connection-75" - }, - { - "key": "packet_dst_channel", - "value": "channel-126" - }, - { - "key": "packet_dst_port", - "value": "transfer" - }, - { - "key": "packet_sequence", - "value": "988" - }, - { - "key": "packet_src_channel", - "value": "channel-104" - }, - { - "key": "packet_src_port", - "value": "transfer" - }, - { - "key": "packet_timeout_height", - "value": "0-0" - }, - { - "key": "packet_timeout_timestamp", - "value": "1711347430185000000" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "module", - "value": "ibc_channel" - } - ] - }, - { - "type": "fungible_token_packet", - "attributes": [ - { - "key": "acknowledgement", - "value": "result:\"\\001\" " - }, - { - "key": "amount", - "value": "27978000" - }, - { - "key": "denom", - "value": "transfer/channel-104/uakt" - }, - { - "key": "memo", - "value": "" - }, - { - "key": "module", - "value": "transfer" - }, - { - "key": "receiver", - "value": "akash1t8np6xr8qr24yjyp3lkg9j4wyeazgf6frrzx4u" - }, - { - "key": "sender", - "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" - } - ] - }, - { - "type": "fungible_token_packet", - "attributes": [ - { - "key": "success", - "value": "\u0001" - } - ] - } - ], - "codespace": "" - } - ], - "begin_block_events": [ - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "20456465438196201488aarch" - }, - { - "key": "receiver", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coinbase", - "attributes": [ - { - "key": "amount", - "value": "20456465438196201488aarch" - }, - { - "key": "minter", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "spender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "receiver", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "recipient", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - }, - { - "key": "sender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "spender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "receiver", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "recipient", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - }, - { - "key": "sender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" - } - ] - }, - { - "type": "archway.rewards.v1.MinConsensusFeeSetEvent", - "attributes": [ - { - "key": "fee", - "value": "{\"denom\":\"aarch\",\"amount\":\"34094109063.660335813333333333\"}" - } - ] - }, - { - "type": "mint", - "attributes": [ - { - "key": "amount", - "value": "20456465438196201488" - }, - { - "key": "annual_provisions", - "value": "107592825618736741349012839.100000000000000000" - }, - { - "key": "bonded_ratio", - "value": "0.476278464914987794" - }, - { - "key": "inflation", - "value": "0.100000000000000000" - } - ] - }, - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "spender", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "receiver", - "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "15342349078647151116aarch" - }, - { - "key": "recipient", - "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" - }, - { - "key": "sender", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "47031267452693036.061160109957597621aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "940625349053860721.223202199151952412aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "38476736132757653.641375706228733112aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "769534722655153072.827514124574662242aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "25198563408572443.297487568120742094aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "503971268171448865.949751362414841889aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "38385179966923893.758115958837052080aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "479814749586548671.976449485463151006aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "20848080058682149.927238603944519387aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "416961601173642998.544772078890387735aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "18078103662935996.564316767356891825aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "361562073258719931.286335347137836505aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "16397185525293103.453610095140066692aarch" - }, - { - "key": "validator", - "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "327943710505862069.072201902801333835aarch" - }, - { - "key": "validator", - "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "321840969895750362.322698020897468527aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "321840969895750362.322698020897468527aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "15497002790178990.382878376219577609aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "309940055803579807.657567524391552185aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "14382002009562408.966451471365272199aarch" - }, - { - "key": "validator", - "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "287640040191248179.329029427305443980aarch" - }, - { - "key": "validator", - "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "13893332467457515.070627762265926164aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "277866649349150301.412555245318523271aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "13770849876624121.332192990936737311aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "275416997532482426.643859818734746213aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "12930798182518861.484757122871543030aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "258615963650377229.695142457430860592aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "12030364971758872.030268279538284386aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "240607299435177440.605365590765687724aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "11189751818200215.104161320082748986aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "223795036364004302.083226401654979719aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "22284930786917069.309869240938732002aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "222849307869170693.098692409387320015aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "10622762200262906.250589114950164761aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "212455244005258125.011782299003295211aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "20593888085947895.310473392523510734aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "205938880859478953.104733925235107341aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "10233575111733853.664058333319530926aarch" - }, - { - "key": "validator", - "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "204671502234677073.281166666390618516aarch" - }, - { - "key": "validator", - "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9990294308427255.981021251439344373aarch" - }, - { - "key": "validator", - "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "199805886168545119.620425028786887454aarch" - }, - { - "key": "validator", - "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9956509646731535.147278403734301398aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "199130192934630702.945568074686027966aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "19126950729710299.665644427976706534aarch" - }, - { - "key": "validator", - "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "191269507297102996.656444279767065337aarch" - }, - { - "key": "validator", - "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3795328565503973.184141327894708544aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "189766428275198659.207066394735427181aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9442139614759897.331870324410660370aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "188842792295197946.637406488213207399aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "37171458291268257.131570065986651951aarch" - }, - { - "key": "validator", - "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "185857291456341285.657850329933259756aarch" - }, - { - "key": "validator", - "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8909997069263457.716045493806167155aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "178199941385269154.320909876123343102aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8410863836693763.423641845394010617aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "168217276733875268.472836907880212335aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "16287634795052974.555039143568147364aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "162876347950529745.550391435681473638aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8116318548809015.185851059708506321aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "162326370976180303.717021194170126423aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "14106818207670570.608562862410733280aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "156742424529673006.761809582341480886aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "7817509546278174.286098972010596527aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "156350190925563485.721979440211930538aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "7698025627362544.745416469488871318aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "153960512547250894.908329389777426363aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "1468691530058656.639589777369466772aarch" - }, - { - "key": "validator", - "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "146869153005865663.958977736946677172aarch" - }, - { - "key": "validator", - "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "13254946033113129.332220275501974624aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "132549460331131293.322202755019746245aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6528176308965305.138762208357045787aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "130563526179306102.775244167140915739aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6427765125466552.035382663728815800aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "128555302509331040.707653274576315992aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6369673068788454.612640168190546461aarch" - }, - { - "key": "validator", - "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "127393461375769092.252803363810929221aarch" - }, - { - "key": "validator", - "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "12731049483598902.774539034875018554aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "127310494835989027.745390348750185539aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6188648127981006.239817584115334679aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "123772962559620124.796351682306693584aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6111735218698457.658597005193378472aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "122234704373969153.171940103867569443aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "11920977472838526.728569377167360808aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "119209774728385267.285693771673608080aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "11798931103635591.155836728325712191aarch" - }, - { - "key": "validator", - "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "117989311036355911.558367283257121914aarch" - }, - { - "key": "validator", - "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5734886166478625.892898092108881652aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "114697723329572517.857961842177633032aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9032987084354732.600540116550070865aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "112912338554434157.506751456875885809aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5622139761003751.922093399217840541aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "112442795220075038.441867984356810827aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5467151622868464.860068008108763923aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "109343032457369297.201360162175278454aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5147485597735517.675781608689883791aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "102949711954710353.515632173797675817aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5061348711718600.465891267895790323aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "101226974234372009.317825357915806467aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5029050017899537.493160438270993264aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "100581000357990749.863208765419865282aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4959406531013593.852444214136180672aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "99188130620271877.048884282723613441aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4784203038222939.406288267155309764aarch" - }, - { - "key": "validator", - "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "95684060764458788.125765343106195284aarch" - }, - { - "key": "validator", - "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4660416003997820.740312005440280988aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "93208320079956414.806240108805619764aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "9300475936685287.242513541288714658aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "93004759366852872.425135412887146582aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4626325987160778.397378224627902136aarch" - }, - { - "key": "validator", - "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "92526519743215567.947564492558042714aarch" - }, - { - "key": "validator", - "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "902962733350027.401752135061459718aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "90296273335002740.175213506145971754aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8912165512916799.835861475013525979aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "89121655129167998.358614750135259792aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8781155492791221.494594506355942232aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "87811554927912214.945945063559422315aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6899333091057620.960224373610959541aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "86241663638220262.002804670136994266aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4310085005410204.100167898860593316aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "86201700108204082.003357977211866318aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4165137000608207.977714955807129321aarch" - }, - { - "key": "validator", - "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "83302740012164159.554299116142586422aarch" - }, - { - "key": "validator", - "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "823400410887391.655444942037895916aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "82340041088739165.544494203789591620aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "8110953022754377.656552773692154718aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "81109530227543776.565527736921547177aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4049923832171419.900874945961500186aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "80998476643428398.017498919230003713aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4046835101594465.126102101748185146aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "80936702031889302.522042034963702927aarch" - }, - { - "key": "validator", - "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4015504538361708.968609533070971737aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "80310090767234179.372190661419434749aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3989445221024750.193829797927477751aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "79788904420495003.876595958549555022aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "7819950980242190.974745026504499838aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "78199509802421909.747450265044998376aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3893314638170688.030671063618776405aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "77866292763413760.613421272375528109aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "7356227686733312.614918000804230323aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "73562276867333126.149180008042303234aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3651595789734440.460813787200889911aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "73031915794688809.216275744017798219aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6336760568920340.042851852762609760aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "70408450765781556.031687252917886220aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3257159969974389.397733527606727682aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "65143199399487787.954670552134553635aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3241903470240747.643062868104794157aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "64838069404814952.861257362095883149aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6479357479850821.563309842818828243aarch" - }, - { - "key": "validator", - "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "64793574798508215.633098428188282433aarch" - }, - { - "key": "validator", - "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3181101210787609.253499528559273910aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "63622024215752185.069990571185478197aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "6341244082981521.831817288858422522aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "63412440829815218.318172888584225217aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5963842014307592.847667445233562256aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "59638420143075928.476674452335622559aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "5748320385530191.674253504092312988aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "57483203855301916.742535040923129879aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2852413840903474.221838280346566438aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "57048276818069484.436765606931328767aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2815496826467752.580425254170529570aarch" - }, - { - "key": "validator", - "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "56309936529355051.608505083410591406aarch" - }, - { - "key": "validator", - "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2778202691396666.747218384581883466aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "55564053827933334.944367691637669328aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2694434066683173.206122624486548955aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "53888681333663464.122452489730979101aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2652887474298394.524581334018800918aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "53057749485967890.491626680376018355aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4945956833129978.687897043942664985aarch" - }, - { - "key": "validator", - "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "49459568331299786.878970439426649847aarch" - }, - { - "key": "validator", - "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2348424476570194.306780348897158990aarch" - }, - { - "key": "validator", - "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "46968489531403886.135606977943179798aarch" - }, - { - "key": "validator", - "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4466388844269614.461180848095981218aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "44663888442696144.611808480959812180aarch" - }, - { - "key": "validator", - "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4410639719897042.568753264099370019aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "44106397198970425.687532640993700187aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2180926627806602.966830879190971933aarch" - }, - { - "key": "validator", - "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43618532556132059.336617583819438666aarch" - }, - { - "key": "validator", - "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4334790628526192.728785775490332845aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43347906285261927.287857754903328446aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4317353020640258.703423690157865934aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43173530206402587.034236901578659340aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4310621135865702.319268914397417516aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43106211358657023.192689143974175157aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2151546397411960.927938840521971384aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "43030927948239218.558776810439427683aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4276970154992218.095443976355904791aarch" - }, - { - "key": "validator", - "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "42769701549922180.954439763559047908aarch" - }, - { - "key": "validator", - "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4227209931455874.017210362427827103aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "42272099314558740.172103624278271034aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "4224035363719377.513891413189025352aarch" - }, - { - "key": "validator", - "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "42240353637193775.138914131890253522aarch" - }, - { - "key": "validator", - "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "" - }, - { - "key": "validator", - "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "36137022017131114.228519325308756161aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "3577726581699250.284220154744698892aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "35777265816992502.842201547446988919aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "2466956306598184.675480716666651432aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "35242232951402638.221153095237877595aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "983390744674140.023941688397971514aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "32779691489138000.798056279932383792aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" - } - ] - }, - { - "type": "commission", - "attributes": [ - { - "key": "amount", - "value": "1717680363758128.131106183256179516aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1yw5nl74hv609enqxsn70k55p3pychyc9cvznds" - } - ] - }, - { - "type": "rewards", - "attributes": [ - { - "key": "amount", - "value": "17176803637581281.311061832561795160aarch" - }, - { - "key": "validator", - "value": "archwayvaloper1yw5nl74hv609enqxsn70k55p3pychyc9cvznds" - } - ] - } - ], - "end_block_events": [ - { - "type": "coin_spent", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "spender", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - } - ] - }, - { - "type": "coin_received", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "receiver", - "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" - } - ] - }, - { - "type": "transfer", - "attributes": [ - { - "key": "amount", - "value": "5114116359549050372aarch" - }, - { - "key": "recipient", - "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" - }, - { - "key": "sender", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - } - ] - }, - { - "type": "message", - "attributes": [ - { - "key": "sender", - "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" - } - ] - } - ], - "validator_updates": null, - "consensus_param_updates": { - "block": { - "max_bytes": "22020096", - "max_gas": "300000000" - }, - "evidence": { - "max_age_num_blocks": "100000", - "max_age_duration": "172800000000000", - "max_bytes": "1048576" - }, - "validator": { - "pub_key_types": ["ed25519"] - } - } - } - } - } -] diff --git a/packages/node/test/kyve_block/block_4326863.json b/packages/node/test/kyve_block/block_4326863.json new file mode 100644 index 000000000..042eae6bb --- /dev/null +++ b/packages/node/test/kyve_block/block_4326863.json @@ -0,0 +1,4902 @@ +[ + { + "key": "4326863", + "value": { + "block": { + "block_id": { + "hash": "B729E427BB694AD5E5CA09E26D3D3B4690DEA0EE7A1F2DC0DE0E07081832DEFF", + "parts": { + "total": 1, + "hash": "404AB929FD200A51028D2A85C28B336AFD9962101285208600824A5E59DEAA49" + } + }, + "block": { + "header": { + "version": { + "block": "11" + }, + "chain_id": "archway-1", + "height": "4326863", + "time": "2024-04-26T10:04:00.954431343Z", + "last_block_id": { + "hash": "B5517CD93ECF6C568C00204CF0BB6D6E87292806911FDC5DD5CF8B318EB5DE6F", + "parts": { + "total": 1, + "hash": "F34408000CA1F5D31D5B9DB6C4A99375AB971DA8E0691076D3C5188DE8DC9C28" + } + }, + "last_commit_hash": "4181AE959099CD36D4D2FE3A77348424538F8294A17B665CBC067E547406FE98", + "data_hash": "0668AC94110099A1EFF223AD7947183CDDD599850104E4F934566FCA87B409CE", + "validators_hash": "05B5B6A3AD65C244270279D72910F366C360C909FD4063F839A2E5C59EE14C18", + "next_validators_hash": "05B5B6A3AD65C244270279D72910F366C360C909FD4063F839A2E5C59EE14C18", + "consensus_hash": "22E3FA2D1695AE7DB62E55677BF0C914B1EC88D64CD8D280CF2E29B2E06D0965", + "app_hash": "35A9080C1FDE71BE45A6B691DE246E9BA4C6922CCC09EED116439D251E500DCA", + "last_results_hash": "201EBDFD6EEC05B6133129D38733227A7BC29C772B757E5E841BB77EFD61D50C", + "evidence_hash": "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855", + "proposer_address": "56AE16561016ECD1B64540DCE711C588F06E2DBA" + }, + "data": { + "txs": [ + "CoKKAgqm+gEKIy9pYmMuY29yZS5jbGllbnQudjEuTXNnVXBkYXRlQ2xpZW50Ev35AQoPMDctdGVuZGVybWludC0yErj5AQomL2liYy5saWdodGNsaWVudHMudGVuZGVybWludC52MS5IZWFkZXISjPkBCvlgCpIDCgIICxIJb3Ntb3Npcy0xGMnVoQciDAiO+K2xBhDp8fmDAipICiD6hIIwJbBp+HkTiwA4nhxISrfw+5rm2k5F6ln8iep3nRIkCAESILIf5NNlz9e1vF6IABF1fdGpoaJwa+Y7HOi1A7k8quG0MiBh/jI86b+kYKjJOoUl2HYmiJf0fyB2T3Ua0lmaIyC0wjogkdXEtMAidDhLJa1BDQOGiE0jkeXLpv4h3lvsy4pMoadCIDFqbiJclqXbWSH+4xgoAtBHMViNYvG7RkDxSw8Wdg9eSiAxam4iXJal21kh/uMYKALQRzFYjWLxu0ZA8UsPFnYPXlIgcYa03WeyQ+BeT/3zwHkjq34kT8/6CXOfb099ll3EfqlaICHEy+uUyLodmYTFFqjKPUr9/1l7YNtyJnjTon8BKyZVYiCMVMWJbRYNCSySkI6PfNEmNWIDS4ABKntSXSIVbqtkYGog47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFVyFAREbaC8xDEAA/l7G+0Hqyq+xv6nEuFdCMnVoQcaSAogT3EFFRD5YrqtsdZ5/wqXjJqf2BjWcV1te5rO2sO+Hr4SJAgCEiBQnt9nH44epPZVmko12I8woXOPWpVCeuBhTLz9zyT+dSICCAEiAggBImgIAhIU4I+6D+mZcH0UlrqrdD6rJ3hNwcUaDAiR+K2xBhDk5tGDAyJANTJ+oGSJNZik0GF+fNERfSEhsOykbtEsi+qNNlaKp55DkZoldy6Ny+NCyXBa6ruXpz9Eo8WsTkks1it5mSMTBSJoCAISFHZVUCKM8wm90z8/XnaDULo9acOxGgwIkfitsQYQmOnllAMiQJbePaq3c0dutidS+y5NY91zxO3mFEbHeuMeReeydhJDMfqerSJu36vCcSD67JgD0XRa2I/nyVnj+fOOk3UnygAiaAgCEhRAzHIzFLbruTtJ+9nTMO7ItGQcqxoMCJH4rbEGEIqdmLUDIkALiOGw0zUxxSs3n5J52CUfsVFxzBQb8hTniopV+bEUmma9K9Ev8k4wmS3squijoZmPU3QuZIiYhT46ujDSCAwIImgIAhIUnQKBeGhy07vlPFj77KEY2G+oIXcaDAiR+K2xBhDS1fmwAyJAjxQkpNvtg3TBEMIvE1GIMO9jdSRoe2X6TRsjHi5vTjXVLS4nSmmwlsrlK7h5JXvKnXiwdlcQAnxnUQU50lBTDSJoCAISFNgjQ/zVp0lpwLSEV9cOjVXY9rgBGgwIkfitsQYQs4e4rAMiQG08+XmITtTo9MpLtGSxFDJgFJQmrGausJeAwJX4h+CfVkWL1pi+AblN38MqsMvYSpFZ7F/bfPvbflP2qNloIw4iAggBImgIAhIUoW5IBSTWNrLaKtGEgzJ8LhCl6KAaDAiR+K2xBhDhrs24AyJAb9hauSnY3rCkC26nLugCIYp9LQfq23AXMn3++KeVqMme7DME+rTE2t+rSNrPgQQ6qTRn29boUaFacVVH9J+GDCJoCAISFHKxSJ77V6aAV3qDiluq6+Fip8gCGgwIkfitsQYQv4T88wIiQOhX6OmF03WNFSNzFpDoOi+Qphwo5SUPmR09sxvvJl4qu9DsrnUK+cMODFsKHELFvv33pzilAlrDENPbI9mYIwAiaAgCEhRR19BaZZIIpldhkK676PB2A4UVFRoMCJH4rbEGELf++vgCIkCZgXLq1MiJKELv8aAy6RYgBVfHrbFwFWiVPAAgQSO3OBkepF9h8hVOwOTKwy35mVpKuEE1Q5usUVxWCGnUkUkLImgIAhIUGwArbr64ZTxyEwGxtWRysbTeckcaDAiR+K2xBhDntMmmAyJA7rZ82fyFEsRA4lkiho3SDBMfBkzHnoLitLDIVRWq/gCehSee7uqaFq9Ab0c8wzGCVK6IKjdDHklkV3JyyC6GBCICCAEiaAgCEhRx342YecIFY6Tiq+2pXNH8V9v2qhoMCJH4rbEGELnP5pwDIkAYsAHmS5gQrfmBiRxX56sBixAUKJW5GaypiQJb34As5Y+UeTTZ07e9Gh3X/8QZy50RKgUq6X2kK6Kexw2O/SkAImgIAhIUEx/HnnoBLZ5+7yHeO6XVAz/NvB8aDAiR+K2xBhDx0bWZAyJA+0lgpg3i2vUQ/Cd3861z1bAPdXG/Jm/I36FQOR/B4JIhjDJanSURrNb++6bV41XvzzDGxmf0yMOGSnnNjeY6CCJoCAISFDkydpLCWKV5cO9T8KpNPAD5WYi4GgwIkfitsQYQ7bHzuQMiQFCOGWNRn3ibVuy5x3lOvsmOhT7alPPvtFJFwuLZSNXsh6kzC8+KOrZNvPlNrJmjU9RV3HnI8mF4BPbDq2YxEgciaAgCEhRzQelwubPv+CsgYNNGn8UNevBBRhoMCJH4rbEGEOj+1J4DIkD3N1Pt1jtOOqsUvogT7KejayvQTbsrmXjW7r/nMie/yV8nwZ1lCnnbyd8MIfQOESJRr2hOUlnpycaJ+fi2FnkOImgIAhIUA8AWq37DLZ+Nd6/bGR+/U+oI2RcaDAiR+K2xBhDPhLWXAyJAFk9/lcJfJwC6PXTOpACOiHRV/+G86lspoHXpnSqpcg4ZADA3X85/hEf93vJdXk97i/ChHDetoAVrrq4syC+mAiJoCAISFCAi/ozEnkhjDHYWDhGogEWSGdJEGgwIkfitsQYQ6qm/iwMiQGTU1TDo7ra0PwDJA9SowTEhnr5uYW3I/QE/1YYg3nK1aF23SbvL1BrFKoMegjRe5Yp20Dx1XcYB1XigEeIhDAkiaAgCEhSefK4Anv/00WPz+4eBoHslwrELMhoMCJH4rbEGEJX70/sCIkASkBUluBMP72i8Wwha+JHRrLSWA06wg5ZdNQtPFbeXLCKeiP4aR4MfI33U4581fQTgf5A9om0O7pIf2crA7gIEImgIAhIUmQY7kZQEtpUKeaajHjcDeP4HAg0aDAiR+K2xBhCj9vaBAyJAyDW8NPZFXBjED4ut1BT8tjt1cvOCzZdu1pOivvA3OsiHSo8YeRjgqRGjmZDxatZeo1NfSveOilVYa4TJrRQdBSICCAEiaAgCEhR2ioJwDjBG5tr4SWZFeeZJWXzBtBoMCJH4rbEGEJz4h/0CIkAcUGZ/JozYVRWxvqkRWODBzpNYgsBnnmCyNs/ZFxPqlbI8kVJkVdS2bW24OHzZvJVbVo2aHeMkE774zz0zNyIPIgIIASICCAEiaAgCEhSga1toK0Ja0gajXK8kb9cN0JjlBhoMCJH4rbEGEMG0xIsDIkArhSlasET3FMV7lfP2tAt4uYtZH+UIdNFZE9nqLihB/3AE4krU2d0nsP897stdnPu0Lq+jMjcuG2PYLoPYNSAHImgIAhIUl6/kU5W3TnhMiNReXMoplQGfrggaDAiR+K2xBhC8wKL/AiJAUOr63plAt9q5yvNE5eliaDldf2lnjI8pEJF3rxwgJHsovj04Zdi/Ysm3oXH8l43nzhbfxhOYKJkUFgdFEi08BiJoCAISFGI5pJjCLfPsP7DKL5bRVTX28zh6GgwIkfitsQYQ2eXQiwMiQPqgK72pKpxFLLYtXtj7BS8OHbgQdIYDMHVLrcAlHGFcKx015Lv35lXJvzqrxCG82KB0CzCUZblUEdPYfFt8WgEiaAgCEhRfmZpL4lSGmSWn8v6gTXs7g2z/CxoMCJH4rbEGEJKBuKwDIkC6xaSYhVXPei5mDzppbXPhaD3P8NhS6uUk4JF3vntgGVhFWM4F6/BN1cR2Nsm/ZAJvDk2TljcmpBeeqQf+PMECImgIAhIU8/Vdoku0faYLD7cewanJJ0vO7bIaDAiR+K2xBhCW1ej7AiJAtVriGtnOhGljOezuMYix01LrqHgMS0ETLp8I6dFFzuUctbKCQbQpUhhIeherUvICdlg0EK783kIaOp1nTsvjCiJoCAISFJy+yMvU7TqtS7KwNG78hqbEH5FgGgwIkfitsQYQ/6WvjAMiQNJNkNiqMbbjRz+Oe2uEJ4tK7Mgso6GxaGECNbBk379CE6b13ZPS636Y67UF49Ay2l/TfWqWi3ZX7Y6rVPAWJwwiaAgCEhSvGVlD5E/h1iUAdri8GRDqvIXx8hoMCJH4rbEGEKDGtPUCIkDI7CjlJZV9IfMSdnuzUPA97YsNdZpCO7zILtkabaYVRRvpmV2wFplwZDprhdzimZtW88sC8uk1t0aKv6v57ZcGImgIAhIU2812XbJkBjGUbBOTuiVYdsdto44aDAiR+K2xBhCyg56QAyJA8loK3Zy/pmG2saF8txhFh0mw/4WX24B9rMo5j9HYfJVi02PE6EipIA+rcORpOy0II5zu4oPwE+mZJ4KuFSVCASJoCAISFGkS4Lo4zQDJ8vyecelx7O1Qe0L9GgwIkfitsQYQytG4lAMiQHDqE/Hv3r3Y96zO0NlCB0iFRxV8jNeY7fjKAiN/QUHK7b87VaMn+f5DZg2Or3heOqg2RYvJ0Nslfs95vo8tqgAiAggBImgIAhIUQMSIOc1IfYoT1llVt/xsT1YNj3IaDAiR+K2xBhCY+de9AyJAKhD5QXxCHbYiHm3yXgAQyIaq2f4MjFFpiXIkMyvzuoOwSjo4SuFajXnOz5D8WC9LA1sSoK6GM3hHjMdU21QlBiJoCAISFI4FRbEiLntchc5p7cePKAyyt50YGgwIkfitsQYQiMqpnQMiQLDIi6g15F1Y+lfrEmHfCzMRFQy7ZVig3Medl0FIOwwZWnFyzgX6ec9UDYADSt5i/2EelFZQHrtej+KK1lP/xAUiAggBImgIAhIUsLNf7UDapf+dS8aFx1klGH9iIRkaDAiR+K2xBhDY8N2jAyJAHB6lqNQbXp5iKQYPOb52tCx16uo3i0znXsqFmZJiLoNAXRhdd3zl2SSAlFj86Fe948lznDNFC+nL+xEyAi8jACJoCAISFBOP2at6vguu0Uyn1B2IW3gFKkqhGgwIkfitsQYQ0+CalwMiQFadgGYYyicZHcd4QAkZ71MRR9aQ8Afnw03BiZ49FK+2X07wcFjpTxK/GOMORzYxGGlU0/ojSOotMiENdjkoiwEiaAgCEhQnP3LuVZh6+ncbJ9Nw+hMfYIuDrBoMCJH4rbEGEI7Sq4kDIkAmW6+lqoA9Qwz9yJwjXCXZ80SGcnPIuVdtaMOgrIwOJ6VyfdpK2rDL+FIHYrJFVtI7E7qYhgMqzux0d+o3RiUPImgIAhIUlbAC3mdwcxPRI9BkkvGnpYR45UYaDAiR+K2xBhDN3vqRAyJArz1V6SNY5QWvZFmooWeot42Qlq8k5ufjq4ZlQcJ2mjQwpu5zHL6D7oVtmwvC2I2sNkrZrviNJwSphn1TopsVASJoCAISFPmpaKQF+wQpQQrlFl5fIZMnHmeKGgwIkfitsQYQpt7VqQMiQHiAEvM281jRNUoB8+CrQbsGS1M2jIWsBOx7VdzMkcvR+yxZrGRvkLCEU0VWuqHPn/1MbbBP81SjLq0ypVZHQwIiAggBImgIAhIUfvJEhowwSqWzSIk3Li34dK/WNc0aDAiR+K2xBhCTsvKhAyJAQ6t/yO2SHUzZwpkWSUUh3hZ4EGUMOMcbfo2JTaluapdk4Ojg+L+5/G5gA/Dd450lH8fjjgVeQCbQMFpNGp4DDCJoCAISFOGR5lTQa59yFWi7lFsutR3cHI/cGgwIkfitsQYQxaya+QIiQKW/gruAor8Luua/5/IuMl6xAd9ploKOl4Hf1hxfGIdMjtoElOJrqhS4nyali1eGg1PANMnX6RR51IC8Hx3KTw4iaAgCEhR+Dtdom2XDRdHIF8WwMy/RMt5YdRoMCJH4rbEGEP/FmJoDIkDuNEo2ruGySWc49oKZOtqath8gxuhKkwmwj0jpgfiI/iO1Mx96tcpOCMj6pi0Mb9PH5yflQ1Fy289r984/jV0EImgIAhIUn47C71gc4lYwyBnxm1SEA550jRoaDAiR+K2xBhCj3JCSAyJAMcRfxb84mRRkNUeWfbfUdgG6jEYB/vzQiYyhzj1PqchFfDrAPCViUQ9cZ1fYO1g5ox3033lqWGZ40+P05ICgDiJoCAISFMoPKnEh+G07bZE0lzAVW5paMcVUGgwIpfitsQYQ7/rm5AEiQGrDguPWelo3fHSJleojb2e3dB7i198/oKwqQlS/X8pmARHwbUzaSmNlP1fxAMuoV00+Z90ZhnrYoskxO5JquwkiAggBIgIIASJoCAISFAb0XDb8uVflXZI6bU6QXC1xURWtGgwIkfitsQYQxtahqQMiQG303dLqRKwEyEQ08FmxqFrinxpg7cMmRs8Z/6mnj7MvNsiU3mr48FCYZ4eE6ndEJdC3L3betDmzY82DYVRoiw4iaAgCEhThLO84cblZXvFUAe7SRm6TEOSBaxoMCJH4rbEGELWW/5gDIkCI5if4Zm0+YaSTwjTXqMycwTyoResL+QBU437pk9zd631BIa9lXPrD8FeL9sbj5JZfkoWRhps3A1a6TBZJQYcGImgIAhIUfVPXby24a+MKmybK3qaQeFMaubsaDAiR+K2xBhDi05aFAyJA17puqyRly1fLoiwau+eK923FPm8wW8JdRuSES/dU3hqWLet3HbF3/E5hgTYYLlqG9CIzmUFq69HkyLxRrwovAyICCAEiAggBImgIAhIU2KbFTFSiNtSEO6VmUgugP2DwnjUaDAiR+K2xBhDMy5iVAyJANp0FzmrY/X9p0dI20n9Yy44XbIdY37T/Xl1d70j1JKDXAPGWSGUAKTG0ei78KkIgu0c8GMMWWGwWPO0rpfHeDSJoCAISFBc4azCO+WcM3UEvsvPAnFuHX7i4GgwIkfitsQYQt/r6kwMiQJDZ2NMcn6we82bhj3KRAPYWBrPvHKqSbD5ECoobwMr04LgPK/oyp2ifOLpx68FhlEvpg6ufqEovMKhg5+ADUgkiaAgCEhTgO5hebIkF4YTYjJlcxjKqJ4mB6xoMCJH4rbEGEMnIgZoDIkBcIi12eLdyXLPrmzSJ0/LFXyypyVY3EGWVAVDmJutT/TCeYy/K8RJbU/emPfIVrnJV32dBjN5cH60UyZ+FALEGImgIAhIUyeYVKJ0dkuUCksOwvYNY2bLkApAaDAiR+K2xBhCM0uj4AiJAGe/z+LIS8sLJTRrojIgIUswXiO9Gbo73L69VLXYMauawv2/5yBn+SJgxFqAMrAbsoVgjfqbyeFXVN6lyyLNuCSJoCAISFPbD94crBG2nGYkF5stYwbd1tIvqGgwIkfitsQYQv4P9lgMiQGF6+oV4AM2zpXkHEwJKWw5Dx6zFar9mKJlcq/gA3zg6GOfuMZEYRrveFNhOLj7i4S+W3ZchEm8h0muyAktq3AkiAggBImgIAhIURt6hN8+xC8QZsld6qaWHGGgOGLoaDAiR+K2xBhDfjvDEAyJAKpoXlwZW90ZvUM7EamWWsaSyFJiX1SJcfxzKfTX2eJkq1WwrtxxvcvdDaqwVxnN+rdc2oZm1FT88RKir3JYrDCICCAEiaAgCEhRpIXSz/7uoA5SpTckmZdwBRPuoNxoMCJH4rbEGEM70xfECIkAmPMQGcSPitnoKXBySeL/LbcizhxZj4MiDDmTpKzpr3qHyOmQQtJjAu5bTilNkBBx1gRJel7CutJq7JUVY4AkKIgIIASJoCAISFGNIH23Kr3M9L8lTozXCIA7hkIYsGgwIkfitsQYQ6fnvmwMiQInNN/2/22icKI+jQ0bbnykeNEc09yUGiUfUnIzvvW1FrJ6ijJUiRDB15hunVoVsl40++0vj+I/3gfDnDGQwuAgiAggBImgIAhIUcSvIka63IdpycyvDDVMeDB6u2uAaDAiR+K2xBhDO0YWZAyJAgRJAJ8j6udPRAKJqZ9WBGlDfmQq4nDK58ZNjJs66DmdKnybePfRGULZegYxmEt3aYBw3Nl8D8QuwB16tdInvDSICCAEiAggBImgIAhIUlDVHysspxVeX4SGstOWGxJ2dOf0aDAiR+K2xBhCHip6BAyJAJ6OfqE/IDYXyv6kI74fdEuNzU3G7cr3g9JdaaJYwMz7m4KPlwQR5QTVjwkc58gHzXqKrWgXHcX6v4pU1HVKRCCJoCAISFF/s7JQIonEIM/L32EgzlGLCnBREGgwIkfitsQYQ88qclQMiQK610vra78jO9BnxfD2t9trNz4pUJI+RqK7bIo6msw2aBZmKirlMD+NRvyMIt+GQru+3YpAt6eezV/8zJfuW3QoiaAgCEhTVuTGQdxpQYEpfeEmq8GfEqdqvnBoMCJH4rbEGEK31+78DIkCMg1VrHyNSnJoCeVMU53wksnhd8uPi+NduNhec8PGWhcZ1sctoUACx1nMDMKMlphjUkkoABU+n8HKDSeYGjYwHImgIAhIUhEKQUx7lm0D+795SWYVzaL9xGewaDAiR+K2xBhC40870AiJAkIo8vHvjFsHoF+6A8SCz3btz563lvyUkDoXIwSGcbSOrOWeEiFoWUWseOaZeRnF1b6Xm6+YEZmP33u/huXhQAiJoCAISFE4VTJKI4xQ2uoFN2S0XxO1s79PxGgwIkfitsQYQ35q9ogMiQJC9SNAzd/yjsS42ek74QEDqfu7E09N9Z9kTKyGwIXJqdRQf+ZQXlnNVyT1ZOovapyscRx69m4/JQKZWbV5iLggiaAgCEhQKcJEtGOE9eMsy5jIqTlf4YebDyBoMCJH4rbEGEP2aqfICIkAPCKFNIgxD8SIc5LGlYlemn+mEvGtbYeMbMGy9DMvq0jcgqZc9Uy93TyH1fZENaruCjeDgg1XtG+jFqyLewmIOIgIIASJoCAISFLXDOkCaWJwJTon3fSQTnyXGpt7pGgwIkfitsQYQi4agngMiQJMtyk+oC05B1YsRX5xL/2f4UepHuUpkh4KEmgsGzDRs5B8Rl/d/SYR4fQt6db+5RxCNYryDwj9uIJO0LVlJNg8iaAgCEhRp0GBSKcZll067c2/HfhYkXD95qhoMCJH4rbEGENnM3v4CIkAIR5VbJKBwCu/kivosBiITsUEDlkYhL5j5WpRPkDlxkw6uTGXuQ3Y0yfE0EKaTQestoSo8wZ94oZSe9InaSXQDImgIAhIUf8HaQLJWjdvVPP87dsSc6JrihoAaDAiR+K2xBhDtqdyHAyJAWMA70DRkc4PhVq2fW7MCEER0gGk33pzevdc6IIbsCxFrXS/1NQQNvPanVpoX7Ar3hiqJyqujMmLgUYVaAqS3ByICCAEiaAgCEhQ+iOfFT2RkKpiy4d3VvbpIeU8GxxoMCJH4rbEGENPWwZEDIkAOtJfxA5Ue5bQpD28nnNPoh77nCIhA+B15LzLi+pU2ydLa8eVReJBqEhUwP4wAs+mpjzv0wtKr3YeVYT/WUd4JIgIIASJoCAISFOXLoZngRecDZxHYFOV+K2bDzAORGgwIkfitsQYQktbfnwMiQOkIIIQuJFqKXonwbKBfBVlS2e3w3CXoJ+U3SRElrbcZpap6ydVrcucIPkrmFFHw/uqYlHrLU/nh1naeGpOWtgIiaAgCEhSJTFbWz8Oo4J620aLjNGfEz3fA9RoMCJH4rbEGENes6aQDIkAcrww0pUuUObD6GfbXA3oNnVY5R+lFwlEDutbGsh1DgKwHcNnERmni452fjfn5Qjf7x/31Jt7/uWnAfCTUAhIIImgIAhIUyJaRcfm1ozVMcSog8AfN4GSMmQ8aDAiR+K2xBhDIosP3AiJAKJ02/0CgWPeIpqMV41B2UIkRfei0gVPzkEihKCfKjMIkPztgELBM9Enr2levIoosceDt2dMNr6c3zReLwD73BSICCAEiaAgCEhTUxBweF+kyHQZ7pOPkdudmssLCvRoMCJH4rbEGEPGyxf8CIkANeciqtSb6kIWZKbGzi3UWxCjk5+zMQjWqsHmBJIdhFBU+dgnM7y+xc0ayE/pu5OTzHKwKT0Bik472TLbioMYNImgIAhIUJvd3e9UpGK5xgBAisOLe7Zfd1QQaDAiR+K2xBhDIgI2cAyJABdxLaSJPp7+fF8cPg8lDgHsGeCS1zXYzDyCWGTa8rT1NBcP0QzPdZ/+jf0If5yeexCIcf6uhGsZPidKH+pnnASICCAEiaAgCEhQV/sEEFuNZzB3bQkxpFmsmcfJRSBoMCJH4rbEGEMzlpqEDIkBLlMxjrZiId6xVX9DBtU/7//1B+UN7QSESARrnjcT/uFuq4AvwlxfoTGV+/XrxthkhlLsf+9sZo/XJkcS8auALImgIAhIUAApZWWNLQpbk3lNkgd4AqKDrmlgaDAiR+K2xBhDXs6SYAyJAZzDelWR0TXtUOKcj2t+ewe/KrO0npK4/uGL/GE7+f6uFkKq3ZADIqLF/9YDRvq51mbWI2lVGqIJ1l5sjIpb6AiICCAEiaAgCEhRgpDPSiwh4jHLiEzVUvVzGh2nc7BoMCJH4rbEGEMH11rIDIkBwJKgnvHOUYtcpAOCx+npjtzror6O+2fTmUM08/wxcrTOCOMilh5NX9AsluYtIn82gNPYXwEdZ8lMgKTxWKpwPImgIAhIUBqo0vW0d00EZ49wXPvrZT0MKt04aDAiR+K2xBhDO7+aJAyJAAHVx5gqaPIyKsZU7CCMPna8mKr3ul5FDdDFxCOs9zEksfm46GeHCx6iqSmTqwNCEWFh08kvdl0x+gPl0otafByJoCAISFMm3U+0pfl+YlNSkMUnPyfeyB7ayGgwIkfitsQYQqrrKgQMiQPKpCJC/FDLBtNNDdm4t2bNGkdG6BrB7Y8lpIWtvmlDmJoSRX03XkOETZTOH+baMsFUoBZ4B1LOzAfNWDf/13w4iaAgCEhQ/9smIeZwa3zrKDaVhQ8gWOJCFmhoMCJH4rbEGEP+Y1KsDIkDH3wINh9LOtiqMEGuyiiRV6ItRP+b6btAK3W/GjtIMaImiMOLpBhnDn8tG5+m7Dw9EnROquR1tfMpfKYqsxq4LImgIAhIUmZOElUB8CbNDViquw6tVGlwkYjIaDAiR+K2xBhCBm4SHAyJA3xdkGf/DHFvhqXKRfQTNNdbdlewjcWCxTFgTo4oMvUMeCv+/S4cUQ60Ypm7X4SZ1rjPDKzHv/6/R2bDhV2MPDyJoCAISFJAf0SLMUS7xPejho9eVO/3cB4bWGgwIkfitsQYQvMOm9wIiQLb4B6ytDWu0ArJh373z/SCnJirBIlKtVLPxtI/T2OlPdtqpMDlULPQ75GOiZiF5R1ZKpaO3r5oL6SrLRH76SAsiaAgCEhT2eD2Psw4oMIHBY5gpP0gtyg6RLRoMCJH4rbEGENnKlZkDIkC0TijxSZKSj47ALlcPo9busMBj2zFd0cfi2798WoJmRL0V6j8YwoEBWGXwOAM2Auy3vZGULN5qD4VolrKTsfUBImgIAhIUqcTg4q8AGD2hFDTtQTIZkF6aho0aDAiR+K2xBhCSrf3/AiJA4AQG1Yjvpg9kTvLUePaWbN98i2J3TIsNCTrtUiDaPvTtlklt3+rn4wLazDX3LiyKWwHv58L8JAkm32+OaoG0BSJoCAISFBnsChVaW+dV520AWe9zDryhIrTxGgwIkfitsQYQr6y9sgMiQOOdyTBgfHkCr6lh9PBq9FxBbi+CNkS7/riesla4zEyaH2kNMMNeUvTLq1hlT1sN9u/ecS5gWEXPHbqIEds7EgIiAggBImgIAhIU4G2t60E4KVWPfJUzn/thSZxaG7kaDAiR+K2xBhCAq7H2AiJAFqzLVPAJI0dKAkxERf4aNLEcl8Fb9IyOFp+9AkU6bCYHpatPlpF3SMplTrzJ6y8PxJT0ZLDKcNrrwRJ8HZUQAiJoCAISFC0Vm3LUDBwdrd8k0lESAAAbdO2EGgwIkfitsQYQ/ODMuQMiQIV8k0Vrjnrgl9HdLotSL+ff1QDsY3ZARhKuH09JYp7Oca1+4VXGuQzq4mzc5MW6TnfYEGYygct7tYv1VWjWgAgiAggBImgIAhIUlto3XYopP49lgNo26iN2zYmrIMQaDAiR+K2xBhDZt/eMAyJAijmkyQTjnZFvaK8qqeuQnNaIuBdOSXdPoFVSvE5xQ9EXzkkEY93XvXFvJKz0QpEwoq4tj24+AQ6i++g0muF0CiJoCAISFM5IVRdknk+McUae99r8+aVYvxZ/GgwIkfitsQYQiISrqwMiQAyr+x+tXd/j+eLnAHIwWFSvKi8d0AjSM7C6T7mKqdIpxB8mV9Nocar/Ms0TMWCkX66JHfKweyTMhYCNGf6IawYiaAgCEhRoJ1w3z/hrtT0p1iN603Do/VCX/BoMCJH4rbEGEOm6nJsDIkDRN9EXAIPt818D9Oi//W1iPluCQoYSb1tgH6QxTUYoBPaa88tFlpQhejTGRFpN5KoJlxSgWWnZdgJQRFcmQ7IGIgIIASICCAEiaAgCEhRucFQkIx3O7DN+tFG8TB0sX7pIyRoMCJH4rbEGEPrJ3s0DIkA7C2vY3xe1cEdjmwR2rjpfaxdWKSvQExIoiGbuIarL09tje05w3h3yG4ONjFgjhVNubzY0ZsaA2KeThMIwcMcBIgIIASJoCAISFHxaqH5SA8Zuo1xkJi9Xbt0putmAGgwIkfitsQYQ6bzaogMiQDi7C160MRc0PNuthfY2w2fgUyg0J+a3K+NtCtV20MpzM9EjTBFDj3UtWCLOUhdLEYH/2ejllQRqn0K8c81EMAgiaAgCEhRFGs7Kp9xMzm4LfN4C9FXflzU15RoMCJH4rbEGELbk1KADIkAwAezYlnczzrgz9tqcQ5gYuku0VJ4+WZqHNOcym7d7FvFlkNnbdEDfqEf4aQS5Ip+Ils6JWyYhjA/gA4bGo84MIgIIASJoCAISFFg65zbmffnXL+h7mqfTIQ07Sw5aGgwIkfitsQYQkf3q/gIiQH2GRzn1SMrZxRTUH5vpiEgbWK/5yvIYznTnsyuknl2gHCWPGCipkO19qu96Eq0dLtms4v7trjuiDIdPlabgfA8iaAgCEhTF7RIuUR/5196phv10I8Ya6xOdNBoMCJH4rbEGEIS38ZMDIkDLvIdfOQTjWSS4z6lH21BcjrCznfqFhJ5AuijLx4kLQ3+pEt32B9YNuEYCfOrSOFYZN0JvaCF0cmDX3LxF3GsHImgIAhIUNRlVauhMXcvPb9rwX7ZE5A/5PDcaDAiR+K2xBhDg676pAyJAE2slGDkG3y1F70Y81cEVeDOEdiPJ1jkzUf7BEvrwyJto8OK15w+hOF8v04T2tGsB7pSRhy6wrM2KEvB6guMMBCJoCAISFB+toU3uhDtzPs1d4udFUq0jSlRRGgwIkfitsQYQmqHCggMiQPk9icyLp60tvsTLVulmYyiDvLbO6sFBTPnP52LWduqKnmubov6fwMmBxb1ZhXsyPfPLe1i5fPQHlNRt9SeeLAIiAggBImgIAhIULTh9leE/aB0zEi5Edfm338Kmj2QaDAiR+K2xBhDNjreeAyJAwsrqoe83ofx/XhwnrqLhaP2LN98ECPR4S0CXjWN6ezGPIb3pOfEH30cle9YgC/hVmZK55FTjo4fATSuhn0vDCiJoCAISFD/3GfFmS+6T1IK0gGd8A6R+wLZDGgwIkfitsQYQkeTfigMiQKGCvps5XA+NBL+9glj9q2cFFmcWZ8+0Zx8TI3Dex/sl/Q39dk7hl1ElXVRA0QkEUZ+lx/EWB1C5Ggn8MHW9PAUiaAgCEhTAKsunZTrDeCdQtT0DpnLhkfADYRoMCJH4rbEGEImqupkDIkAnE5483h/gsg0Yodeta/QOEwtCSfdHxOXofWG/Cat3BLf863+LO301PAz4xL7lN1xyZqx6pCZUe5v/eazK8MkIImgIAhIUN3FMTaQHydE82kJKrnjDsoUVoVwaDAiR+K2xBhCcttSSAyJABuHsaev50ZnJTGYrTIv/MTDZn11WhLufhTZCRPCiUbXKzyOwNXhdj5Dl6HWpaH8Gur39aEqlTGdBsFDe5lqdByJoCAISFAYUCIxB5qhftb80RVKlEg5aATn8GgwIkfitsQYQir3whAMiQPSpQhOxGb0jUABTxjlQqje+KBMzH6NwYQopQBw97lCVOafRYIy5QbWrLGNRVEYXOjhJeEqrUvqsWQRMeSugnwYiAggBImgIAhIUQUb9ehq4uGG3AYl4vNE9LR+mPr4aDAiR+K2xBhCZjridAyJAN55r83NUF640JsM73DT1hE7eayr3gJyH+Ii5jVV4tkYH2ZJF9QxnP73jMel710ssLbssm3oj29FshvkiKJzHCSJoCAISFIAUuiEu04hZdRDQZCWPXjCqMNWRGgwIkfitsQYQlpWEgwMiQOplHVvxP3O0nFzBw3mBY2UTB3SmKohmWsA9qCtqeCF+fVhsTp6eb0cthLeaK2eLyUu6Os2+x7a1i9CmhB17igsiaAgCEhQ3P4bLN1Wh3njMadPl961ddhW4XRoMCJH4rbEGENWftLQDIkC66fMAXc7xbGjZ4abn1n3qzVm/HeVk4iSInzjf1fBpz+h+Paia2T/awiUw4HF4cLDGB/fIxl+S5mM3TO0Ih60DImgIAhIUIrpZrCkYr6TBtW0+b4YIPkcM2MsaDAiR+K2xBhDuhriuAyJA/uygHor9em6k1TlHLE3LoxQknXO2BqNGlGb1XATn1jhrmdKy92DREckrI02aEUv0Jm2tz1z22jroI+gguPvSAyJoCAISFHNkvmzHtuQEvRwgUMy2p0cnhuO2GgwIkfitsQYQuvuMnAMiQJaoWgUKwe9OzZmyatFonPfMwR53V9OzA7GeNdjtTa8E9cogA+tOMnk7vUpLIXa6ukk6Au7EhiiUVbfOPFxJHwciaAgCEhSXKmhPNkzOMUabN6nUOZhRFetaQBoMCJH4rbEGEJ2ahYQDIkAD5ClntYbPeupErQXrgvf1VRj5UdW8L6yID24Fm+u4yAeWfQKTDkhXHdsCdv7+QQ55M1OpkTjx4ERc+OnkhPICIgIIASJoCAISFC+J19PR4UePiO862KrXaogYn2EkGgwIkfitsQYQ0s3ooAMiQEk+GGnGfwps27AzaSkIi3mHkhA5yBD72+aOfzOUUgyfd7XPLKjwPnNYQsUmIjJtRpbWqcJZ7447JINTeKmfhQMiAggBIgIIASICCAEiaAgCEhQt1tIpae58LKH4tCjROomVwEMETBoMCJH4rbEGELTw6ccDIkBeT6mVXXvfsdAaoIMDohTJb3c2lNDNwIh+TPT1xFTFd1gTYOz5MggY7ug1qigFNByBhZT8ubi823Q1zhexDAcIImgIAhIUlJZTWo8pRb22BXIBXS1vchq2/tkaDAiR+K2xBhDSwqmHAyJAqn/8iKcxm/qrQe9FhrotfYACGO+1Yqz2N8+Qt4zNKM9mwZ1pio/2JNtJUzttWM8dOaYfsjeBIJuI9zHJbxSECyICCAEiaAgCEhSxUGnkGxpg/wOujY90H3jHsRRPvhoMCJH4rbEGEMzk9f4CIkCtQWicwCM3hFfhLke95XgyzPcutusAtZQVEAW1zWpC9IxNmMRQuBVNelQ311UeZtIppTR+Il4xdPCcfrXfQ2IGImgIAhIU0MIHHW8v7wIdvT9fH3LxvzCkZ7kaDAiR+K2xBhC30Z7yAiJAswnFjSr9mNoUqSf0XkRA/L2FuA53HscTIW398Riny9FcbmOw1MOXgR+CwsW7gnr9NuO/r5o515ymFI3uKBSWASJoCAISFF1WT4RNQRaUsTGxxKT9OziUlPSPGgwIkfitsQYQoKu5qAMiQGTLwIHAz6mzEBnWEUcyqPTmpGVJYhWVOWoZMW4FcX91KrAR1T9PKeV2Yb0Z8ACXNYCDldh/tz1BpIezA0OJ2QUiaAgCEhQZHolqEcCnepapmr7phqKkA1XARBoMCJH4rbEGEMiUz/sCIkBBhEjDglVacLgRKlSvOoUhuFR//Brq0fMbG7bUDW6GaJ6bONJOWfcE1BXFQ292hQaOLfNwy55bkMWGbDpURs4JImgIAhIUR8iWIfR7p/8jYsGy+XpPYxG2RvkaDAiR+K2xBhC75cPVAyJAj4n0GZk18StDB3aKio4b6lAEjVB592paYnUwBhPTGSP4wQ63peL9N0dis8Vv3Pu+O1FyAZr/6xLggXzpdD37BiJoCAISFPDItq3a98xOzlcIZgepoMfqYnXgGgwIkfitsQYQo+aJqAMiQN/bVagDrHzqVE/v4hMhy1QpFE+bs7wRoQgtso78y1X62XBk1Vt6NAFoZdQisJiFRN4GRQ/SlzdpPjjXDyP/pwoiaAgCEhQgZYv0DtSO0BotCHx/94dPIaVjMxoMCJH4rbEGELOtrY4DIkBFv1wuCjF7GFK3QKV9cmIguv3sypU0Zsu3i26lizVHXW9ByI26u+ffEmxCFiJaGjd15PKWf5lNqn7dEHaGzMcNImgIAhIUIzVGWye5VIMTqvRlIXeH/Y5hE9MaDAiR+K2xBhCM3ebyAiJAATm5N+/FDNVj29gBEhHhsT+ker4Xb0g7Og7/tPx1dxB/JU2E8hQjpbstC6t4RiMNuaZlK1EkJRApJLUdx+X1AhKATAo/ChTLWmO5Ho9O6NuTWULL4lckY2R54BIiCiDo3PT1gYfPBbGNzMbQiErgi/SpjYhxfQ//kqK29FdNRximv5sKCj8KFB9ySfQYuQcUv1J5cza3cbWtRnUzEiIKILH9OxZ6SAPXeBD2dReYIdKKXGyYgerulsxh2e6quhVjGJ69kgoKPwoU4I+6D+mZcH0UlrqrdD6rJ3hNwcUSIgog3g5KC6fJ2YYRoN583mKdstLi5egwt2CkyR0yiWIRlQwYiICOCAo/ChR2VVAijPMJvdM/P152g1C6PWnDsRIiCiBW3JzdEDJR/29aFDlGWxB1pA0Uu3bZkVjG9IdTp3QgpxilyOIGCj8KFEDMcjMUtuu5O0n72dMw7si0ZByrEiIKIAYJ3v/Gt6lCXyy+Fmb1ShR2OhZblRJac5hu1wqgRmkAGLjgvAYKPwoUnQKBeGhy07vlPFj77KEY2G+oIXcSIgogdfTEd6+krWYzqsBcpqdxySq+iwh7SGcwnBO8XaW2qKYYzPPjBQo/ChTYI0P81adJacC0hFfXDo1V2Pa4ARIiCiB/xOMXaWTfS0wayMUr8XsuC+PPbh3eGHES66FHKcQ9WxjqzegDCj8KFGa2lmbr93bn68vhl6ukZqcS4nB2EiIKIMAduUrS8W85g9Lk4hYh+sckmXdB9d5MmpzVL75VKWt+GKzHpQMKPwoUoW5IBSTWNrLaKtGEgzJ8LhCl6KASIgogYd2RYHyC0I3G34ZMld5rs94e4S5L1TnWaBDaDIhhpSgYss6bAwo/ChRysUie+1emgFd6g4pbquvhYqfIAhIiCiBw1FSs63gjmslywBWFQ6IG84thFIXHh2yjbZtxQSG2chiC3oADCj8KFFHX0FplkgimV2GQrrvo8HYDhRUVEiIKIGLrHsyvQP4r1XmEJfQDtNMe2kuJxZMRG4p8GR4bIFT4GNWm4gIKPwoUGwArbr64ZTxyEwGxtWRysbTeckcSIgoggalx4JN7FbjF2scxKj0u7h1pwNQ/NyPu96rhIermC6sY47bUAgo/ChTSS3oyQTM4wqom/AAW2R++c7terhIiCiCnu+wCaEAqUqPsw5gTHke3Q3TAa5rQ6fflbNburd4WHhiFlswCCj8KFHHfjZh5wgVjpOKr7alc0fxX2/aqEiIKIAwiYfdTqofT++oGAu9aRUs3dHMZ76kQ8mevzyxWX4CxGODwtgIKPwoUEx/HnnoBLZ5+7yHeO6XVAz/NvB8SIgogjd4Dwn3GrqBTcwNpuXaOmge1gNyja9SmYZso6e8xAHAY4cuvAgo/ChQ5MnaSwlileXDvU/CqTTwA+VmIuBIiCiBVmDqFINGRp4RqxP0G5i/9o1DXRGgsx5MTB6K3IpU2vxio2o8CCj8KFHNB6XC5s+/4KyBg00afxQ168EFGEiIKIDv7BuuH5jvf650X5CXwmQzZuymN4nkTPLwlOYQnclM1GKmQiQIKPwoUA8AWq37DLZ+Nd6/bGR+/U+oI2RcSIgogOdVpTfLCvPyBLeE6jNxesgy3Hg1IiA+165lSusZDgLsY3fj6AQo/ChQgIv6MxJ5IYwx2Fg4RqIBFkhnSRBIiCiCerr6gMFdhIoshHa+Sw54Yz2JVPf5G0jJYBYRSpw6g7hiL0PkBCj8KFJ58rgCe//TRY/P7h4GgeyXCsQsyEiIKIJv5+0tWTvpFLSO/sYAhp5JaOYl4DHSPUL4n9lXLx2I4GPT+9gEKPwoUmQY7kZQEtpUKeaajHjcDeP4HAg0SIgogT1wp5ELzvqVOqBm6eGYiQQWe0TaC2LV2BThHaVxh/rkY5/n1AQo/ChQWoWmVGoeCR9viWP3ccWOPZgbRVhIiCiBvvvMKH9WxGBW98Ze5bh0H4OGDg+sxZYELkbYr+oWCJRik9+8BCj8KFHaKgnAOMEbm2vhJZkV55klZfMG0EiIKIDbt2AC5lX+5L0V2wgsZYsHDx5g/L5kTK/UN/ZWyuNcOGLz87gEKPwoUBMg6og91Y7vLz2qhUO9rDIGAjaoSIgog95HMDW5006ssh50NO61qSXj94ZqRXGe1Ta78qy7u6Z0YoencAQo/ChR+2wBlImEMWCg+MGRKFPJ7zA0y7RIiCiDPNlZkClEJoJfVgjNlADFwdHklf6v/NYm/+dPuZ6Ti3Rj1sNoBCj8KFKBrW2grQlrSBqNcryRv1w3QmOUGEiIKINNFRrmRQHnp5/2X/K2KjaMMlJ08z6N83LvyyqbRiJx1GM+I0wEKPwoUl6/kU5W3TnhMiNReXMoplQGfrggSIgogZH2TWvk7bd8MLjDHLItvOJUv+ElgfItJO4V4XnXedVwY393OAQo/ChRiOaSYwi3z7D+wyi+W0VU19vM4ehIiCiD+TtfxgQ4Tce1EL3Uar2taHcp12TaWzmDJ5ROFmOrgOhiG98wBCj8KFF+ZmkviVIaZJafy/qBNezuDbP8LEiIKIBT6WWJWl9Z43GTV0vltKQJt2rj6qDkOnnKGWHxFAXeVGLLgxAEKPwoU8/Vdoku0faYLD7cewanJJ0vO7bISIgogjjcSFNFQ8q+t/xHr1uYdI2/c1sPwAD17uKg+AyOWTe4Y68fDAQo/ChScvsjL1O06rUuysDRu/IamxB+RYBIiCiBvzgXGhobiT0gpBg2nOofXqcIDfnOYC6auG1I8m8whxxjLirsBCj8KFK8ZWUPkT+HWJQB2uLwZEOq8hfHyEiIKII+DIetJnPW/PB+LgjqZjkOI2JMwW1+NcfgD/ghVptzbGM/dugEKPwoU2812XbJkBjGUbBOTuiVYdsdto44SIgogUN3akx4LNxT6+vVjf02dzkYb5nPp2Xb1iB9VBisxHegYlpK4AQo/ChRpEuC6OM0AyfL8nnHpceztUHtC/RIiCiCjUC5feam4dOzobPgGhTxH0mPTzPv+MnrJVWipzZUUkBirpLcBCj8KFIsdVnb0wMhxoMeGSFDUUdaorI47EiIKILamh0ZNcJLqhzI3zepA0tcplOVWQwtVy5hTRSEZLaN6GLWztgEKPwoUQMSIOc1IfYoT1llVt/xsT1YNj3ISIgogu6iZIVGM1il2+eaishuCM1gOjJMJlM6mPL5trWWsbaoYzM21AQo/ChSOBUWxIi57XIXOae3HjygMsredGBIiCiC9g1NlbEqF7dSfqAX6pfpxUHej8obhjEwLj8iBFMrTPhjQs6wBCj8KFMAvUx2bu6SQdRHvJoBCHOcUoR47EiIKICPbH0qbbH58BDiGPH0U9xnswIjrOx/Ip/5gdJZEf6xOGLPuqwEKPwoUsLNf7UDapf+dS8aFx1klGH9iIRkSIgogw/cYALnzUUHfP0Ej/N0GcWk8Kl6q5+CnIqxbrX4A2vkYprurAQo/ChQTj9mrer4LrtFMp9QdiFt4BSpKoRIiCiCaZhCbacCetQorko3LfUUJX2UEyX38qBGVri8GyH8lcBjrgKsBCj8KFCc/cu5VmHr6dxsn03D6Ex9gi4OsEiIKIBj5a3Sec/xG121CnN8SHEJ/izlNVGheJMpOwn73qYSYGPzEqAEKPwoUlbAC3mdwcxPRI9BkkvGnpYR45UYSIgogPA+RvSpVTcAWBD/+nxXltHLaOdaUzbrpNGfjMak/usUY3r6gAQo/ChT5qWikBfsEKUEK5RZeXyGTJx5nihIiCiDBaK5BHoJirZLfWiC+sOtgPyIjdXVyEgsnrGJ74mtEnxj9u50BCj8KFF6AnpHqtp04V4TRkRQOnIz23RA3EiIKICwgreAgUq5A70gx1jAe73qWGeLMKKtQNKzqZkTOPmOnGIeRnQEKPwoUfvJEhowwSqWzSIk3Li34dK/WNc0SIgogAmRwY/dqPSBXDY/YO/huPokiInnsXm0h+wM4ORwQivYYy7qcAQo/ChThkeZU0GufchVou5RbLrUd3ByP3BIiCiBIiKcJ/gYqa6obW7TURkLL481j9/7yxCM/DKcbZqSSDxjGpZoBCj8KFH4O12ibZcNF0cgXxbAzL9Ey3lh1EiIKIEXxDI/gQIoPPmCI8CJarhlgO1UTtQjH4oJ+j7cBHLepGM20mAEKPwoUn47C71gc4lYwyBnxm1SEA550jRoSIgogd2hzX/3wrmjtrb+jAKUUvO95VeejdRoxTHdQY7/8gLoY8pmWAQo/ChTKDypxIfhtO22RNJcwFVuaWjHFVBIiCiBAtOAIQjLTOfZ/nX1Powe9qIr37naxBOPOydPDn3Xp0Rjzk5UBCj8KFJZv2JsdtRU18tiYz5sPFNo3TvuWEiIKIEZXWKWEAo9ugHmaurR+rgtMkqfbzGK8CLiaMMlolWk4GM/GkAEKPwoUdvcGrnOoJRZSvHLLgB5ClOITWvsSIgogvNya6ReeIsgTR3h7cNq0uDwIX9Zcn4Sx/ZAFQW9oS7UYnqeQAQo/ChQG9Fw2/LlX5V2SOm1OkFwtcVEVrRIiCiAs5RoNNLRhlLvQeMHCv0BF6tcxdtfEU+xLFDju42YC8BjYjZABCj8KFOEs7zhxuVle8VQB7tJGbpMQ5IFrEiIKIAt52JfhSwHW5E5K7z/DoYHclEB+A6SA+aU9u6Eo/F5aGOuojAEKPwoUfVPXby24a+MKmybK3qaQeFMaubsSIgogQuejs9DfnCsgGElTXxULslAU06c4bzyrxDSTtDZ6VO8Ygq+KAQo/ChQg7+GG2pGgCsfwQs1stqHogsWDxxIiCiD8mfpRfRBVZU6q4SDlFZTEyRRHxD11HJzuCSa/3YMElBiclIcBCj8KFM7+fWVLUj3qKp7XGKWREmx0FxaJEiIKICRQQ6O7PzZVp6COoW8uGsqrLUs7Ig/E+imm8VUw2VM9GIKbhgEKPwoU2KbFTFSiNtSEO6VmUgugP2DwnjUSIgog8YRkE4YdrBPXVK9hgiLYKbrgnNUYJsGGfc8Kd/tOWuoYlaaEAQo/ChQXOGswjvlnDN1BL7LzwJxbh1+4uBIiCiBe9gw8N9+8eGUHIf5PaYoIRdzMpnQWhRBY+2i7RDjX5RjTgYABCj4KFOA7mF5siQXhhNiMmVzGMqoniYHrEiIKICQPgYSN54nvbUfpUQg2958mQetLW4R14ezDVqU2qybiGJ+Ofwo+ChTJ5hUonR2S5QKSw7C9g1jZsuQCkBIiCiCBa3qr7zYtHacxYejuTarksYuxfO5kZqNlBUXKqTPKBhjfo3sKPgoU9sP3hysEbacZiQXmy1jBt3W0i+oSIgogR4DgU+pyHuF07Toy3N7lsDNCoL5YggyOEw830AwXBWAYo+N4Cj4KFAREbaC8xDEAA/l7G+0Hqyq+xv6nEiIKIDCj0fbkgWMbgrMASE6hrtDFA8fzQXdjyj5DsmamUwmxGMTtdwo+ChRG3qE3z7ELxBmyV3qppYcYaA4YuhIiCiAkwXWbMbx+PRrSBKW+r20/VoMvtmdxNaX+rsuiujK1Gxis5HUKPgoU8ZTdSorYMyPD6cKpPbJfBJYhx7QSIgogoboi39aVwyap22GNEnO/xV39Kvv+/njYlKzqXDHQ/u4Yo6t1Cj4KFGkhdLP/u6gDlKlNySZl3AFE+6g3EiIKIPonBlFXsmzWmHON4jQy9Ir3Jpvbff4lotv9QHOBda3FGMOWcwo+ChSERc9Vy1EnjmOyExrbZagdwjidjhIiCiD3klqMklR7/l0zIVE4dAalvFto7ACER9DdLLw7k0vmZxif8G8KPgoUY0gfbcqvcz0vyVOjNcIgDuGQhiwSIgogZ3A0fCkaKR09vvDT7x18I2IczxvVpezksPpsYyK1n2YY7t9tCj4KFCcSz2ivaYK0vXU2uUzdDRBKAxP0EiIKIOCAmp2vELwhLgHF5vzt+Sq+kxREFkIT+ilNbwsjpueIGOzNawo+ChRxK8iRrrch2nJzK8MNUx4MHq7a4BIiCiCiS2ONlxaft52PHXhuVY7tXWaGEKSC8F6BfNdYP2z1oBibyGsKPgoUvU+A8MGme0lQdyZi9uvK1YoliTMSIgogQxPhzXFD/heBVTak80mb3g0cAN4fo3iIAfGhzW3KtksYmdVpCj4KFGijk8ftSWhxFQwKfK0MrAm45Fj7EiIKIG1NZt2g0MMSKahWLm42SIUr2AomtTEEn02mlyQYN/J8GK+yaAo+ChSUNUfKyynFV5fhIay05YbEnZ05/RIiCiD5Yp825uigKkR0kT3dr6Qox+f9iMmGL0MHlplk1L12nhiUxmQKPgoUX+zslAiicQgz8vfYSDOUYsKcFEQSIgogCSSFpeTmF3bi6Q4GHTnUZ907ghHTQzr23gm/BH439AEY7YBjCj4KFNW5MZB3GlBgSl94SarwZ8Sp2q+cEiIKIPqLB8AQf6kvayw8bymUgVgY6I6HCRn3xa9EFHtEJu1ZGJqJYQo+ChSEQpBTHuWbQP7v3lJZhXNov3EZ7BIiCiA4+xme9PLdL3SsDyS/YVAQqYWKBOfmEd0CinSo1mA1Nxir7mAKPgoUThVMkojjFDa6gU3ZLRfE7Wzv0/ESIgogd0bdUFPpo0HhlikzHJURLoIXvUiUEvO28q4IncjPy9UY7uJgCj4KFApwkS0Y4T14yzLmMipOV/hh5sPIEiIKIAamrL2XxN4Tw7J/aD/oALQokjOb666HGWyZWvJ2oagFGKqpXwo+ChToDR9VGaWzydKQ0+oxT6BVZFNcGhIiCiBsOdTHnU4KUxoGO3KcTdEuYJvSaU+WRpYtVkMGasLVRxiP+l0KPgoUtcM6QJpYnAlOifd9JBOfJcam3ukSIgog+rf+Ky6Edfpk5kqdNuv3+nn7moWmbRFCVwLgMwMSR1UY56lcCj4KFGnQYFIpxmWXTrtzb8d+FiRcP3mqEiIKIPrmOwiwtVo9ev2kedL8Ny3CW8CJdvxf86K21CISqivxGLGAXAo+ChR/wdpAslaN29U8/zt2xJzomuKGgBIiCiDlvRV8yRcjVgSi2pn8C+1PxM7C6ifv5GCAovhnpvZtmBjx8FoKPgoU2krxmjeMCbVMJsNGfLCt+IkpKVQSIgogdOk2pUzVZHq8JDdyNLOyHH9k+ry/Xvxl7d/vZivYE0IY7JdXCj4KFD6I58VPZGQqmLLh3dW9ukh5TwbHEiIKIHribm3cKdFjY1/cT1UWHDGgT3dDQj/ZiijHFFbT4akJGLCPUwo+ChQsJGcYC7qE8vHUVl5m9WWjQAPuTxIiCiC13s+M4Zypr1iulp43zHuDrv35OX+BaKGREkYYvCQfXRi/9VEKPgoU5cuhmeBF5wNnEdgU5X4rZsPMA5ESIgogU9J4uq5i6zKKHkReUKsMetJSvyCNrCaqLICyIoqXUEwYsr9KCj4KFIlMVtbPw6jgnrbRouM0Z8TPd8D1EiIKIIhkNZwYCHmwopZwkMK6n/ZMyr6AMQ8wMn9Y/wR0vG8/GKm9Rwo+ChTIlpFx+bWjNUxxKiDwB83gZIyZDxIiCiCt9C368Anghf6SkBoEAOsXksk+PelMFqwskvh8r8qMLBi8wkYKPgoUnL8u/9VXCzqaQTRiRHV82j4Y1AESIgogPwTrMSmKul2l8xfN3RmAryyVv2+PvwG9XpZxf4Vc4uMY3IpGCj4KFNTEHB4X6TIdBnuk4+R252aywsK9EiIKIEqPagoZmehF3b/Sv1dVnLi6h4Yz3Z2Gkd1refX6Ai/cGL6IRgo+ChQm93d71SkYrnGAECKw4t7tl93VBBIiCiDNihzHB5qZmboY4Tg0xn5XNo+l4Z2hIiyQgDhAej7+gRjn3D4KPgoU8jPgNiSKNvxzwVT/p5JhvL3Eu3YSIgoguqhpfK4aZ8MaTC8ZxD4xhgcgXDCnko4ed6zEdz7jDesYo/09Cj4KFBX+wQQW41nMHdtCTGkWayZx8lFIEiIKIDoySTPpQj6OfJTVg4BA6mhOipqiBFxo+Jp9Qf3wJZlHGOqYPAo+ChQACllZY0tCluTeU2SB3gCooOuaWBIiCiBdgK+F1w6Wb/mDWAdI77v+EC4JDSRk9Ttcq9zULl7VThi4gjgKPgoUS2UlWFfkOTdU8Enb6UXFrIf1Y9gSIgog2VCm4fclLlyltKmcYuJZE6+UgZ+HtL1uhaxnRittXBQYsdM3Cj4KFGCkM9KLCHiMcuITNVS9XMaHadzsEiIKIB6N+HKiEcQ7tvIqHOuP1biHm3ynkt5nI78wZfpsQmbxGK62Ngo+ChQGqjS9bR3TQRnj3Bc++tlPQwq3ThIiCiC5VlA3OmGUxZ4YRW9KJsq1f008J3Zpyq+lMLbFAjtNzxj+mTYKPgoUybdT7Sl+X5iU1KQxSc/J97IHtrISIgogQEpXxUDaunv2wmnaQ1Qw0zYS/zHCOa3wJIImSInhjawYy8Q1Cj4KFD/2yYh5nBrfOsoNpWFDyBY4kIWaEiIKIJd2lnpYn+KksJ8Xd/D3MbzgfRfKKHeKASMcEI3Cm/6IGJKnMwo+ChSZk4SVQHwJs0NWKq7Dq1UaXCRiMhIiCiAS8xrqw+kQlDPxupqUYwRI68MqrZhhc+j36Jveqr6bPxjFmDMKPgoUkB/RIsxRLvE96OGj15U7/dwHhtYSIgogXgIu1lX318LSJylroCLzRjAliJoOI+nye7r3vG8S7FcY450xCj4KFPZ4PY+zDigwgcFjmCk/SC3KDpEtEiIKINnLlalCG8tOe8WfJ3b6LApN37qL8waCRizMge+CbGTYGIyqMAo+ChSpxODirwAYPaEUNO1BMhmQXpqGjRIiCiC1eeaFQxwjJshv1bObHm2IsPjGiMZBzmKts5w1v9FOGhjmhTAKPgoUGewKFVpb51XnbQBZ73MOvKEitPESIgogeaz4NzeK6vuV3LPFcA4Z3UIUWHwGSA6nSNfKgz0xHX8Yo80vCj4KFDdJCGtthb3j2s++RIXj35XnCbbbEiIKINf/6eM//cCb+uqvVwWXXwK3YkN/JuC9hxaH7NvaxuPxGMCULgo+ChTgba3rQTgpVY98lTOf+2FJnFobuRIiCiB3eo2TY1zkPNqlFE80n/92NvpQnxxGUlG1jF7jxCVb6BjZ/i0KPgoULRWbctQMHB2t3yTSURIAABt07YQSIgogcWOywd6/utG67FuJjTyXn8ou1dIBNZtaqSKbH62WghsY8J8tCj4KFAzrkX3k3xxLT47fxKzm/W058eYeEiIKINV44Bor8wT4ZgVYAdTiBaZ+8wq8HE2GnpsrvIMZQSTQGNWwKwo+ChSW2jddiik/j2WA2jbqI3bNiasgxBIiCiAwGXNg6W6vX5tUZNd3q24d4bEtrb+FnmErxiBMksYXExi3jysKPgoUzkhVF2SeT4xxRp732vz5pVi/Fn8SIgogTWhrgLe+T+LFELUqUHzcvmFoRUy+A+NL1ZvKIGdc1NUYjYErCj4KFGgnXDfP+Gu1PSnWI3rTcOj9UJf8EiIKIFGr9XYEIjoULgl7XEG0NBndNiEVAYkw9ZjoBwhq+u8RGNS8KAo+ChTiOvzwA1+wGs0C/pb2gAZpdNcHKxIiCiDWAdD6UzjWvNWGrG/Ar+CW0gx0iIDYrOsq7tEmtjmvtBi30ycKPgoU4kLbLLkp1vRKGi/khcx9P2IP+usSIgogs5PS5N/ichjOxyDowRowgjqZChE3Q/qEweTIK3Sn/X4Yuc0nCj4KFG5wVCQjHc7sM360UbxMHSxfukjJEiIKILw5ELeO8jh38QF19SUwlNnH/B+uDJneUU1sRiNtoQQSGLD8JQo+ChRBtUPpFHmpXNXKnxCcJt+sFJEm+hIiCiALzy6lu17jrynpWdRjEVK1W6BpX4XOLoLdhyQriXCmAhiQsyMKPgoUfFqoflIDxm6jXGQmL1du3Sm62YASIgogYzA8yyHSvymqCplrh0r50T1DRhlNscmxK38Q4T0U4oIY36AjCj4KFEUazsqn3EzObgt83gL0Vd+XNTXlEiIKINuqjnYsvZPC4FpCBeqwzqoLBZe8tP6i4DZ/jUP0GFZYGJbYIQo+ChSRJ9+mF1DdHVbLHSqI+IMaKz+bDhIiCiAitDYT66vuDGGTvv+BrEfEPQM/IhFZbTYiC6jnsf/dnBj3/yAKPgoUWDrnNuZ9+dcv6Huap9MhDTtLDloSIgogQ+OdeY346jm7jDLQxXBm+6eUZb8MDSmniOR8dVq53yYYqO8fCj4KFMXtEi5RH/nX3qmG/XQjxhrrE500EiIKIORtbDu7EBIIBKTUzqFUxgI5BOu1uZi+8NPrufZXk3drGPfNHgo+ChQ1GVVq6Exdy89v2vBftkTkD/k8NxIiCiCGbrpxpV8tUcPAyhdg3ktqvQvHu3ns6erpynfURqPc6hifpx4KPgoUH62hTe6EO3M+zV3i50VSrSNKVFESIgogTYPVhAi4+57tjTnNwjtKruQDZR6znYbSjSgsJ0UgsRcYpaUdCj4KFBVxA4taqrQx7AEfarEJRGPG7ZhCEiIKIPA/MF5DGfXf6fOrDsSM7P1L9zDGMnq9QDI+lJzinXFtGIC7HAo+ChQtOH2V4T9oHTMSLkR1+bffwqaPZBIiCiDhfTk6TI4/VAoKJMV9mwhBMeLuheqJT0W039uJumcKthjp5BsKPgoUP/cZ8WZL7pPUgrSAZ3wDpH7AtkMSIgoggJvkPLiHo2+12JJGprhwVsABASXzXO/dSWtnk0ywNB4Ylq4bCj4KFMAqy6dlOsN4J1C1PQOmcuGR8ANhEiIKIBxt6nIOMqgs5QRuTamLWWkSrVaeVinMZxE0Ga9BkyZmGJSJGgo+ChQ3cUxNpAfJ0TzaQkqueMOyhRWhXBIiCiDzHAwRAMjjGgPZnfTR/y+mNviRthBW53ntGBaGWu0G0xj07RkKPgoUBhQIjEHmqF+1vzRFUqUSDloBOfwSIgogwwsbQ6mkEweZt2ZhPannQap/Fim1sDviGOdQpa0gyA8YsP4YCj4KFM3AGIInRwJL6v0QpFq+zHrBnLqwEiIKIOUgNYRH+Pq8uZ+6jlo8aze3AUX8G/UqsD5m8CMxJAF5GPfdGAo+ChRBRv16Gri4YbcBiXi80T0tH6Y+vhIiCiCuqzPc9rn8BukK5AQlSX+aHqjPYH+ZuSck7F1VN4CRQxis2hcKPgoUgBS6IS7TiFl1ENBkJY9eMKow1ZESIgogxP04sdg7xwZqPpOYaoTIjOhCgQjXK5adgghQLpkP6MMYhNIXCj4KFDc/hss3VaHeeMxp0+X3rV12FbhdEiIKIGDKIAZKsa0rTpo3SrkDn1KW1IPTgu0rDk5qoEtWYyVtGPi5Fwo+ChQiulmsKRivpMG1bT5vhgg+RwzYyxIiCiBvYNU0EusgVeRDX1ZeZvOVQqH6xCsFpJjWzyFI+QUUxhj70RYKPgoUc2S+bMe25AS9HCBQzLanRyeG47YSIgogVlyhe1RD0MI9OENbbN2yjmTTtVJgSYYZOiSNC+k0JuUY6P8VCj4KFJcqaE82TM4xRps3qdQ5mFEV61pAEiIKIAPzZT8WA8yN3IDWZJfFUmB1wXvdAQr9ZoKneV/PHmGNGLnKFQo+ChTiAARRUxGyBWGPrVBPtSmj3u4ucRIiCiCibEZcfzl2SYZ6xDkbBDLRgpnqq+b7/Z7x/GhqGUqitBj5kxUKPgoUL4nX09HhR4+I7zrYqtdqiBifYSQSIgognCD7wpBgaHm5CTMvsWro4W9ODmvzvLzphYoIAmSW5R8Y+sMTCj4KFNgHpVx9aahPt1n7C9lrtNpQrbonEiIKID5a9faluQgurahpvhXKrpHaklLcUbUlcJlVSwtTgrhtGLm9Ewo+ChR+Ee190G+uewvttGlyEVHy8xy7ahIiCiBMdpwGNSXwTH1jYWuUoyuPmhluir+xWlNYy1qbBRaWhBjRrhMKPgoU2pZWTSN5rO4A3Z+qVYaBu0mXV/0SIgoghZcBdfFQiz0C1EOkEPkqwC5fp781juBznOctvFAIs1IYgKgTCj4KFC3W0ilp7nwsofi0KNE6iZXAQwRMEiIKIHDNh1M2rti9w9tOtyyiOWBph3IWu/bub5kBVsiqNwP+GPKSEwo+ChSUllNajylFvbYFcgFdLW9yGrb+2RIiCiB4B4BQqc+8bFvqERDhXHNU77pla/KqfU6O3MGOrMErFBjz9xIKPgoUY00vXtfJ2C9CKY2JIjBNG0rbIPcSIgog2DGWcF3kuB0LZAzqB4Lg8bXADob7jUbjeweo++eteIYYu94SCj4KFLFQaeQbGmD/A66Nj3QfeMexFE++EiIKIFisYognB+hbHnGEe+DnPqNX9eGdv+6vpMybg9vcUS6pGMmfEgo+ChTQwgcdby/vAh29P18fcvG/MKRnuRIiCiB9hTJBtoUanw1de26j8TKidVDbWloa+tTIKQsNzUxutRjrvxEKPgoUXVZPhE1BFpSxMbHEpP07OJSU9I8SIgoguDxVypf6eEePXCtFB8v3GRKrXxGxLQqxqGO6ERBNi14YlpYRCj4KFBkeiWoRwKd6lqmavumGoqQDVcBEEiIKIIxt2Dj8y8RDpnwtsTfKsarRfgNSBi759fQIU74UpqK/GMDHEAo+ChRHyJYh9Hun/yNiwbL5ek9jEbZG+RIiCiDJfH6WB3qQNoyN/DO/XsMJj1ZpsgXHcLoe0hmNc+sHAxiEnxAKPgoU8Mi2rdr3zE7OVwhmB6mgx+pideASIgogJ8pHYf6n68tf77wVQrLJGwLU295p5grf4InmCZ7F6sMYz5AQCj4KFCBli/QO1I7QGi0IfH/3h08hpWMzEiIKIHH/lz5gILVzSvweBrs7xKSXYcGhRaNX5+vSj4Wj10DlGIGeDwo+ChQjNUZbJ7lUgxOq9GUhd4f9jmET0xIiCiCtg8zmzC3YMmYoWAju/QHO3/vJQhpRYX4urSG7qoX99xjEkg8SPgoUBERtoLzEMQAD+Xsb7QerKr7G/qcSIgogMKPR9uSBYxuCswBITqGu0MUDx/NBd2PKPkOyZqZTCbEYxO13GP+9nq8BGgcIARCz1aEHIoFMCj8KFMtaY7kej07o25NZQsviVyRjZHngEiIKIOjc9PWBh88FsY3MxtCISuCL9KmNiHF9D/+Sorb0V01HGKa/mwoKPwoUH3JJ9Bi5BxS/UnlzNrdxta1GdTMSIgogsf07FnpIA9d4EPZ1F5gh0opcbJiB6u6WzGHZ7qq6FWMYnr2SCgo/ChTgj7oP6ZlwfRSWuqt0PqsneE3BxRIiCiDeDkoLp8nZhhGg3nzeYp2y0uLl6DC3YKTJHTKJYhGVDBiIgI4ICj8KFHZVUCKM8wm90z8/XnaDULo9acOxEiIKIFbcnN0QMlH/b1oUOUZbEHWkDRS7dtmRWMb0h1OndCCnGKXI4gYKPwoUQMxyMxS267k7SfvZ0zDuyLRkHKsSIgogBgne/8a3qUJfLL4WZvVKFHY6FluVElpzmG7XCqBGaQAYuOC8Bgo/ChSdAoF4aHLTu+U8WPvsoRjYb6ghdxIiCiB19MR3r6StZjOqwFymp3HJKr6LCHtIZzCcE7xdpbaophjM8+MFCj8KFNgjQ/zVp0lpwLSEV9cOjVXY9rgBEiIKIH/E4xdpZN9LTBrIxSvxey4L489uHd4YcRLroUcpxD1bGOrN6AMKPwoUZraWZuv3dufry+GXq6RmpxLicHYSIgogwB25StLxbzmD0uTiFiH6xySZd0H13kyanNUvvlUpa34YrMelAwo/ChShbkgFJNY2stoq0YSDMnwuEKXooBIiCiBh3ZFgfILQjcbfhkyV3muz3h7hLkvVOdZoENoMiGGlKBiyzpsDCj8KFHKxSJ77V6aAV3qDiluq6+Fip8gCEiIKIHDUVKzreCOayXLAFYVDogbzi2EUhceHbKNtm3FBIbZyGILegAMKPwoUUdfQWmWSCKZXYZCuu+jwdgOFFRUSIgogYusezK9A/ivVeYQl9AO00x7aS4nFkxEbinwZHhsgVPgY1abiAgo/ChQbACtuvrhlPHITAbG1ZHKxtN5yRxIiCiCBqXHgk3sVuMXaxzEqPS7uHWnA1D83I+73quEh6uYLqxjjttQCCj8KFNJLejJBMzjCqib8ABbZH75zu16uEiIKIKe77AJoQCpSo+zDmBMeR7dDdMBrmtDp9+Vs1u6t3hYeGIWWzAIKPwoUcd+NmHnCBWOk4qvtqVzR/Ffb9qoSIgogDCJh91Oqh9P76gYC71pFSzd0cxnvqRDyZ6/PLFZfgLEY4PC2Ago/ChQTH8eeegEtnn7vId47pdUDP828HxIiCiCN3gPCfcauoFNzA2m5do6aB7WA3KNr1KZhmyjp7zEAcBjhy68CCj8KFDkydpLCWKV5cO9T8KpNPAD5WYi4EiIKIFWYOoUg0ZGnhGrE/QbmL/2jUNdEaCzHkxMHorcilTa/GKjajwIKPwoUc0HpcLmz7/grIGDTRp/FDXrwQUYSIgogO/sG64fmO9/rnRfkJfCZDNm7KY3ieRM8vCU5hCdyUzUYqZCJAgo/ChQDwBarfsMtn413r9sZH79T6gjZFxIiCiA51WlN8sK8/IEt4TqM3F6yDLceDUiID7XrmVK6xkOAuxjd+PoBCj8KFCAi/ozEnkhjDHYWDhGogEWSGdJEEiIKIJ6uvqAwV2EiiyEdr5LDnhjPYlU9/kbSMlgFhFKnDqDuGIvQ+QEKPwoUnnyuAJ7/9NFj8/uHgaB7JcKxCzISIgogm/n7S1ZO+kUtI7+xgCGnklo5iXgMdI9Qvif2VcvHYjgY9P72AQo/ChSZBjuRlAS2lQp5pqMeNwN4/gcCDRIiCiBPXCnkQvO+pU6oGbp4ZiJBBZ7RNoLYtXYFOEdpXGH+uRjn+fUBCj8KFBahaZUah4JH2+JY/dxxY49mBtFWEiIKIG++8wof1bEYFb3xl7luHQfg4YOD6zFlgQuRtiv6hYIlGKT37wEKPwoUdoqCcA4wRuba+ElmRXnmSVl8wbQSIgogNu3YALmVf7kvRXbCCxliwcPHmD8vmRMr9Q39lbK41w4Y9PzuAQo/ChQEyDqiD3Vju8vPaqFQ72sMgYCNqhIiCiD3kcwNbnTTqyyHnQ07rWpJeP3hmpFcZ7VNrvyrLu7pnRih6dwBCj8KFH7bAGUiYQxYKD4wZEoU8nvMDTLtEiIKIM82VmQKUQmgl9WCM2UAMXB0eSV/q/81ib/50+5npOLdGPWw2gEKPwoUoGtbaCtCWtIGo1yvJG/XDdCY5QYSIgog00VGuZFAeenn/Zf8rYqNowyUnTzPo3zcu/LKptGInHUYz4jTAQo/ChSXr+RTlbdOeEyI1F5cyimVAZ+uCBIiCiBkfZNa+Ttt3wwuMMcsi284lS/4SWB8i0k7hXhedd51XBjf3c4BCj8KFGI5pJjCLfPsP7DKL5bRVTX28zh6EiIKIP5O1/GBDhNx7UQvdRqva1odynXZNpbOYMnlE4WY6uA6GOL5zAEKPwoUX5maS+JUhpklp/L+oE17O4Ns/wsSIgogFPpZYlaX1njcZNXS+W0pAm3auPqoOQ6ecoZYfEUBd5UYsuDEAQo/ChTz9V2iS7R9pgsPtx7BqcknS87tshIiCiCONxIU0VDyr63/EevW5h0jb9zWw/AAPXu4qD4DI5ZN7hjrx8MBCj8KFJy+yMvU7TqtS7KwNG78hqbEH5FgEiIKIG/OBcaGhuJPSCkGDac6h9epwgN+c5gLpq4bUjybzCHHGMuKuwEKPwoUrxlZQ+RP4dYlAHa4vBkQ6ryF8fISIgogj4Mh60mc9b88H4uCOpmOQ4jYkzBbX41x+AP+CFWm3NsYz926AQo/ChTbzXZdsmQGMZRsE5O6JVh2x22jjhIiCiBQ3dqTHgs3FPr69WN/TZ3ORhvmc+nZdvWIH1UGKzEd6Bj8u7gBCj8KFGkS4Lo4zQDJ8vyecelx7O1Qe0L9EiIKIKNQLl95qbh07Ohs+AaFPEfSY9PM+/4yeslVaKnNlRSQGKuktwEKPwoUix1WdvTAyHGgx4ZIUNRR1qisjjsSIgogtqaHRk1wkuqHMjfN6kDS1ymU5VZDC1XLmFNFIRkto3oYtbO2AQo/ChRAxIg5zUh9ihPWWVW3/GxPVg2PchIiCiC7qJkhUYzWKXb55qKyG4IzWA6MkwmUzqY8vm2tZaxtqhjMzbUBCj8KFI4FRbEiLntchc5p7cePKAyyt50YEiIKIL2DU2VsSoXt1J+oBfql+nFQd6PyhuGMTAuPyIEUytM+GNCzrAEKPwoUwC9THZu7pJB1Ee8mgEIc5xShHjsSIgogI9sfSptsfnwEOIY8fRT3GezAiOs7H8in/mB0lkR/rE4Ys+6rAQo/ChSws1/tQNql/51LxoXHWSUYf2IhGRIiCiDD9xgAufNRQd8/QSP83QZxaTwqXqrn4KcirFutfgDa+Rimu6sBCj8KFBOP2at6vguu0Uyn1B2IW3gFKkqhEiIKIJpmEJtpwJ61CiuSjct9RQlfZQTJffyoEZWuLwbIfyVwGOuAqwEKPwoUJz9y7lWYevp3GyfTcPoTH2CLg6wSIgogGPlrdJ5z/EbXbUKc3xIcQn+LOU1UaF4kyk7CfvephJgY/MSoAQo/ChSVsALeZ3BzE9Ej0GSS8aelhHjlRhIiCiA8D5G9KlVNwBYEP/6fFeW0cto51pTNuuk0Z+MxqT+6xRjevqABCj8KFPmpaKQF+wQpQQrlFl5fIZMnHmeKEiIKIMForkEegmKtkt9aIL6w62A/IiN1dXISCyesYnvia0SfGP27nQEKPwoUXoCekeq2nThXhNGRFA6cjPbdEDcSIgogLCCt4CBSrkDvSDHWMB7vepYZ4swoq1A0rOpmRM4+Y6cYh5GdAQo/ChR+8kSGjDBKpbNIiTcuLfh0r9Y1zRIiCiACZHBj92o9IFcNj9g7+G4+iSIieexebSH7Azg5HBCK9hjLupwBCj8KFOGR5lTQa59yFWi7lFsutR3cHI/cEiIKIEiIpwn+BiprqhtbtNRGQsvjzWP3/vLEIz8MpxtmpJIPGMalmgEKPwoUfg7XaJtlw0XRyBfFsDMv0TLeWHUSIgogRfEMj+BAig8+YIjwIlquGWA7VRO1CMfign6PtwEct6kYzbSYAQo/ChSfjsLvWBziVjDIGfGbVIQDnnSNGhIiCiB3aHNf/fCuaO2tv6MApRS873lV56N1GjFMd1Bjv/yAuhjymZYBCj8KFMoPKnEh+G07bZE0lzAVW5paMcVUEiIKIEC04AhCMtM59n+dfU+jB72oivfudrEE487J08OfdenRGPOTlQEKPwoUlm/Ymx21FTXy2JjPmw8U2jdO+5YSIgogRldYpYQCj26AeZq6tH6uC0ySp9vMYrwIuJowyWiVaTgYz8aQAQo/ChR29wauc6glFlK8csuAHkKU4hNa+xIiCiC83JrpF54iyBNHeHtw2rS4PAhf1lyfhLH9kAVBb2hLtRiep5ABCj8KFAb0XDb8uVflXZI6bU6QXC1xURWtEiIKICzlGg00tGGUu9B4wcK/QEXq1zF218RT7EsUOO7jZgLwGNiNkAEKPwoU4SzvOHG5WV7xVAHu0kZukxDkgWsSIgogC3nYl+FLAdbkTkrvP8OhgdyUQH4DpID5pT27oSj8XloY66iMAQo/ChR9U9dvLbhr4wqbJsreppB4Uxq5uxIiCiBC56Oz0N+cKyAYSVNfFQuyUBTTpzhvPKvENJO0NnpU7xiCr4oBCj8KFCDv4YbakaAKx/BCzWy2oeiCxYPHEiIKIPyZ+lF9EFVlTqrhIOUVlMTJFEfEPXUcnO4JJr/dgwSUGJyUhwEKPwoUzv59ZUtSPeoqntcYpZESbHQXFokSIgogJFBDo7s/NlWnoI6hby4ayqstSzsiD8T6KabxVTDZUz0YgpuGAQo/ChTYpsVMVKI21IQ7pWZSC6A/YPCeNRIiCiDxhGQThh2sE9dUr2GCItgpuuCc1RgmwYZ9zwp3+05a6hiVpoQBCj8KFBc4azCO+WcM3UEvsvPAnFuHX7i4EiIKIF72DDw337x4ZQch/k9pighF3MymdBaFEFj7aLtEONflGNOBgAEKPgoU4DuYXmyJBeGE2IyZXMYyqieJgesSIgogJA+BhI3nie9tR+lRCDb3nyZB60tbhHXh7MNWpTarJuIYn45/Cj4KFMnmFSidHZLlApLDsL2DWNmy5AKQEiIKIIFreqvvNi0dpzFh6O5NquSxi7F87mRmo2UFRcqpM8oGGN+jewo+ChT2w/eHKwRtpxmJBebLWMG3dbSL6hIiCiBHgOBT6nIe4XTtOjLc3uWwM0KgvliCDI4TDzfQDBcFYBij43gKPgoUBERtoLzEMQAD+Xsb7QerKr7G/qcSIgogMKPR9uSBYxuCswBITqGu0MUDx/NBd2PKPkOyZqZTCbEYxO13Cj4KFEbeoTfPsQvEGbJXeqmlhxhoDhi6EiIKICTBdZsxvH49GtIEpb6vbT9Wgy+2Z3E1pf6uy6K6MrUbGKzkdQo+ChTxlN1KitgzI8Ppwqk9sl8EliHHtBIiCiChuiLf1pXDJqnbYY0Sc7/FXf0q+/7+eNiUrOpcMdD+7hijq3UKPgoUaSF0s/+7qAOUqU3JJmXcAUT7qDcSIgog+icGUVeybNaYc43iNDL0ivcmm9t9/iWi2/1Ac4F1rcUYw5ZzCj4KFIRFz1XLUSeOY7ITGttlqB3COJ2OEiIKIPeSWoySVHv+XTMhUTh0BqW8W2jsAIRH0N0svDuTS+ZnGJ/wbwo+ChRjSB9tyq9zPS/JU6M1wiAO4ZCGLBIiCiBncDR8KRopHT2+8NPvHXwjYhzPG9Wl7OSw+mxjIrWfZhju320KPgoUJxLPaK9pgrS9dTa5TN0NEEoDE/QSIgog4ICana8QvCEuAcXm/O35Kr6TFEQWQhP6KU1vCyOm54gY7M1rCj4KFHEryJGutyHacnMrww1THgwertrgEiIKIKJLY42XFp+3nY8deG5Vju1dZoYQpILwXoF811g/bPWgGJvIawo+ChS9T4DwwaZ7SVB3JmL268rViiWJMxIiCiBDE+HNcUP+F4FVNqTzSZveDRwA3h+jeIgB8aHNbcq2SxiZ1WkKPgoUaKOTx+1JaHEVDAp8rQysCbjkWPsSIgogbU1m3aDQwxIpqFYubjZIhSvYCia1MQSfTaaXJBg38nwYr7JoCj4KFJQ1R8rLKcVXl+EhrLTlhsSdnTn9EiIKIPlinzbm6KAqRHSRPd2vpCjH5/2IyYYvQweWmWTUvXaeGJTGZAo+ChRf7OyUCKJxCDPy99hIM5RiwpwURBIiCiAJJIWl5OYXduLpDgYdOdRn3TuCEdNDOvbeCb8Efjf0ARjtgGMKPgoU1bkxkHcaUGBKX3hJqvBnxKnar5wSIgog+osHwBB/qS9rLDxvKZSBWBjojocJGffFr0QUe0Qm7VkYmolhCj4KFIRCkFMe5ZtA/u/eUlmFc2i/cRnsEiIKIDj7GZ708t0vdKwPJL9hUBCphYoE5+YR3QKKdKjWYDU3GKvuYAo+ChROFUySiOMUNrqBTdktF8TtbO/T8RIiCiB3Rt1QU+mjQeGWKTMclREughe9SJQS87byrgidyM/L1Rju4mAKPgoUCnCRLRjhPXjLMuYyKk5X+GHmw8gSIgogBqasvZfE3hPDsn9oP+gAtCiSM5vrrocZbJla8nahqAUYqqlfCj4KFOgNH1UZpbPJ0pDT6jFPoFVkU1waEiIKIGw51MedTgpTGgY7cpxN0S5gm9JpT5ZGli1WQwZqwtVHGI/6XQo+ChS1wzpAmlicCU6J930kE58lxqbe6RIiCiD6t/4rLoR1+mTmSp026/f6efuahaZtEUJXAuAzAxJHVRjnqVwKPgoUadBgUinGZZdOu3Nvx34WJFw/eaoSIgog+uY7CLC1Wj16/aR50vw3LcJbwIl2/F/zorbUIhKqK/EYsYBcCj4KFH/B2kCyVo3b1Tz/O3bEnOia4oaAEiIKIOW9FXzJFyNWBKLamfwL7U/EzsLqJ+/kYICi+Gem9m2YGPHwWgo+ChTaSvGaN4wJtUwmw0Z8sK34iSkpVBIiCiB06TalTNVkerwkN3I0s7Icf2T6vL9e/GXt3+9mK9gTQhjsl1cKPgoUPojnxU9kZCqYsuHd1b26SHlPBscSIgogeuJubdwp0WNjX9xPVRYcMaBPd0NCP9mKKMcUVtPhqQkYsI9TCj4KFCwkZxgLuoTy8dRWXmb1ZaNAA+5PEiIKILXez4zhnKmvWK6WnjfMe4Ou/fk5f4FooZESRhi8JB9dGL/1UQo+ChTly6GZ4EXnA2cR2BTlfitmw8wDkRIiCiBT0ni6rmLrMooeRF5Qqwx60lK/II2sJqosgLIiipdQTBiyv0oKPgoUiUxW1s/DqOCettGi4zRnxM93wPUSIgogiGQ1nBgIebCilnCQwrqf9kzKvoAxDzAyf1j/BHS8bz8Yqb1HCj4KFMiWkXH5taM1THEqIPAHzeBkjJkPEiIKIK30LfrwCeCF/pKQGgQA6xeSyT496UwWrCyS+HyvyowsGLzCRgo+ChScvy7/1VcLOppBNGJEdXzaPhjUARIiCiA/BOsxKYq6XaXzF83dGYCvLJW/b4+/Ab1elnF/hVzi4xjcikYKPgoU1MQcHhfpMh0Ge6Tj5HbnZrLCwr0SIgogSo9qChmZ6EXdv9K/V1WcuLqHhjPdnYaR3Wt59foCL9wYvohGCj4KFCb3d3vVKRiucYAQIrDi3u2X3dUEEiIKIM2KHMcHmpmZuhjhODTGflc2j6XhnaEiLJCAOEB6Pv6BGOfcPgo+ChTyM+A2JIo2/HPBVP+nkmG8vcS7dhIiCiC6qGl8rhpnwxpMLxnEPjGGByBcMKeSjh53rMR3PuMN6xij/T0KPgoUFf7BBBbjWcwd20JMaRZrJnHyUUgSIgogOjJJM+lCPo58lNWDgEDqaE6KmqIEXGj4mn1B/fAlmUcY6pg8Cj4KFAAKWVljS0KW5N5TZIHeAKig65pYEiIKIF2Ar4XXDpZv+YNYB0jvu/4QLgkNJGT1O1yr3NQuXtVOGLiCOAo+ChRLZSVYV+Q5N1TwSdvpRcWsh/Vj2BIiCiDZUKbh9yUuXKW0qZxi4lkTr5SBn4e0vW6FrGdGK21cFBix0zcKPgoUYKQz0osIeIxy4hM1VL1cxodp3OwSIgogHo34cqIRxDu28ioc64/VuIebfKeS3mcjvzBl+mxCZvEYrrY2Cj4KFAaqNL1tHdNBGePcFz762U9DCrdOEiIKILlWUDc6YZTFnhhFb0omyrV/TTwndmnKr6UwtsUCO03PGP6ZNgo+ChTJt1PtKX5fmJTUpDFJz8n3sge2shIiCiBASlfFQNq6e/bCadpDVDDTNhL/McI5rfAkgiZIieGNrBjLxDUKPgoUP/bJiHmcGt86yg2lYUPIFjiQhZoSIgogl3aWelif4qSwnxd38PcxvOB9F8ood4oBIxwQjcKb/ogYkqczCj4KFJmThJVAfAmzQ1YqrsOrVRpcJGIyEiIKIBLzGurD6RCUM/G6mpRjBEjrwyqtmGFz6Pfom96qvps/GMWYMwo+ChSQH9EizFEu8T3o4aPXlTv93AeG1hIiCiBeAi7WVffXwtInKWugIvNGMCWImg4j6fJ7uve8bxLsVxjjnTEKPgoU9ng9j7MOKDCBwWOYKT9ILcoOkS0SIgog2cuVqUIby057xZ8ndvosCk3fuovzBoJGLMyB74JsZNgYjKowCj4KFKnE4OKvABg9oRQ07UEyGZBemoaNEiIKILV55oVDHCMmyG/Vs5sebYiw+MaIxkHOYq2znDW/0U4aGOaFMAo+ChQZ7AoVWlvnVedtAFnvcw68oSK08RIiCiB5rPg3N4rq+5Xcs8VwDhndQhRYfAZIDqdI18qDPTEdfxijzS8KPgoUN0kIa22FvePaz75EhePflecJttsSIgog1//p4z/9wJv66q9XBZdfArdiQ38m4L2HFofs29rG4/EYwJQuCj4KFOBtretBOClVj3yVM5/7YUmcWhu5EiIKIHd6jZNjXOQ82qUUTzSf/3Y2+lCfHEZSUbWMXuPEJVvoGNn+LQo+ChQtFZty1AwcHa3fJNJREgAAG3TthBIiCiBxY7LB3r+60brsW4mNPJefyi7V0gE1m1qpIpsfrZaCGxjwny0KPgoUDOuRfeTfHEtPjt/ErOb9bTnx5h4SIgog1XjgGivzBPhmBVgB1OIFpn7zCrwcTYaemyu8gxlBJNAY1bArCj4KFJbaN12KKT+PZYDaNuojds2JqyDEEiIKIDAZc2Dpbq9fm1Rk13erbh3hsS2tv4WeYSvGIEySxhcTGLePKwo+ChTOSFUXZJ5PjHFGnvfa/PmlWL8WfxIiCiBNaGuAt75P4sUQtSpQfNy+YWhFTL4D40vVm8ogZ1zU1RiNgSsKPgoUaCdcN8/4a7U9KdYjetNw6P1Ql/wSIgogUav1dgQiOhQuCXtcQbQ0Gd02IRUBiTD1mOgHCGr67xEY1LwoCj4KFOI6/PADX7AazQL+lvaABml01wcrEiIKINYB0PpTONa81Yasb8Cv4JbSDHSIgNis6yru0Sa2Oa+0GLfTJwo+ChTiQtssuSnW9EoaL+SFzH0/Yg/66xIiCiCzk9Lk3+JyGM7HIOjBGjCCOpkKETdD+oTB5MgrdKf9fhi5zScKPgoUbnBUJCMdzuwzfrRRvEwdLF+6SMkSIgogvDkQt47yOHfxAXX1JTCU2cf8H64Mmd5RTWxGI22hBBIYsPwlCj4KFEG1Q+kUealc1cqfEJwm36wUkSb6EiIKIAvPLqW7XuOvKelZ1GMRUrVboGlfhc4ugt2HJCuJcKYCGJCzIwo+ChR8Wqh+UgPGbqNcZCYvV27dKbrZgBIiCiBjMDzLIdK/KaoKmWuHSvnRPUNGGU2xybErfxDhPRTighjfoCMKPgoURRrOyqfcTM5uC3zeAvRV35c1NeUSIgog26qOdiy9k8LgWkIF6rDOqgsFl7y0/qLgNn+NQ/QYVlgYltghCj4KFJEn36YXUN0dVssdKoj4gxorP5sOEiIKICK0NhPrq+4MYZO+/4GsR8Q9Az8iEVltNiILqOex/92cGPf/IAo+ChRYOuc25n351y/oe5qn0yENO0sOWhIiCiBD4515jfjqObuMMtDFcGb7p5RlvwwNKaeI5Hx1WrnfJhio7x8KPgoUxe0SLlEf+dfeqYb9dCPGGusTnTQSIgog5G1sO7sQEggEpNTOoVTGAjkE67W5mL7w0+u59leTd2sY980eCj4KFDUZVWroTF3Lz2/a8F+2ROQP+Tw3EiIKIIZuunGlXy1Rw8DKF2DeS2q9C8e7eezp6unKd9RGo9zqGJ+nHgo+ChQfraFN7oQ7cz7NXeLnRVKtI0pUURIiCiBNg9WECLj7nu2NOc3CO0qu5ANlHrOdhtKNKCwnRSCxFxilpR0KPgoUFXEDi1qqtDHsAR9qsQlEY8btmEISIgog8D8wXkMZ9d/p86sOxIzs/Uv3MMYyer1AMj6UnOKdcW0YgLscCj4KFC04fZXhP2gdMxIuRHX5t9/Cpo9kEiIKIOF9OTpMjj9UCgokxX2bCEEx4u6F6olPRbTf24m6Zwq2GOnkGwo+ChQ/9xnxZkvuk9SCtIBnfAOkfsC2QxIiCiCAm+Q8uIejb7XYkkamuHBWwAEBJfNc791Ja2eTTLA0HhiWrhsKPgoUwCrLp2U6w3gnULU9A6Zy4ZHwA2ESIgogHG3qcg4yqCzlBG5NqYtZaRKtVp5WKcxnETQZr0GTJmYYlIkaCj4KFDdxTE2kB8nRPNpCSq54w7KFFaFcEiIKIPMcDBEAyOMaA9md9NH/L6Y2+JG2EFbnee0YFoZa7QbTGPTtGQo+ChQGFAiMQeaoX7W/NEVSpRIOWgE5/BIiCiDDCxtDqaQTB5m3ZmE9qedBqn8WKbWwO+IY51ClrSDIDxiw/hgKPgoUzcAYgidHAkvq/RCkWr7MesGcurASIgog5SA1hEf4+ry5n7qOWjxrN7cBRfwb9SqwPmbwIzEkAXkY990YCj4KFEFG/XoauLhhtwGJeLzRPS0fpj6+EiIKIK6rM9z2ufwG6QrkBCVJf5oeqM9gf5m5JyTsXVU3gJFDGKzaFwo+ChSAFLohLtOIWXUQ0GQlj14wqjDVkRIiCiDE/Tix2DvHBmo+k5hqhMiM6EKBCNcrlp2CCFAumQ/owxiE0hcKPgoUNz+GyzdVod54zGnT5fetXXYVuF0SIgogYMogBkqxrStOmjdKuQOfUpbUg9OC7SsOTmqgS1ZjJW0Y+LkXCj4KFCK6WawpGK+kwbVtPm+GCD5HDNjLEiIKIG9g1TQS6yBV5ENfVl5m85VCofrEKwWkmNbPIUj5BRTGGPvRFgo+ChRzZL5sx7bkBL0cIFDMtqdHJ4bjthIiCiBWXKF7VEPQwj04Q1ts3bKOZNO1UmBJhhk6JI0L6TQm5Rjo/xUKPgoUlypoTzZMzjFGmzep1DmYURXrWkASIgogA/NlPxYDzI3cgNZkl8VSYHXBe90BCv1mgqd5X88eYY0YucoVCj4KFOIABFFTEbIFYY+tUE+1KaPe7i5xEiIKIKJsRlx/OXZJhnrEORsEMtGCmeqr5vv9nvH8aGoZSqK0GPmTFQo+ChQvidfT0eFHj4jvOtiq12qIGJ9hJBIiCiCcIPvCkGBoebkJMy+xaujhb04Oa/O8vOmFiggCZJblHxj6wxMKPgoU2AelXH1pqE+3WfsL2Wu02lCtuicSIgogPlr19qW5CC6tqGm+FcqukdqSUtxRtSVwmVVLC1OCuG0Yub0TCj4KFH4R7X3Qb657C+20aXIRUfLzHLtqEiIKIEx2nAY1JfBMfWNha5SjK4+aGW6Kv7FaU1jLWpsFFpaEGNGuEwo+ChTallZNI3ms7gDdn6pVhoG7SZdX/RIiCiCFlwF18VCLPQLUQ6QQ+SrALl+nvzWO4HOc5y28UAizUhiAqBMKPgoULdbSKWnufCyh+LQo0TqJlcBDBEwSIgogcM2HUzau2L3D2063LKI5YGmHcha79u5vmQFWyKo3A/4Y8pITCj4KFJSWU1qPKUW9tgVyAV0tb3Iatv7ZEiIKIHgHgFCpz7xsW+oREOFcc1TvumVr8qp9To7cwY6swSsUGPP3Ego+ChRjTS9e18nYL0IpjYkiME0bStsg9xIiCiDYMZZwXeS4HQtkDOoHguDxtcAOhvuNRuN7B6j75614hhi73hIKPgoUsVBp5BsaYP8Dro2PdB94x7EUT74SIgogWKxiiCcH6FsecYR74Oc+o1f14Z2/7q+kzJuD29xRLqkYyZ8SCj4KFNDCBx1vL+8CHb0/Xx9y8b8wpGe5EiIKIH2FMkG2hRqfDV17bqPxMqJ1UNtaWhr61MgpCw3NTG61GOu/EQo+ChRdVk+ETUEWlLExscSk/Ts4lJT0jxIiCiC4PFXKl/p4R49cK0UHy/cZEqtfEbEtCrGoY7oREE2LXhiWlhEKPgoUGR6JahHAp3qWqZq+6YaipANVwEQSIgogjG3YOPzLxEOmfC2xN8qxqtF+A1IGLvn19AhTvhSmor8YwMcQCj4KFEfIliH0e6f/I2LBsvl6T2MRtkb5EiIKIMl8fpYHepA2jI38M79ewwmPVmmyBcdwuh7SGY1z6wcDGISfEAo+ChTwyLat2vfMTs5XCGYHqaDH6mJ14BIiCiAnykdh/qfry1/vvBVCsskbAtTb3mnmCt/gieYJnsXqwxjPkBAKPgoUIGWL9A7UjtAaLQh8f/eHTyGlYzMSIgogcf+XPmAgtXNK/B4GuzvEpJdhwaFFo1fn69KPhaPXQOUYgZ4PCj4KFCM1RlsnuVSDE6r0ZSF3h/2OYRPTEiIKIK2DzObMLdgyZihYCO79Ac7f+8lCGlFhfi6tIbuqhf33GMSSDxI/ChTLWmO5Ho9O6NuTWULL4lckY2R54BIiCiDo3PT1gYfPBbGNzMbQiErgi/SpjYhxfQ//kqK29FdNRximv5sKGPnqnq8BGi5hcmNod2F5MXk4azlhMzM5NjdkbTluN2E4dTJkMmw2cTltN3RlZWN2bnh5MHQwCpMPCiIvaWJjLmNvcmUuY2hhbm5lbC52MS5Nc2dSZWN2UGFja2V0EuwOCvsBCNPwBRIIdHJhbnNmZXIaDGNoYW5uZWwtMTQyOSIIdHJhbnNmZXIqCWNoYW5uZWwtMTK7AXsiYW1vdW50IjoiMzY2MDAwMDAwMDAwMDAwMDAwMDAwIiwiZGVub20iOiJ0cmFuc2Zlci9jaGFubmVsLTE0MjkvYWFyY2giLCJyZWNlaXZlciI6ImFyY2h3YXkxdDhucDZ4cjhxcjI0eWp5cDNsa2c5ajR3eWVhemdmNmZtbm45eDMiLCJzZW5kZXIiOiJvc21vMXQ4bnA2eHI4cXIyNHlqeXAzbGtnOWo0d3llYXpnZjZmeHJ1MzY1In06AECAqrmEwJHz5BcSsgwKgwoKgAoKQGNvbW1pdG1lbnRzL3BvcnRzL3RyYW5zZmVyL2NoYW5uZWxzL2NoYW5uZWwtMTQyOS9zZXF1ZW5jZXMvOTYzMzkSINhC3mekDyzT1xZlD2PRx3DPeWtXdYD0v95MjTwtJkh/Gg4IARgBIAEqBgACkKvDDiIsCAESKAIEkKvDDiADeFSOHHb4ZKUAzagZp6addI3zvCJaCM9+p/Es6cplsSAiLAgBEigECJCrww4gD+qSIM1vyeDJ8gcYBwkLypQYLu3GdZfu1wRuYZCR1rsgIiwIARIoBgyQq8MOIKcLzjRdiOALLLHxfuTVuvk0a0yiXMIiE3+/kfJkOYzSICIsCAESKAgSkKvDDiCBA8FAkPxetowxtKNFBrVrflz7no+7tsH2GI1wBzWhTyAiLAgBEigKHJCrww4gICkA2CwOawrBATWo3Lt9ZpPcqJDcj1Es32ppEmt/OqEgIi4IARIHDDSQq8MOIBohIAWVRs5Gw8tX5yGlMZFy+j4+7KGdHIgsoGRX32Z9htHEIi4IARIHDmqQq8MOIBohII3bnbAoW9hL9ZWrQXE6DBhbj2YBc21snbM/AtwyxaodIi8IARIIENYBkKvDDiAaISDZQkAo0+JGFD4QTuA74aWetkJ94sBfT6etX9uqn+YIfSIvCAESCBK8BJCrww4gGiEges82GCPn735hcBl9EbjBtc80aWuRCThKHjGtA0eEh2MiLwgBEggUvAiQq8MOIBohIOaRONTjWUwprnDfkKZ1vxeu4gSGu56uCttUHAepD+QEIi8IARIIFvQSkKvDDiAaISAgi+oCuML1Ig4uop+7nyRs+p1eAXyApI1xPOz7OgwM6yIvCAESCBjcHpCrww4gGiEgYJcEDM3KeMLnoKVIETkVxX4Ld/xFLVjT1bnx8Y5Y8kciLQgBEikcmj6Qq8MOIPvXfE2iZCZZqv80OBFMtXApOYq3r4CDHHZSIt6ctwHDICIuCAESKh7yigGQq8MOIAQ5W33qppdklBVfJe0nabK6KJ96WMjUh2/ALDU3sp/7ICIwCAESCSKg5gKQq8MOIBohII4jYRXe3JORcuNiU12mIpqRFNMsg9Qx3BEbqVZ7CbOZIi4IARIqJuy9CpCrww4gYrAmCj/PKxMFDIhq/w2i3ix1L4xzpk1w1QjlBh00U1AgIjAIARIJKt6LG5Crww4gGiEgJ/87YMhJwNADfVgvkA30D/sZLSmQNy89+1B6G5s/GSYiMAgBEgks8vhAkKvDDiAaISC+LbX6JsPtVeZSAN/39f2TFRMpptqGh+UP+1YrMo93ESIvCAESKy6uw7sBkKvDDiD6xP3v84ZaaCCKCT4rf+HI3OUF+FQtcPHvIHpl0syKvCAiMQgBEgowrqGLApCrww4gGiEgXbMF7+DumXayC/+wSP4C84hgwbJ01HpmPLAJUzbJdjMiLwgBEisyxKL9BpCrww4g0r0MEPa1awmJgXxuzq3CUlxlS6XHY4k6iPzPAl2LPlMgIjEIARIKNsDn0gqQq8MOIBohIO7iN4FD9hnDGge67fiueCe/dvXpQ/wMvOumGjfQb8PDIjEIARIKOJLMlRWQq8MOIBohIB9h/mZFQF0fiHS8j2Q2plBcF99gWmF+7mKwgbxp7/pfIi8IARIrOt7biiWQq8MOIGGTWlC9c7AMt/GT51fCM8u7WyVO25iEpUkP2FqfY0mYIAqpAgqmAgoDaWJjEiCZYsd1HgA2QFGLAzh2ahiEVYsFjoWndu+jMHBqjnY+hBoJCAEYASABKgEAIicIARIBARogxQXA/UixzytlYZ8SsxROGcYLTmtiUl7pNr6T0EFiPr8iJwgBEgEBGiCmJ4xLBYkyoXpm5lHvodkDvnLxnorR9yLlHk7jt+k53yInCAESAQEaIBSOOuVfGm05LqukdPLAT+yzMagnIWrM+tflOyt3RJIVIicIARIBARogkbHyjJYINk0K2Fc3shOhU3EC4bHR5haLxdKwHsyXENoiJQgBEiEBgq2siVFY2nBfSZsohUGIrNoBNx+hsTY10ZXzTsNUnf8iJwgBEgEBGiCTqq4ERhKlYhJPx3/zOdQQktlF258sRsjI9w8psf5+HBoHCAEQydWhByIuYXJjaHdheTF5OGs5YTMzOTY3ZG05bjdhOHUyZDJsNnE5bTd0ZWVjdm54eTB0MBJAbXpvbmRlciB8IGhlcm1lcyAxLjYuMCsxYzFjZjAyIChodHRwczovL2hlcm1lcy5pbmZvcm1hbC5zeXN0ZW1zKRKnAQpSCkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohAqcOUK9hvgd977yTcoV+bCVgCNTL8Y/NlWkASpkaryRQEgQKAggBGNXjBRJRChsKBWFhcmNoEhIxMTM1ODk3NTAwMDAwMDAwMDAQkZwuIi5hcmNod2F5MWt0a2E1cTNjbnN5M2FyN3F3ajJodXp6NnFqOXE0eXM3aDc0bDl5GkAHnhEyknT46ASVO+NM5JUpOF0mRkC6yC90ssXySYNvumV7JDu4mGsQXJVbpJNVo3+GUw76Nn8QAGALMoj86XBT", + "CrYGCrMGCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QSigYKLmFyY2h3YXkxNGp4ZXR0bnJ5d20wODhqYTVnMzZuc3I2NnkwOHRzMG11MHk0OGESQmFyY2h3YXkxemxjMDBnanc0ZWNhbjN0a2s1ZzBsZmQ3OGd5ZmxkaDRodmt2Mmc4ejVxbndsa3o5dnFtc2RmdnM3cRqTBXsidXBkYXRlX2RpcmVjdF9yYXRpb3MiOnsicmF0aW9zIjpbeyJhZGRyIjoiYXJjaHdheTFhbHVrYXJmdmt4NW0ydXphemx5ZTd5dTB2bXlyZTc2cnZtNjN6bnl0amw5OTZ0aHdqdHpzdDVtangwIiwicmF0aW8iOiI2NDQzMjU2NzQzMyIsInRyaWdnZXJNYXhWYXJpYXRpb24iOmZhbHNlfSx7ImFkZHIiOiJhcmNod2F5MXo5dHJkcnZhNDdnNHd2dWRwbndoZnJzejJkcG5zcDZ6emRlYXhheDNteGN5ZnlsbXI1OHF0MncyeDkiLCJyYXRpbyI6IjE2OTkwNiIsInRyaWdnZXJNYXhWYXJpYXRpb24iOmZhbHNlfSx7ImFkZHIiOiJhcmNod2F5MXo0MjRqNGpoamY5MmRzZzU2cXQ5d3MycTV6bmh4cGFrZmRremVzZmUyeHg3cXluMjZ2OHF5MzdjMmciLCJyYXRpbyI6IjkyNTc3MCIsInRyaWdnZXJNYXhWYXJpYXRpb24iOmZhbHNlfSx7ImFkZHIiOiJhcmNod2F5MWwybW1yMHZwbmRndjh2c3R3bmo3cWhuMHB4NGZuODBlMHZ4ZG51ZW51ZGZ3YTU3bjUyZnFmazlmZTMiLCJyYXRpbyI6IjEwMTk2MDUiLCJ0cmlnZ2VyTWF4VmFyaWF0aW9uIjpmYWxzZX0seyJhZGRyIjoiYXJjaHdheTFjc3R5NmtsdGo1bnk3dncydm5uMzN0NWhsejcwNGxuOGE0eGZ5ZjI4ZHQ0anNzNDVsNHlxbTNneDlhIiwicmF0aW8iOiI4MjQxNzU4IiwidHJpZ2dlck1heFZhcmlhdGlvbiI6ZmFsc2V9XX19EqYBClIKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEC6YWLCHnxmaVJ//9A8Jo7ina7eIRl1BfdS9lxauMkvuMSBAoCCAEY4+gEElAKGgoFYWFyY2gSETYzMDAwMDAwMDAwMDAwMDAwENC7GyIuYXJjaHdheTFncHlxemMwYWVyYzg1Y3BrMmNtOGVjNnprYzk1eDV5cXJha3NrdhpASbc3d6pYIjT6jegsMGhDcWaRfQC1+IodCi2erEDIa9Zb/auoex17aWfIy1DwaS/PrsUTsNssJufbuNLrqmhEyA==", + "Co4ECskBCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QSoAEKLmFyY2h3YXkxdm41eGx4eXA2ZTUwaGhteHB5ODdoNDJ5cjhnYTNucDVqNTBlNWsSQmFyY2h3YXkxNTNsOXBjN2FjdjdxdzQzbHl4M2YwZDN0dDAyZ3U4MHpkbGxscjRsdnd0ajlncGs3bnUwcTdxZGFnZxoqeyJ1bnN0YWtlIjp7ImFtb3VudCI6IjEwMDAwMDAwMDAwMDAwMDAwIn19CrACCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QShwIKLmFyY2h3YXkxdm41eGx4eXA2ZTUwaGhteHB5ODdoNDJ5cjhnYTNucDVqNTBlNWsSQmFyY2h3YXkxcGF6dG1wZmY4OHNqamNyd3dlajhxbHlmejdkbGxldHE2NDB3dXhnZzRscnB2aHZxdWNxczkyd3duahqQAXsic2VuZCI6eyJhbW91bnQiOiIxMDAwMDAwMDAwMDAwMDAwMCIsImNvbnRyYWN0IjoiYXJjaHdheTE1M2w5cGM3YWN2N3F3NDNseXgzZjBkM3R0MDJndTgwemRsbGxyNGx2d3RqOWdwazdudTBxN3FkYWdnIiwibXNnIjoiZXlKemRHRnJaU0k2ZTMxOSJ9fRINVXBkYXRlIFJld2FyZBJ1ClAKRgofL2Nvc21vcy5jcnlwdG8uc2VjcDI1NmsxLlB1YktleRIjCiEDFoTqz3G/fpPilox111GgWydbThr7HWiIQbxEsnQwt7ASBAoCCH8YCBIhChsKBWFhcmNoEhIxMjQ2NTAxMjAwMDAwMDAwMDAQwugmGkBXdLfx9Zq+XeMmg2avX7qze2L0dlhmHEoadFS+cfZlmD15c+skMNlMmxhs9cwTFFtdXUhhVoIRd0fBFxd3npad", + "Cp0CCoACCikvaWJjLmFwcGxpY2F0aW9ucy50cmFuc2Zlci52MS5Nc2dUcmFuc2ZlchLSAQoIdHJhbnNmZXISCmNoYW5uZWwtMjAaUQpEaWJjLzhDQjU2QzgxM0E1QzIzODcxNDBCQkVBQUJDQ0U3OTdBRkEwOTYwQzhEMDdCMTcxRjcxQTUxODg3MjZDRkVEMkMSCTQ5Nzg0MDAwMCIuYXJjaHdheTF0OG5wNnhyOHFyMjR5anlwM2xrZzlqNHd5ZWF6Z2Y2Zm1ubjl4MyotYWdvcmljMWNjcjJtNDA3cnZoN24wd2hjcmhxMHR3YXd4a3J5MmN5OXlxazBmOMCdvofdkfPkFxIYNzQtYXJjaHdheUJvdC0yMDI0LTA0LTI2EncKUgpGCh8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQJj1p/A6OVBI087EWcRgSt+xzdgLmR/f8UHHBPMloqn4BIECgIIARiGhwQSIQobCgVhYXJjaBISMTQwMDAwMDAwMDAwMDAwMDAwEODFCBpADpmkxVmQaQXFDASxZnozMcqf99XKcSn8NkJjMCEYtDld3W2XIHfhPRWx1tBtE43wsncCwO5fY/Jhq0rlyB99iA==" + ] + }, + "evidence": { + "evidence": [] + }, + "last_commit": { + "height": "4326862", + "round": 0, + "block_id": { + "hash": "B5517CD93ECF6C568C00204CF0BB6D6E87292806911FDC5DD5CF8B318EB5DE6F", + "parts": { + "total": 1, + "hash": "F34408000CA1F5D31D5B9DB6C4A99375AB971DA8E0691076D3C5188DE8DC9C28" + } + }, + "signatures": [ + { + "block_id_flag": 2, + "validator_address": "454BA446172211B1CB7A08E14161FB3BA1493F73", + "timestamp": "2024-04-26T10:04:00.913603708Z", + "signature": "w10rBPhVKtW5paIFCCQYAfqBGErds6bW2SVgpIufOJvd+DaXLH909yw86vZsY8EpNrW9vq9dEHxkT71+JawJAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "5E026F83F8DDC51308008A80518530E9C03C7771", + "timestamp": "2024-04-26T10:04:01.044089215Z", + "signature": "eWyM18DsNXtsPUA7njF8AtNGR9PRRCtWlLRwv77+tGkegcD+hikLNdLn/lkWmQSKPdMGB2Xb/998izmPJ/v8Bw==" + }, + { + "block_id_flag": 2, + "validator_address": "C64F7CF03BBB07B80E1B557A185032114C1F0201", + "timestamp": "2024-04-26T10:04:00.941638306Z", + "signature": "WAoeu5BKqzgqnjFwrz4j3+Xp8b1Y4Irqyb055ku3Gp1C/Sy7z7fnT9f17vIGgbCU3JoVu7LGmnI8lOFfVvgyAw==" + }, + { + "block_id_flag": 2, + "validator_address": "9396A4ECDC186B5F92600579AEC5E04D1059642D", + "timestamp": "2024-04-26T10:04:00.999364252Z", + "signature": "cOlxmrOKEynOCii7gYa5AEl14+IPuEFjamjWrogA5zRdmt1esUkNXBnkaSjnV80Fz+O0FY6PWmhu4Nsiq6C1Dw==" + }, + { + "block_id_flag": 2, + "validator_address": "192D17EFD1F6012E52A8833717D8621178168264", + "timestamp": "2024-04-26T10:04:00.928039558Z", + "signature": "bKXDa7F2ecJwZ7T4/5COSo2nBKnsjUBJzoyi5D6WpPjgRlZYwyAhMqylSNIwvVF4aYpZ90UkF+N0yDmozebCAg==" + }, + { + "block_id_flag": 2, + "validator_address": "56AE16561016ECD1B64540DCE711C588F06E2DBA", + "timestamp": "2024-04-26T10:04:00.922100324Z", + "signature": "9qfChH0ARYuskzwoWyH39zOoj6kQKIa6SnbgX1Tt4z5uRq50LfrXJeY6hG71A+2Ivejb+9I98RqHqbe2seMnCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "3ABC887FAAB038EBB82506305FD928270AD2867C", + "timestamp": "2024-04-26T10:04:01.088343164Z", + "signature": "IuFFBkH6cmQiHjTwzda2yS1tbhSh62pb8fwiVMZ/yKON5iO0xtuf4D1aLNzRXkmHTpcUI0EU3aYYDQIdQL+uCg==" + }, + { + "block_id_flag": 2, + "validator_address": "7CF3A6E06DA02BF700E33372951EA2E95AF6A7C6", + "timestamp": "2024-04-26T10:04:00.954431343Z", + "signature": "CV1oHmG/QFF6Z2KsB/47/COGs6c+JyyCHzkH05SWCm54ieVlNecg9p+QT/RTIi2puIAa3J0BQU/ScskIuX5PDw==" + }, + { + "block_id_flag": 2, + "validator_address": "E89799B6440988A1AAEE14ADA7050FCFBCBE31B5", + "timestamp": "2024-04-26T10:04:00.990899045Z", + "signature": "B4UvTc3oPz0KCIv1QzAYypY72y155O4tg+mkqkKMt7cf8YqK3aYkIHrwu9HzxAsWfWu//pkAaw6fCwk72AklBA==" + }, + { + "block_id_flag": 2, + "validator_address": "E840B5676A5DA43F7ECA8385B461FA6BF0BE2CCB", + "timestamp": "2024-04-26T10:04:01.011836697Z", + "signature": "kyhMD36cZ7aTT/7Lrugn+Nfa/wtgkq+r5hQVlw5nCSFnFPruwzs3dC7kcUPPFvM4dgShlYJAzgQrdNCz80CKBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "90FAA31CA9BE4E4BB8E4C9732EB69575F4C5B626", + "timestamp": "2024-04-26T10:04:00.93586698Z", + "signature": "PBuimBU1d+puX7nn4pxfuTzhKGBESgdSFipr0puGwMU8bTQcgCaiUnWi2RTQUzOhSrkFFiokIWjjblJrsaebDg==" + }, + { + "block_id_flag": 2, + "validator_address": "CB8D061C7D78BAE099C50D6857B97AD4A9218776", + "timestamp": "2024-04-26T10:04:00.941546835Z", + "signature": "1b0H261RPgTeqrWn9MlkI6UagDbYRf6YOjzvcC8nC+vDUDq2E8dZOLUPLDM9Ncf0FgJ9iCig71QpbKJ8710wBw==" + }, + { + "block_id_flag": 2, + "validator_address": "4630574528AEF5F2CE3BEA1BE9E092927E311F0E", + "timestamp": "2024-04-26T10:04:00.896772993Z", + "signature": "AxsIx+ntgm4h9MwTxdVHH8GDBRP7oszUVQnbPdssFgZl3/7WH905Ob54TvvsKkjwCShf/HNDkRFSUaeeYkjtBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "B2FF86CCBBA2DB501E828E0E9D15EC14D50E0214", + "timestamp": "2024-04-26T10:04:00.904433802Z", + "signature": "rCnRIxqroTrbr+vZ6mi/2zp2tlGheTH3MUzktBolxKMx9UD+XixezzzWMU/HhK5dPDzjlpU3SLrH/K2lsK+oCg==" + }, + { + "block_id_flag": 2, + "validator_address": "CFBD265B3AB49045D2AEE7D001199ABD30BD1E5C", + "timestamp": "2024-04-26T10:04:01.012598511Z", + "signature": "wNuNxQP4h05R8XvTIw2Lj/imn4+smkU3fZrju5mYIhvFPJaIsEvSrnH9JBfZJy0iJWtvkTgTrRyJ0dLK482FCw==" + }, + { + "block_id_flag": 2, + "validator_address": "2348415EAAEAE89FE5A9412F2F45CA9AA5E73BBA", + "timestamp": "2024-04-26T10:04:00.987450291Z", + "signature": "CloINMlS6FEhLQ4xC6lWd6UhfXgrsFKeF9ahd6/O0wNF61m4KTH2RXhf3EheFhD/bdDvs9ggwnfUoRi8dNB6DQ==" + }, + { + "block_id_flag": 2, + "validator_address": "E4983569DBE9E32DC1C9C69CBE4DCF1CB82899AA", + "timestamp": "2024-04-26T10:04:00.994730635Z", + "signature": "NspkRTG8v/16zgocMkeyIXCme4qsGTvjqtRePtl6OYIIxpgf+k26vkWzoeiVG4V5EapMAe2Dvt0sdfRafg6QBg==" + }, + { + "block_id_flag": 2, + "validator_address": "9417D3AA3F23E9D96CDCBA2045A07B401C1E11DC", + "timestamp": "2024-04-26T10:04:00.914497965Z", + "signature": "kpPd4bB8p/edsfFGsGd4AyfYTtcYyl0sZlZudwwmBi1/rJT8M+yIL1MZ4dzdKxd6stsNMTfAltMCKW8p38C7CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "F183805F63AD6C429B7157D90D7199F2075280AA", + "timestamp": "2024-04-26T10:04:01.013508783Z", + "signature": "JOJ1EPxvJ1gg3a2jzWCz6GaUhNTvdwBGJrZZDEh+PvbNDjFTTacpYZdsiG7gwO7gOW8/j1EiVvEwt7jjY9qtBA==" + }, + { + "block_id_flag": 2, + "validator_address": "5F647EE2AA22982E897765117160DA27BD8DD1AE", + "timestamp": "2024-04-26T10:04:00.923550559Z", + "signature": "tFxPEppwKDtOzgWflBXlExT8uRHvwNxaPmNv5Uzh6ERZO5jDQs0/7c0BOCKNdEPgr4FE6xFkEVlydAWeCOsYDg==" + }, + { + "block_id_flag": 2, + "validator_address": "C6216B74B71AD3DD522E00D28BF1E7D7B9145869", + "timestamp": "2024-04-26T10:04:00.964602274Z", + "signature": "kz519Lexud8+ftzYGuDSGE+jzgXGfkJQWQAG+UZculVVDRrslEC0Yjl8LKgYwbG31tHyyMar4FjpHIaAABD7DA==" + }, + { + "block_id_flag": 2, + "validator_address": "31323915F9B0CBC60B4F371E454B5FB19B0AD26D", + "timestamp": "2024-04-26T10:04:00.981107953Z", + "signature": "lYc1784Rb4SnNgVXDLkUIjun9CeF0468L7GxUuw3A7v4IIv6EHqvz7ehaRBUVDQirpJpZeVwwgepz74cj8A2CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "1D143C66358013DFA42A05A3BD9D00397AFDD6D4", + "timestamp": "2024-04-26T10:04:00.978188855Z", + "signature": "sWw4JSawoyUEnSATf0TihVNlvO8fJKzqKxP+nEbGqDTCGglfkO4zzCxYkeIxzSNiNC5bO2e2ZBaUJiRYgDOnAw==" + }, + { + "block_id_flag": 2, + "validator_address": "90F0753D72B15384CD536B1FAE023BD7FF7D250E", + "timestamp": "2024-04-26T10:04:00.914707884Z", + "signature": "zfO/at4ULlKl3dRzTki7H/Jio+D4JwedCSTLgbMsBRlsNit4/voyUwMfRnxVHABXe/YmbtY3zf0i05ODDgzmAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "38303246077ABA69E2782CB2C71C89DE9E2B7BCC", + "timestamp": "2024-04-26T10:04:00.993706125Z", + "signature": "O6xL+/9b5vL7Cx42KCEOXztyjbAoKYQMhDAnQSkxnOj8HRL0FwnEtk3pi0SNt7JiyFE3mprz1JJbxJotBlB6AA==" + }, + { + "block_id_flag": 2, + "validator_address": "8F41A1631BC7D5ED4915B673297D2F60A22C6E34", + "timestamp": "2024-04-26T10:04:00.91698356Z", + "signature": "OHrmrLsvyAjOfd1+hZd7Nl5sXcv5TJ/Wd9xSssvSqRvmsMIxf+Sgf3HQX67eJwRwOTH4+cseZ36DMAKJk76wAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "8B714B0E76353D945D98D4974C8BD0B0748EC196", + "timestamp": "2024-04-26T10:04:00.935853331Z", + "signature": "9w2bgHC6Yg5kOSQ60QAJaxTw1sssf0ppGW9ML/MDR5ILYPqzmL/ETx/0KhKqzGHXViW1xC8MfcJ+Qo5Q2bd5Cw==" + }, + { + "block_id_flag": 2, + "validator_address": "94B06CE54895A6138DB5D3E406E5914ED41445D9", + "timestamp": "2024-04-26T10:04:00.962779109Z", + "signature": "hk0pmeOhe0oRDNEI7f6RbL0DB9O+Leya6y3CZQtiALb4g90cMDmPvgic0wTCDwstq2gebWT+xYq00NQnEFyGDA==" + }, + { + "block_id_flag": 2, + "validator_address": "ADADEE9B97C69600FEA8911323F3F5CB28906EE5", + "timestamp": "2024-04-26T10:04:01.043290814Z", + "signature": "07n5NXnWpHoxQkBW1/e8k5zsQcoSNCe9yzXndYSZUcgb+Q+8psB9jc3iK6cuOrTPXJpufBW+PwbYQ9mzTcuyDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "FD1E562DD7FA1296ACA834EF29AA0685A8AD8F33", + "timestamp": "2024-04-26T10:04:00.929138154Z", + "signature": "4SQKY9tcsWwhOCerZWGUKG7e+vDRo2Q7qHkPgNESlb0tjYPeRZWplV2bhXPLWs2BCed+VpvMKenP87cmXZ5hBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "A0212325DA0D8E777AA60AC5DA61DE409072726A", + "timestamp": "2024-04-26T10:04:00.941745838Z", + "signature": "n2vFH1iekNbMTRWrXn50jrSJHApDKqS7MC4q5qsceFroJrFsii/KUsYugiOo1RsyvaTstjM1y2RdokFbtwbTBg==" + }, + { + "block_id_flag": 2, + "validator_address": "CF65D933DAAD0646727C76795AAB0DE423B8C0E5", + "timestamp": "2024-04-26T10:04:00.932145904Z", + "signature": "REmNHc7KdPZDm8WeFHQnnnGV2RO+7EaZdvYB8Ye/op/ZsZ8aKqBPaxowLTBS0JAuOIGyGYCEhxZd9C3qAE/HCw==" + }, + { + "block_id_flag": 2, + "validator_address": "80FF2FDD961F707F3C005A7FD41D55A74F076AA0", + "timestamp": "2024-04-26T10:04:00.923333741Z", + "signature": "r73YeOsqFmfHp139X/WlUZwUP5Verv6moA/7pFWzsyxvmBfEd7sytk8qNW8UrGjB9OJTOJ0mgKU4glkODNuqBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "FF592BF088B8ADABFA6080AA820F7903F0F02046", + "timestamp": "2024-04-26T10:04:00.96546151Z", + "signature": "8ZzOzkghVXSRUFgBjxYVqe6RLb0jrE5psPKRLGjimZcJB0SYVYkc9y97e8wnHjj66Q/0r0xstkRK31uuAvPKAA==" + }, + { + "block_id_flag": 2, + "validator_address": "C5047A5B0C008A531993140151F3E54C1308A86F", + "timestamp": "2024-04-26T10:04:00.927806845Z", + "signature": "VG0CocWnpRzD6KyjM5n2uk6NdUY1BqiLyZ79JwsgtgWLebKoIXXcKYBDuQXE938RnAEuROPqpcF4T0k7xYhiBw==" + }, + { + "block_id_flag": 2, + "validator_address": "43EAC69067530360F849375487ADA1F26FC026FE", + "timestamp": "2024-04-26T10:04:00.943727613Z", + "signature": "UtCnnQQAAK0/Z1OnVkhmgetiDc7gsgSLHx6ST2kQMAbyXMhfynpoJ7b9rMvpitox53AOhEwc2+8CB5AV6/I6Dw==" + }, + { + "block_id_flag": 2, + "validator_address": "5894E2D8B68C01CBC835985BADBF0AE378A5A6B6", + "timestamp": "2024-04-26T10:04:00.981015154Z", + "signature": "b+Zw2dywJ3eCUJbFySNnrkFbi+hNEzdubKxZ8BKkfSUQbsN16DSW75EjZwsfs/qzeThrljsEpj4PW6uOxnHLBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "94A81ED9CF1EFE9672501231F0255F0C54A4F411", + "timestamp": "2024-04-26T10:04:01.103703381Z", + "signature": "Rsi1Hy5cdrw6pDKE1R7zvzMP5+rSmrgyIPjbar+fQarlIa3iZthnH43cA4RsyloJOI9YU4nCfS8kmB17S680Cg==" + }, + { + "block_id_flag": 2, + "validator_address": "69C38FB90624F19356482DAA89E64D9957A37C00", + "timestamp": "2024-04-26T10:04:00.915164032Z", + "signature": "ilZ2+sCgmVxoooGEVGYPR2NK2tuCGjVAT8ekL+SL7tZz+45CjCIMQ5Q0mNdlTfZXgCtjumZQhFHiXlIwKAOJAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "D78997B5A01D2D4E80C5189D930A14055002B478", + "timestamp": "2024-04-26T10:04:00.922386823Z", + "signature": "53AoColG7N5KOBEhamWTtRZxlAw5159b7yxIytokO0X0oUxZ2jUwg72vBQz4Oc1ikRz7MX+QgUIj3Q5i9vUIAw==" + }, + { + "block_id_flag": 2, + "validator_address": "1AF66CF8C90E5D334FB095B4983210FDC2E2815F", + "timestamp": "2024-04-26T10:04:01.009681532Z", + "signature": "rWmZwKarW11fMZu3kVWsPyaR02tNCr2xZhPHnDlB9iIJYsC1XC1V8uJyJ5Illr7PWwfUiQSeTsrJiYiS7GFsBg==" + }, + { + "block_id_flag": 2, + "validator_address": "2D63B9079FCAF8CEE74B072665A04599064BCB09", + "timestamp": "2024-04-26T10:04:00.909836541Z", + "signature": "YQRS9L61CyChYVGzCoYtdeYk8EW8paO9TOuF4n58vg+U1JiFwA+cTgQgBguFnuBUy3FcDqNgw6Uegw81CyH6Cw==" + }, + { + "block_id_flag": 2, + "validator_address": "159424CD4756CBEF88083C1A11B6033423537A3A", + "timestamp": "2024-04-26T10:04:01.14491675Z", + "signature": "I0JtE48qtoMmlB5vKDk23+A6haytlNUbNEK14QZiFT2ygNR3wBlpxCo3pov2gCE8kWVGqNdYaGub3BedwjfZAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "C406A6BFB29F36979ADA959B917DD4A2A780E519", + "timestamp": "2024-04-26T10:04:00.990328705Z", + "signature": "le3eD6IZYEq0XuhH+SM/a2mEcMrJAk3h8xS1oG9obtnqbXUG3aAltwloq9TAybPaGL1bH2ib2L1a3zeWgfj7Aw==" + }, + { + "block_id_flag": 2, + "validator_address": "92C0FD982DEC037B295494DC7ACF25FBB8E3EE5C", + "timestamp": "2024-04-26T10:04:35.192046013Z", + "signature": "lzLnElmHq9qRH+12eJjoamR1k+EDzL+fUG/A9XSdpRvzCTlkDA1cngta1W9bc9d0AMTlj+RxVR28LqbeFNh5CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "5883CB9214B4FE1A0CE68774D714425DC6024D52", + "timestamp": "2024-04-26T10:04:00.956305413Z", + "signature": "8I9v/tacLKIUbkFI14kpDNE5kpEEq0u+E45oP/aW/fwS2IfSLFbRUGKmLhTVbHDQRDIOp3yFYZ95e+Yu84ByDw==" + }, + { + "block_id_flag": 2, + "validator_address": "6C6412282FB32525FD92617157F154579434F9FC", + "timestamp": "2024-04-26T10:04:00.966533734Z", + "signature": "d0AeYo/wIcuK23EBhKnvTX0nZwSR9n4R+7nGucKmbMWQOkdULMIIHAqR9fShSkAKdwhp6H8Cpg5aNonSjwMlAw==" + }, + { + "block_id_flag": 2, + "validator_address": "EEB553125D331715F799680FE763B33D4D8EC063", + "timestamp": "2024-04-26T10:04:00.910177954Z", + "signature": "Rr+QsR/0Dekjt5bs3RkjF2fogRNQiE6DVM5cYeNsWNKl/RhNrpRFkAs36toB4fzvODZWM7UjFMawIbh+Ez88Aw==" + }, + { + "block_id_flag": 2, + "validator_address": "DB2D66F06C70A06818910685E8A51C73E6EF3324", + "timestamp": "2024-04-26T10:04:00.915375321Z", + "signature": "dIuLN0L3qMFXj/pMjJcmz/LpJKnQ2QdEguoiG+e6F5wmSH5WJTuLnj8iGiNp6k8dEXKi5JhIZ3mZiWmmNjkKAg==" + }, + { + "block_id_flag": 2, + "validator_address": "07F4F6BEAC490B1508E93E38D9E5B3DC50716200", + "timestamp": "2024-04-26T10:04:00.929773802Z", + "signature": "vXV3XTSWuW5rtmDZfwgJLlbGzKZX6+OdMpYMmGqFqfinBKwLYuend3773Ghb2ttb3zAp0A8XC/Ayt4gbt/hMBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "32F529A962B3F9D7896BD858D9970E3C1392570E", + "timestamp": "2024-04-26T10:04:01.169994618Z", + "signature": "FEoAgVWkQIz2Wcsi3mI31Vq6evSgmd5/vg5LTH4sWcG7Vc6SEzDo0nVWJT2nIqJZ3z5u6qbwB4enV3nEyB5QBA==" + }, + { + "block_id_flag": 2, + "validator_address": "223BD658ADC0BE9E1A318EAEE26A927E9B782DFB", + "timestamp": "2024-04-26T10:04:00.962986725Z", + "signature": "YYB10YQ5FrtGrdQw56Mn7Ezcsp6w/Xlv6MPiDSzSfOXcQmej0XBGjvycpHAYHBChjJOjDES69kD/hKjDD3GMBw==" + }, + { + "block_id_flag": 2, + "validator_address": "B155936FBF30A4A21C2FD9B2A3CC1C2CACA9DDE7", + "timestamp": "2024-04-26T10:04:00.936798583Z", + "signature": "DUw8pS/NluFJ9BCizNe6tOWapuFgSpcjUMe/AXVBBc62uSfN0e3QPUMl/JyCoWJSzkMpqik2XtChlOxy+RXxDg==" + }, + { + "block_id_flag": 2, + "validator_address": "D0810844A5202004AE1249CE17610A4AA5A1684E", + "timestamp": "2024-04-26T10:04:01.006509656Z", + "signature": "sJ+CaXHMy4TvEC/FP96ruEwRumtUpMUix75oMPdW+Yafm/cYg8SLMSS0cAhnEsDZavTj4imxEymoO7nkj3gCAw==" + }, + { + "block_id_flag": 2, + "validator_address": "0C170D04155D212B97B3D33AD24D0076053E70C2", + "timestamp": "2024-04-26T10:04:01.002639723Z", + "signature": "ByY9zB6bgJ4whsYxYtuD6Ly6UjdSjqImiscPLCz2MPts8ayP59Hfcc3FzLj7q1D5/d0wdUM9mmHYgC6ai6BjBw==" + }, + { + "block_id_flag": 2, + "validator_address": "2859D4F84CABF0136BEAF3EFA339F5BF6F6CD39C", + "timestamp": "2024-04-26T10:04:00.959915232Z", + "signature": "5gDzBD75G1G/vKkTMmKVfjZvs6Ib+hgwTyu1pnVOUbNFCprqrxigdRlKuQoiB6VXypw0mEtsCiOTMo+B035aBg==" + }, + { + "block_id_flag": 2, + "validator_address": "195623E1DDC7F85D8E5015D79B9D0DA47A7F59C2", + "timestamp": "2024-04-26T10:04:00.929835606Z", + "signature": "f/EhOAX7HDi9kSnnYPqnKnQyjsLGolPzDQoVrHMDBVGjpoTrMokbr2pcBTMO8kIjoh26gu+a8R/5ygKAb5UxCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "8066E3C72BE72F9CD84439FFB59D79B2C316C01D", + "timestamp": "2024-04-26T10:04:01.006960346Z", + "signature": "a3qn5HeSsPPFn2Vj2lxoM9bg1ycjdYUFnsVLLsBIqCJGu/TpccXP4ev53R/aEV9eZ/fshw1WXuodQ25/Xw23CQ==" + }, + { + "block_id_flag": 2, + "validator_address": "7B0411064960AD679FC4A64A7066B401DF3C7F52", + "timestamp": "2024-04-26T10:04:01.00029083Z", + "signature": "u+vBrE/B0ccq/rT0lgiwMjiGAj6tCNr5qRTPf5aG+2vvJl6qhGm5WPsf2c2RlIuDNoD6tL+5drh/i+eW5hEpDg==" + }, + { + "block_id_flag": 2, + "validator_address": "7991CF87E4FF6C6D46376939E6E7214FA7473AE0", + "timestamp": "2024-04-26T10:04:00.928510912Z", + "signature": "SvCQZfN43YDRLAm1JAPozZvtHxqH7XXcOhQiXNXHL88UzCm/iDIIuKwaMTevIIJ0zrLmTge1sz8zZtNsZkZnAw==" + }, + { + "block_id_flag": 2, + "validator_address": "8CB1BE337D1427136EB8EDDD9232735E2405C50C", + "timestamp": "2024-04-26T10:04:00.962967879Z", + "signature": "JQfUPvYaMPrlulZTdOhNrGI2ssnwCyatsZoITIAraRde8Xy7s7epcB09wo55Kiiul1s2UFa7HWb+nCwDfaaKCg==" + }, + { + "block_id_flag": 2, + "validator_address": "83CC77F0F60F418B9DE2A24642645777D2FBCC02", + "timestamp": "2024-04-26T10:04:01.002090386Z", + "signature": "S5MsCg2KbV3tkZne/22iixKyEIKzTbMQ8tHhX7f/t4K9ActgUcdX+vBguK8r8ebr0gZLmYS7qWy0wqL5x096DQ==" + }, + { + "block_id_flag": 2, + "validator_address": "DBDE432B755C38F3136A75D2D3F530B5A74FBDF2", + "timestamp": "2024-04-26T10:04:00.93402786Z", + "signature": "F3UyudW9NgjQuG1RT2cy1gbKG4XcYzQUQoW7sr5ZROPaOWNsTPVtukFQiFepXSTCFn2LjGcxQ4nJuxWSl/e2BQ==" + }, + { + "block_id_flag": 2, + "validator_address": "D83516A8B94EA1DB899B7C80C76C05D0BE204004", + "timestamp": "2024-04-26T10:04:00.937974051Z", + "signature": "8L6eR9zHo9wOGP40eEhwEFSXS1pEjfa5RBNVKU3U8JR8BCNn85kU2/Luv4DK3l4MXOr2tqp0omdNqIPuA/tMCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "8F9C9F4EC28C7E06F3D348394270FCA69DBA116B", + "timestamp": "2024-04-26T10:04:01.010547638Z", + "signature": "r4aChcLxSWqaCI4UDHgqL6bbh0I89pQtqxPLeukjL7B20JEmkRa3Up8RThZomxYIXJoCh4gEwYUrdj4xxP38AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "F9F61FD65FB010A8C9365032D83CCAB9FEF69BFA", + "timestamp": "2024-04-26T10:04:00.94550454Z", + "signature": "QJMpuJXhUmU+KVOPR8CbVsC0xZ+fkRv4SUVwcn5KW66SRjSEK9vSu6ymyXbzzAcGnnlfwYevkaRCslwtUOwnDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "02425C209B7A5BFDA29FEEC5876E12AEC64D4C81", + "timestamp": "2024-04-26T10:04:00.958602132Z", + "signature": "Da5IT2DMuzmzBpTwwfKDtMrID+TVrmzu1MYYus9c29upsffW8keHLetLpNGrU9vv/B+fLhXaBT/iWrSa8GO9AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "37CBD9EAD6B6632851646323C2D9127E79B1C37C", + "timestamp": "2024-04-26T10:04:00.946524061Z", + "signature": "VY/q5c5U5D7/KhwUPHDpt9ZBbRALxzCrwsPputOBRO3r9pFTFdwwTkRaM/sF9W4ZL52z5F1UnHp2Rg9S3VT0Ag==" + }, + { + "block_id_flag": 2, + "validator_address": "1DA762F8A91B63B90817D5D3A20D0A3E8CB240C9", + "timestamp": "2024-04-26T10:04:00.934908911Z", + "signature": "L+VYhKS2m3Q2LP0KWnP+evyryu/6JDb57C1Je6Lug5TmOg7Ucr36N8hPl2GbdX50/H1NUu38jTAzR5Kgk2PCCg==" + }, + { + "block_id_flag": 2, + "validator_address": "012ED7FDCAFD53E87DBC4F98DCC93B73E30FFA2D", + "timestamp": "2024-04-26T10:04:00.955269129Z", + "signature": "0WIdmnyrEApyHUhPhstnMD7MyuoIj7PVpmzOc304PdI0lz9K0Vo7DDJ3izN2s+XV9zzEvT0yLWGWB0n20PRICg==" + }, + { + "block_id_flag": 2, + "validator_address": "E27C9D446FA6A9CFCE43802136CF958E7F939226", + "timestamp": "2024-04-26T10:04:00.987552691Z", + "signature": "StLvIyR2ii+q1t3dSjLDUla9RiMjkxR9kPPnvQa87MSyTSbIZ+QSMreSZgFUExGb/nFKUK8nrPugfBZHRH4YBw==" + }, + { + "block_id_flag": 2, + "validator_address": "0B854339BDCC14B85FB8711E41C2942377476F70", + "timestamp": "2024-04-26T10:04:00.920062407Z", + "signature": "+i62YTIYLZ3YZgkPA/IX0MvqP7rlRQMXZ3KzPzKpCJsoyRDzQGlACyjZdL7c4AoKKUASfuKBC4dglcjx+i1/AQ==" + }, + { + "block_id_flag": 2, + "validator_address": "9C3BFE7B68E53DFF9D3CF7B70E3B8115AFD42411", + "timestamp": "2024-04-26T10:04:01.130940819Z", + "signature": "OwyQkx0Y9KkjQCUNVp4sNpLh83PfWKJYvQ/iC3YIlwQYSSOmIbqcBjI8/7hoeDWs4IsAgamVGWD5Q+h19vepBw==" + }, + { + "block_id_flag": 2, + "validator_address": "ECEE73D95A77E41A4AC3148D75BE7AEB02CC147D", + "timestamp": "2024-04-26T10:04:01.00895827Z", + "signature": "0HRExMDh7w96SB1di3ey2CJ/M09vwRib1tWF69X4PbseE3Y7N4+L2PX6bpnVHnKVBYvpwnL8A9xKbO0iCnhbCA==" + }, + { + "block_id_flag": 2, + "validator_address": "E3DE542C5573C78253BF5DA6F20E2119C0F1BA48", + "timestamp": "2024-04-26T10:04:00.944774159Z", + "signature": "F1loC4gG6cDG+q9ipb4pwyqLFIbguLTLVZBrKWPeOg8UzQjrR+Vle6LaiOjpkfZMK9pA1qHGYSPnpDl9lKtiCQ==" + }, + { + "block_id_flag": 2, + "validator_address": "1A0DD1BA9B3EF21F6414210D0AA35EE0F9A12BE0", + "timestamp": "2024-04-26T10:04:00.962984232Z", + "signature": "pdArNEGhA+zfJnVyHStmoQBzKYDDu0khTz/tGt7VNgcxctDxTfZAvY1z+sP9Y//yZG3g3Z1C6GK/k6j6DalzDA==" + }, + { + "block_id_flag": 2, + "validator_address": "10AC1B41D924B67539EA8D755FB0158D57B0F555", + "timestamp": "2024-04-26T10:04:01.02376877Z", + "signature": "cOrYQL6byKizyYRsA+JfMtu7g2WwbFpUM3asC8oTSSt3WDe1qRtQBlnnamRWiS1FefFVMX5azVdqvoljOPHqDg==" + }, + { + "block_id_flag": 2, + "validator_address": "3E01DF5EF729ABFB3CB4E8CBAE5062D685009FB7", + "timestamp": "2024-04-26T10:04:00.975495951Z", + "signature": "MID9+MrXo8dyMqQ+nen7I78b06jX2CW1WmPf9eRBF8bhsjpdl8stftsfQVaCYtBIfG+uIZ+iF10Bnmp+ALrTBA==" + }, + { + "block_id_flag": 2, + "validator_address": "F5EFDE8E7BF30A548B847ACD250407CF0CC0539E", + "timestamp": "2024-04-26T10:04:00.931791944Z", + "signature": "dlc0DOtf+w8lmI5KdCTss6c26NjoZQTrqBqvRzB+oVfGWq9MZhrg2GJIIgHW53jZkSjmBeEL9XjPeFwlEGp9Aw==" + }, + { + "block_id_flag": 2, + "validator_address": "4C10504F2614BE17668FB7EE4CCDC9BDBDC5E94D", + "timestamp": "2024-04-26T10:04:00.909121611Z", + "signature": "1cAH+tE9U3gnL/t/Dxdreyrgv54YMd2l5V5Pd7nYIW+rpP7CHjr1ZJD3AWJZIgCuRVNmYNPX1N2qIfJx6o8KDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "E42A113076FE41D20780BC6F2FA1C700B2756193", + "timestamp": "2024-04-26T10:04:01.045395998Z", + "signature": "kY3u6KhwnPVWlxmZX9GwXb15M9HysDhH0/vblHrlRUlZIG1/27vMhZwV409JOIq0vrRZm6rjksturlj2f26iBA==" + }, + { + "block_id_flag": 2, + "validator_address": "A468764E5AC834870F79453F1CA26060DEBFA629", + "timestamp": "2024-04-26T10:04:00.949599606Z", + "signature": "NpOj2gNOjHEdiLDpkIPNG2pM3fp2oVN8Hk7ufd+vV8MZOCWXoHxb+w3ZpU0DVNt1n28Ow65Hb+5qJ7bGXE/vBg==" + }, + { + "block_id_flag": 2, + "validator_address": "132A20818488C9362C9E37E529B879CBCD6FBDF3", + "timestamp": "2024-04-26T10:04:00.928538414Z", + "signature": "VbG+NJWojagNUXVoV9d4DLVu6tDkKaDJriHvuzqYxrDsylLmKqiIJKOPszytCfmJhnmf5aWTfLZLIVL1r5OXDw==" + }, + { + "block_id_flag": 2, + "validator_address": "152DBAD504AF9B1C103D3D4BBBB472C45758F301", + "timestamp": "2024-04-26T10:04:00.996613464Z", + "signature": "xl1/aJtEZfaXOyJ9xy7LxzEvUdnscT4j+SA6G3FaViuwzcv7YLOIlWrffXyOr1G/GeZ4xN8wwCHsNntN3/FICA==" + }, + { + "block_id_flag": 2, + "validator_address": "2191940572E2B2E4F477DA155AE95FA3697AF3D3", + "timestamp": "2024-04-26T10:04:00.938635513Z", + "signature": "F8emLuO8J18N/YtKJ+8O/G6gROAXOBROk4XagQ0+fl8KWQHrHtJU1SnxQx5g73Gg4L+ljDRnohxVrQSJWWaBBw==" + }, + { + "block_id_flag": 2, + "validator_address": "AF28D38FEA9D6F1A8559AE134EDA0F1FE1509768", + "timestamp": "2024-04-26T10:04:00.956757179Z", + "signature": "qQpd/UxxpTrAWPMMFXYeZyEWN9k1fCYImhI3gefTZvV6SeAMdtxpbSEaRsndxDIlCGiSWN6rYqeh+1kC1O5ZAg==" + }, + { + "block_id_flag": 2, + "validator_address": "8D0008FE0C7A6EE7BDD1D59CAFFF96AE369C303F", + "timestamp": "2024-04-26T10:04:01.03429594Z", + "signature": "hYu9PZbIdsxh8Oa5AHiagC9GvG/X3in7Fo7+SGzBgCwYkDb/vEo2gLBKy+7Ht/QMw5QvExdiYgrLcmGVRLU4Ag==" + }, + { + "block_id_flag": 2, + "validator_address": "88102131B351CE7719EED9CADB15330217A9D038", + "timestamp": "2024-04-26T10:04:00.956670634Z", + "signature": "mjZQsF4+808V4ygfcISGy+tGui4wabhZSzITi5qPIJnOY91UfpLKxUlqz6VdQeOvLj90YaohaaGpPyDu5D4YCw==" + }, + { + "block_id_flag": 2, + "validator_address": "39BB490F1B1554AF3FB524CC89D1533EC5A02E2D", + "timestamp": "2024-04-26T10:04:00.930753233Z", + "signature": "BwiURHjTU8vj7c01KipvZ69/IdGkNMziGB9abpWTrp4uLxfF4E0xgtkfKyrj14hPZ7wrnNemxtPbTKDg8dbFCA==" + }, + { + "block_id_flag": 2, + "validator_address": "E7F7CE3DC63D23B2AC7A233A432F8C7ED74B23B7", + "timestamp": "2024-04-26T10:04:00.901633063Z", + "signature": "U7v9mgxeWsDlnMg0yhTHMd5ErxGbNBNLIJyggayARVyN1OAFSntfw1yFDYbMdslZiPlg24iL/lehzETjU48FCw==" + }, + { + "block_id_flag": 2, + "validator_address": "750CA8CEE4ABA1CA93D1E0A524F26DA8A64EF7F7", + "timestamp": "2024-04-26T10:04:00.928224511Z", + "signature": "OPrs4e4FhdGJm6h4GnB0GGv4njG/EqByupUifii1N2WaxLu4dhE3Bb3+yQkJ1hD6A6WEcd7VfUATDoq6rkdqBQ==" + }, + { + "block_id_flag": 2, + "validator_address": "DBAC8BF532C03354ED8BCA5FB7992EA14C1B62C1", + "timestamp": "2024-04-26T10:04:00.983152302Z", + "signature": "OuAv3OgdDwTACCwrjgOSoYHFZUFAs0LskoHmwC6KbQ3QVAVDYQhOSmXgd1JErK5SmH/Nlh3LgSzUzS7pGYxRBw==" + }, + { + "block_id_flag": 2, + "validator_address": "23D911027C3A30470D63EBC2EDA4D71C91412543", + "timestamp": "2024-04-26T10:04:01.065060136Z", + "signature": "TXpTvhtxgyNtRioRbxZ/YqZ7Axd92QFsUEGD0A5/+dCtZmbV/wOipuoFWOfeoz2AKP87BLK5FG8iV8V1Yh/CAQ==" + }, + { + "block_id_flag": 2, + "validator_address": "4B71B41D7DC82C7F44FADB7D527011678B14693D", + "timestamp": "2024-04-26T10:04:19.983903775Z", + "signature": "SiZiIQoi8XRjzDS3X3hKryaJxjbFYFKmuO63DWwyDMtdr7jFQ4/zgct+F96Yx8ulto7/LLQWg/7ZAk2EloG2Dg==" + }, + { + "block_id_flag": 2, + "validator_address": "3A0C2AED56A4E76E52616CD336FBC311B3799322", + "timestamp": "2024-04-26T10:04:00.979187289Z", + "signature": "y37Im9El3V8H2XMTGMSSscbjVP05WLaTy3f6c/yWF/ex4MRmQ6aawzL7MgUiWUBa0Gvpr9MYo4j7vCURi9TCDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "C071D8A87D78969620BC2D1AB55DCE5B683851ED", + "timestamp": "2024-04-26T10:04:01.013430573Z", + "signature": "FVG1yDs3yULzCxFcIfx5Qa/i+lz1uXlCeth910Voh08lasylY+EG0EOI2H1+o4B2uHunZk5W6BQQXTWGbOOGDQ==" + }, + { + "block_id_flag": 2, + "validator_address": "C875B64A69611343F68BD7F1B81C16F971876720", + "timestamp": "2024-04-26T10:04:00.924585366Z", + "signature": "2iZS/maCBiQ79nRc100I95P5EaY3kw+TMgzB0eXN7eanKzjSteiDryfTmYfc1BP25u8hGr/Nnz0yGzXaXq5jBA==" + }, + { + "block_id_flag": 2, + "validator_address": "180049B647B4CE71C46D70E1AAAB869B2114D0A5", + "timestamp": "2024-04-26T10:04:01.081809318Z", + "signature": "Lvesy8nsAoWgMaxigpno/j3UBxl99Ps2JspjnS3zJRuWIQ1saBAwvWJKg4foxZmPalJ9s+g15vsgwVUNnWLdBw==" + }, + { + "block_id_flag": 2, + "validator_address": "B6411041F5AA0C6E38612CC8E75BB70E74D0704E", + "timestamp": "2024-04-26T10:04:00.990271544Z", + "signature": "t8JGFD4AJD2ds0jBW5tUvXv1Zyfc5SjDJ9kDRQi30+04Y+ZOMMkRPF5aZPZ1Uru+3KzYKIyAoYJrFCIS4aAWAA==" + }, + { + "block_id_flag": 2, + "validator_address": "EDBDBBD2090018CE7B0CBEECB12B556269449EFC", + "timestamp": "2024-04-26T10:04:00.972281212Z", + "signature": "P9a6Nv974ZAAMqojXTi7IvGDNoiS/0x9bXd69RXOxw989IInbAcOqrXczcamEiZh1nMD2ImWSGTrTsfdFhzmCw==" + } + ] + } + } + }, + "block_results": { + "height": "4326863", + "txs_results": [ + { + "code": 0, + "data": "Ei0KKy9pYmMuY29yZS5jbGllbnQudjEuTXNnVXBkYXRlQ2xpZW50UmVzcG9uc2USMAoqL2liYy5jb3JlLmNoYW5uZWwudjEuTXNnUmVjdlBhY2tldFJlc3BvbnNlEgIIAg==", + "info": "", + "gas_wanted": "757265", + "gas_used": "543723", + "events": [ + { + "type": "use_feegrant", + "attributes": [ + { + "key": "grantee", + "value": "archway1y8k9a33967dm9n7a8u2d2l6q9m7teecvnxy0t0" + }, + { + "key": "granter", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "update_feegrant", + "attributes": [ + { + "key": "grantee", + "value": "archway1y8k9a33967dm9n7a8u2d2l6q9m7teecvnxy0t0" + }, + { + "key": "granter", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "113589750000000000aarch" + }, + { + "key": "spender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "113589750000000000aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "113589750000000000aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1ktka5q3cnsy3ar7qwj2huzz6qj9q4ys7h74l9y" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "113589750000000000aarch" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "archway1y8k9a33967dm9n7a8u2d2l6q9m7teecvnxy0t0/94677" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "B54RMpJ0+OgElTvjTOSVKThdJkZAusgvdLLF8kmDb7pleyQ7uJhrEFyVW6STVaN/hlMO+jZ/EABgCzKI/OlwUw==" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/ibc.core.client.v1.MsgUpdateClient" + }, + { + "key": "sender", + "value": "archway1y8k9a33967dm9n7a8u2d2l6q9m7teecvnxy0t0" + } + ] + }, + { + "type": "update_client", + "attributes": [ + { + "key": "client_id", + "value": "07-tendermint-2" + }, + { + "key": "client_type", + "value": "07-tendermint" + }, + { + "key": "consensus_height", + "value": "1-15231689" + }, + { + "key": "consensus_heights", + "value": "1-15231689" + }, + { + "key": "header", + "value": "0a262f6962632e6c69676874636c69656e74732e74656e6465726d696e742e76312e4865616465721287fd010af4640a92030a02080b12096f736d6f7369732d3118c9d5a107220c088ef8adb10610e9f1f983022a480a20fa84823025b069f879138b00389e1c484ab7f0fb9ae6da4e45ea59fc89ea779d122408011220b21fe4d365cfd7b5bc5e880011757dd1a9a1a2706be63b1ce8b503b93caae1b4322061fe323ce9bfa460a8c93a8525d876268897f47f20764f751ad2599a2320b4c23a2091d5c4b4c02274384b25ad410d0386884d2391e5cba6fe21de5beccb8a4ca1a74220316a6e225c96a5db5921fee3182802d04731588d62f1bb4640f14b0f16760f5e4a20316a6e225c96a5db5921fee3182802d04731588d62f1bb4640f14b0f16760f5e52207186b4dd67b243e05e4ffdf3c07923ab7e244fcffa09739f6f4f7d965dc47ea95a2021c4cbeb94c8ba1d9984c516a8ca3d4afdff597b60db722678d3a27f012b265562208c54c5896d160d092c92908e8f7cd1263562034b80012a7b525d22156eab64606a20e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855721404446da0bcc4310003f97b1bed07ab2abec6fea712dc6108c9d5a1071a480a204f71051510f962baadb1d679ff0a978c9a9fd818d6715d6d7b9acedac3be1ebe122408021220509edf671f8e1ea4f6559a4a35d88f30a1738f5a95427ae0614cbcfdcf24fe75220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214e08fba0fe999707d1496baab743eab27784dc1c51a0c0891f8adb10610e4e6d18303224035327ea064893598a4d0617e7cd1117d2121b0eca46ed12c8bea8d36568aa79e43919a25772e8dcbe342c9705aeabb97a73f44a3c5ac4e492cd62b7999231305226808021214765550228cf309bdd33f3f5e768350ba3d69c3b11a0c0891f8adb1061098e9e59403224096de3daab773476eb62752fb2e4d63dd73c4ede61446c77ae31e45e7b276124331fa9ead226edfabc27120faec9803d1745ad88fe7c959e3f9f38e937527ca0022680802121440cc723314b6ebb93b49fbd9d330eec8b4641cab1a0c0891f8adb106108a9d98b50322400b88e1b0d33531c52b379f9279d8251fb15171cc141bf214e78a8a55f9b1149a66bd2bd12ff24e30992decaae8a3a1998f53742e648898853e3aba30d2080c082268080212149d0281786872d3bbe53c58fbeca118d86fa821771a0c0891f8adb10610d2d5f9b00322408f1424a4dbed8374c110c22f13518830ef637524687b65fa4d1b231e2e6f4e35d52d2e274a69b096cae52bb879257bca9d78b0765710027c67510539d250530d226808021214d82343fcd5a74969c0b48457d70e8d55d8f6b8011a0c0891f8adb10610b387b8ac0322406d3cf979884ed4e8f4ca4bb464b1143260149426ac66aeb09780c095f887e09f56458bd698be01b94ddfc32ab0cbd84a9159ec5fdb7cfbdb7e53f6a8d968230e220f08011a0b088092b8c398feffffff01226808021214a16e480524d636b2da2ad18483327c2e10a5e8a01a0c0891f8adb10610e1aecdb80322406fd85ab929d8deb0a40b6ea72ee802218a7d2d07eadb7017327dfef8a795a8c99eec3304fab4c4dadfab48dacf81043aa93467dbd6e851a15a715547f49f860c22680802121472b1489efb57a680577a838a5baaebe162a7c8021a0c0891f8adb10610bf84fcf3022240e857e8e985d3758d1523731690e83a2f90a61c28e5250f991d3db31bef265e2abbd0ecae750af9c30e0c5b0a1c42c5befdf7a738a5025ac310d3db23d998230022680802121451d7d05a659208a6576190aebbe8f076038515151a0c0891f8adb10610b7fefaf8022240998172ead4c8892842eff1a032e916200557c7adb1701568953c00204123b738191ea45f61f2154ec0e4cac32df9995a4ab84135439bac515c560869d491490b2268080212141b002b6ebeb8653c721301b1b56472b1b4de72471a0c0891f8adb10610e7b4c9a6032240eeb67cd9fc8512c440e25922868dd20c131f064cc79e82e2b4b0c85515aafe009e85279eeeea9a16af406f473cc3318254ae882a37431e4964577272c82e8604220f08011a0b088092b8c398feffffff0122680802121471df8d9879c20563a4e2abeda95cd1fc57dbf6aa1a0c0891f8adb10610b9cfe69c03224018b001e64b9810adf981891c57e7ab018b10142895b919aca989025bdf802ce58f947934d9d3b7bd1a1dd7ffc419cb9d112a052ae97da42ba29ec70d8efd2900226808021214131fc79e7a012d9e7eef21de3ba5d5033fcdbc1f1a0c0891f8adb10610f1d1b599032240fb4960a60de2daf510fc2777f3ad73d5b00f7571bf266fc8dfa150391fc1e092218c325a9d2511acd6fefba6d5e355efcf30c6c667f4c8c3864a79cd8de63a0822680802121439327692c258a57970ef53f0aa4d3c00f95988b81a0c0891f8adb10610edb1f3b9032240508e1963519f789b56ecb9c7794ebec98e853eda94f3efb45245c2e2d948d5ec87a9330bcf8a3ab64dbcf94dac99a353d455dc79c8f2617804f6c3ab663112072268080212147341e970b9b3eff82b2060d3469fc50d7af041461a0c0891f8adb10610e8fed49e032240f73753edd63b4e3aab14be8813eca7a36b2bd04dbb2b9978d6eebfe73227bfc95f27c19d650a79dbc9df0c21f40e112251af684e5259e9c9c689f9f8b616790e22680802121403c016ab7ec32d9f8d77afdb191fbf53ea08d9171a0c0891f8adb10610cf84b597032240164f7f95c25f2700ba3d74cea4008e887455ffe1bcea5b29a075e99d2aa9720e190030375fce7f8447fddef25d5e4f7b8bf0a11c37ada0056baeae2cc82fa6022268080212142022fe8cc49e48630c76160e11a880459219d2441a0c0891f8adb10610eaa9bf8b03224064d4d530e8eeb6b43f00c903d4a8c131219ebe6e616dc8fd013fd58620de72b5685db749bbcbd41ac52a831e82345ee58a76d03c755dc601d578a011e2210c092268080212149e7cae009efff4d163f3fb8781a07b25c2b10b321a0c0891f8adb1061095fbd3fb02224012901525b8130fef68bc5b085af891d1acb496034eb083965d350b4f15b7972c229e88fe1a47831f237dd4e39f357d04e07f903da26d0eee921fd9cac0ee020422680802121499063b919404b6950a79a6a31e370378fe07020d1a0c0891f8adb10610a3f6f681032240c835bc34f6455c18c40f8badd414fcb63b7572f382cd976ed693a2bef0373ac8874a8f187918e0a911a39990f16ad65ea3535f4af78e8a55586b84c9ad141d05220f08011a0b088092b8c398feffffff01226808021214768a82700e3046e6daf849664579e649597cc1b41a0c0891f8adb106109cf887fd0222401c50667f268cd85515b1bea91158e0c1ce935882c0679e60b236cfd91713ea95b23c91526455d4b66d6db8387cd9bc955b568d9a1de32413bef8cf3d3337220f220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214a06b5b682b425ad206a35caf246fd70dd098e5061a0c0891f8adb10610c1b4c48b0322402b85295ab044f714c57b95f3f6b40b78b98b591fe50874d15913d9ea2e2841ff7004e24ad4d9dd27b0ff3deecb5d9cfbb42eafa332372e1b63d82e83d835200722680802121497afe45395b74e784c88d45e5cca2995019fae081a0c0891f8adb10610bcc0a2ff02224050eafade9940b7dab9caf344e5e96268395d7f69678c8f29109177af1c20247b28be3d3865d8bf62c9b7a171fc978de7ce16dfc61398289914160745122d3c062268080212146239a498c22df3ec3fb0ca2f96d15535f6f3387a1a0c0891f8adb10610d9e5d08b032240faa02bbda92a9c452cb62d5ed8fb052f0e1db81074860330754badc0251c615c2b1d35e4bbf7e655c9bf3aabc421bcd8a0740b309465b95411d3d87c5b7c5a012268080212145f999a4be254869925a7f2fea04d7b3b836cff0b1a0c0891f8adb106109281b8ac032240bac5a4988555cf7a2e660f3a696d73e1683dcff0d852eae524e09177be7b6019584558ce05ebf04dd5c47636c9bf64026f0e4d93963726a4179ea907fe3cc102226808021214f3f55da24bb47da60b0fb71ec1a9c9274bceedb21a0c0891f8adb1061096d5e8fb022240b55ae21ad9ce84696339ecee3188b1d352eba8780c4b41132e9f08e9d145cee51cb5b28241b4295218487a17ab52f20276583410aefcde421a3a9d674ecbe30a2268080212149cbec8cbd4ed3aad4bb2b0346efc86a6c41f91601a0c0891f8adb10610ffa5af8c032240d24d90d8aa31b6e3473f8e7b6b84278b4aecc82ca3a1b168610235b064dfbf4213a6f5dd93d2eb7e98ebb505e3d032da5fd37d6a968b7657ed8eab54f016270c226808021214af195943e44fe1d6250076b8bc1910eabc85f1f21a0c0891f8adb10610a0c6b4f5022240c8ec28e525957d21f312767bb350f03ded8b0d759a423bbcc82ed91a6da615451be9995db0169970643a6b85dce2999b56f3cb02f2e935b7468abfabf9ed9706226808021214dbcd765db2640631946c1393ba255876c76da38e1a0c0891f8adb10610b2839e90032240f25a0add9cbfa661b6b1a17cb718458749b0ff8597db807dacca398fd1d87c9562d363c4e848a9200fab70e4693b2d08239ceee283f013e9992782ae152542012268080212146912e0ba38cd00c9f2fc9e71e971eced507b42fd1a0c0891f8adb10610cad1b89403224070ea13f1efdebdd8f7acced0d94207488547157c8cd798edf8ca02237f4141caedbf3b55a327f9fe43660d8eaf785e3aa836458bc9d0db257ecf79be8f2daa00220f08011a0b088092b8c398feffffff0122680802121440c48839cd487d8a13d65955b7fc6c4f560d8f721a0c0891f8adb1061098f9d7bd0322402a10f9417c421db6221e6df25e0010c886aad9fe0c8c5169897224332bf3ba83b04a3a384ae15a8d79cecf90fc582f4b035b12a0ae863378478cc754db5425062268080212148e0545b1222e7b5c85ce69edc78f280cb2b79d181a0c0891f8adb1061088caa99d032240b0c88ba835e45d58fa57eb1261df0b3311150cbb6558a0dcc79d9741483b0c195a7172ce05fa79cf540d80034ade62ff611e9456501ebb5e8fe28ad653ffc405220f08011a0b088092b8c398feffffff01226808021214b0b35fed40daa5ff9d4bc685c75925187f6221191a0c0891f8adb10610d8f0dda30322401c1ea5a8d41b5e9e6229060f39be76b42c75eaea378b4ce75eca859992622e83405d185d777ce5d924809458fce857bde3c9739c33450be9cbfb1132022f2300226808021214138fd9ab7abe0baed14ca7d41d885b78052a4aa11a0c0891f8adb10610d3e09a97032240569d806618ca27191dc778400919ef531147d690f007e7c34dc1899e3d14afb65f4ef07058e94f12bf18e30e473631186954d3fa2348ea2d32210d7639288b01226808021214273f72ee55987afa771b27d370fa131f608b83ac1a0c0891f8adb106108ed2ab89032240265bafa5aa803d430cfdc89c235c25d9f344867273c8b9576d68c3a0ac8c0e27a5727dda4adab0cbf8520762b24556d23b13ba9886032aceec7477ea3746250f22680802121495b002de67707313d123d06492f1a7a58478e5461a0c0891f8adb10610cddefa91032240af3d55e92358e505af6459a8a167a8b78d9096af24e6e7e3ab866541c2769a3430a6ee731cbe83ee856d9b0bc2d88dac364ad9aef88d2704a9867d53a29b1501226808021214f9a968a405fb0429410ae5165e5f2193271e678a1a0c0891f8adb10610a6ded5a9032240788012f336f358d1354a01f3e0ab41bb064b53368c85ac04ec7b55dccc91cbd1fb2c59ac646f90b084534556baa1cf9ffd4c6db04ff354a32ead32a556474302220f08011a0b088092b8c398feffffff012268080212147ef244868c304aa5b34889372e2df874afd635cd1a0c0891f8adb1061093b2f2a103224043ab7fc8ed921d4cd9c29916494521de167810650c38c71b7e8d894da96e6a9764e0e8e0f8bfb9fc6e6003f0dde39d251fc7e38e055e4026d0305a4d1a9e030c226808021214e191e654d06b9f721568bb945b2eb51ddc1c8fdc1a0c0891f8adb10610c5ac9af9022240a5bf82bb80a2bf0bbae6bfe7f22e325eb101df6996828e9781dfd61c5f18874c8eda0494e26baa14b89f26a58b57868353c034c9d7e91479d480bc1f1dca4f0e2268080212147e0ed7689b65c345d1c817c5b0332fd132de58751a0c0891f8adb10610ffc5989a032240ee344a36aee1b2496738f682993ada9ab61f20c6e84a9309b08f48e981f888fe23b5331f7ab5ca4e08c8faa62d0c6fd3c7e727e5435172dbcf6bf7ce3f8d5d042268080212149f8ec2ef581ce25630c819f19b5484039e748d1a1a0c0891f8adb10610a3dc909203224031c45fc5bf389914643547967db7d47601ba8c4601fefcd0898ca1ce3d4fa9c8457c3ac03c2562510f5c6757d83b5839a31df4df796a586678d3e3f4e480a00e226808021214ca0f2a7121f86d3b6d91349730155b9a5a31c5541a0c08a5f8adb10610effae6e40122406ac382e3d67a5a377c748995ea236f67b7741ee2d7df3fa0ac2a4254bf5fca660111f06d4cda4a63653f57f100cba8574d3e67dd19867ad8a2c9313b926abb09220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff0122680802121406f45c36fcb957e55d923a6d4e905c2d715115ad1a0c0891f8adb10610c6d6a1a90322406df4ddd2ea44ac04c84434f059b1a85ae29f1a60edc32646cf19ffa9a78fb32f36c894de6af8f05098678784ea774425d0b72f76deb439b363cd836154688b0e226808021214e12cef3871b9595ef15401eed2466e9310e4816b1a0c0891f8adb10610b596ff9803224088e627f8666d3e61a493c234d7a8cc9cc13ca845eb0bf90054e37ee993dcddeb7d4121af655cfac3f0578bf6c6e3e4965f928591869b370356ba4c16494187062268080212147d53d76f2db86be30a9b26cadea69078531ab9bb1a0c0891f8adb10610e2d39685032240d7ba6eab2465cb57cba22c1abbe78af76dc53e6f305bc25d46e4844bf754de1a962deb771db177fc4e618136182e5a86f4223399416aebd1e4c8bc51af0a2f03220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214d8a6c54c54a236d4843ba566520ba03f60f09e351a0c0891f8adb10610cccb9895032240369d05ce6ad8fd7f69d1d236d27f58cb8e176c8758dfb4ff5e5d5def48f524a0d700f1964865002931b47a2efc2a4220bb473c18c316586c163ced2ba5f1de0d22680802121417386b308ef9670cdd412fb2f3c09c5b875fb8b81a0c0891f8adb10610b7fafa9303224090d9d8d31c9fac1ef366e18f729100f61606b3ef1caa926c3e440a8a1bc0caf4e0b80f2bfa32a7689f38ba71ebc161944be983ab9fa84a2f30a860e7e0035209226808021214e03b985e6c8905e184d88c995cc632aa278981eb1a0c0891f8adb10610c9c8819a0322405c222d7678b7725cb3eb9b3489d3f2c55f2ca9c956371065950150e626eb53fd309e632fcaf1125b53f7a63df215ae7255df67418cde5c1fad14c99f8500b106226808021214c9e615289d1d92e50292c3b0bd8358d9b2e402901a0c0891f8adb106108cd2e8f802224019eff3f8b212f2c2c94d1ae88c880852cc1788ef466e8ef72faf552d760c6ae6b0bf6ff9c819fe48983116a00cac06eca158237ea6f27855d537a972c8b36e09226808021214f6c3f7872b046da7198905e6cb58c1b775b48bea1a0c0891f8adb10610bf83fd96032240617afa857800cdb3a5790713024a5b0e43c7acc56abf6628995cabf800df383a18e7ee31911846bbde14d84e2e3ee2e12f96dd9721126f21d26bb2024b6adc09220f08011a0b088092b8c398feffffff0122680802121446dea137cfb10bc419b2577aa9a58718680e18ba1a0c0891f8adb10610df8ef0c40322402a9a17970656f7466f50cec46a6596b1a4b2149897d5225c7f1cca7d35f678992ad56c2bb71c6f72f7436aac15c6737eadd736a199b5153f3c44a8abdc962b0c220f08011a0b088092b8c398feffffff01226808021214692174b3ffbba80394a94dc92665dc0144fba8371a0c0891f8adb10610cef4c5f1022240263cc4067123e2b67a0a5c1c9278bfcb6dc8b3871663e0c8830e64e92b3a6bdea1f23a6410b498c0bb96d38a5364041c7581125e97b0aeb49abb254558e0090a220f08011a0b088092b8c398feffffff0122680802121463481f6dcaaf733d2fc953a335c2200ee190862c1a0c0891f8adb10610e9f9ef9b03224089cd37fdbfdb689c288fa34346db9f291e344734f725068947d49c8cefbd6d45ac9ea28c9522443075e61ba756856c978d3efb4be3f88ff781f0e70c6430b808220f08011a0b088092b8c398feffffff01226808021214712bc891aeb721da72732bc30d531e0c1eaedae01a0c0891f8adb10610ced1859903224081124027c8fab9d3d100a26a67d5811a50df990ab89c32b9f1936326ceba0e674a9f26de3df44650b65e818c6612ddda601c37365f03f10bb0075ead7489ef0d220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01226808021214943547cacb29c55797e121acb4e586c49d9d39fd1a0c0891f8adb10610878a9e8103224027a39fa84fc80d85f2bfa908ef87dd12e3735371bb72bde0f4975a689630333ee6e0a3e5c10479413563c24739f201f35ea2ab5a05c7717eafe295351d5291082268080212145fecec9408a2710833f2f7d848339462c29c14441a0c0891f8adb10610f3ca9c95032240aeb5d2fadaefc8cef419f17c3dadf6dacdcf8a54248f91a8aedb228ea6b30d9a05998a8ab94c0fe351bf2308b7e190aeefb762902de9e7b357ff3325fb96dd0a226808021214d5b93190771a50604a5f7849aaf067c4a9daaf9c1a0c0891f8adb10610adf5fbbf0322408c83556b1f23529c9a02795314e77c24b2785df2e3e2f8d76e36179cf0f19685c675b1cb685000b1d6730330a325a618d4924a00054fa7f0728349e6068d8c07226808021214844290531ee59b40feefde5259857368bf7119ec1a0c0891f8adb10610b8d3cef4022240908a3cbc7be316c1e817ee80f120b3ddbb73e7ade5bf25240e85c8c1219c6d23ab396784885a16516b1e39a65e4671756fa5e6ebe6046663f7deefe1b97850022268080212144e154c9288e31436ba814dd92d17c4ed6cefd3f11a0c0891f8adb10610df9abda203224090bd48d03377fca3b12e367a4ef84040ea7eeec4d3d37d67d9132b21b021726a75141ff99417967355c93d593a8bdaa72b1c471ebd9b8fc940a6566d5e622e082268080212140a70912d18e13d78cb32e6322a4e57f861e6c3c81a0c0891f8adb10610fd9aa9f20222400f08a14d220c43f1221ce4b1a56257a69fe984bc6b5b61e31b306cbd0ccbead23720a9973d532f774f21f57d910d6abb828de0e08355ed1be8c5ab22dec2620e220f08011a0b088092b8c398feffffff01226808021214b5c33a409a589c094e89f77d24139f25c6a6dee91a0c0891f8adb106108b86a09e032240932dca4fa80b4e41d58b115f9c4bff67f851ea47b94a648782849a0b06cc346ce41f1197f77f4984787d0b7a75bfb947108d62bc83c23f6e2093b42d5949360f22680802121469d0605229c665974ebb736fc77e16245c3f79aa1a0c0891f8adb10610d9ccdefe0222400847955b24a0700aefe48afa2c062213b141039646212f98f95a944f903971930eae4c65ee437634c9f13410a69341eb2da12a3cc19f78a1949ef489da4974032268080212147fc1da40b2568ddbd53cff3b76c49ce89ae286801a0c0891f8adb10610eda9dc8703224058c03bd034647383e156ad9f5bb302104474806937de9cdebdd73a2086ec0b116b5d2ff535040dbcf6a7569a17ec0af7862a89caaba33262e051855a02a4b707220f08011a0b088092b8c398feffffff012268080212143e88e7c54f64642a98b2e1ddd5bdba48794f06c71a0c0891f8adb10610d3d6c1910322400eb497f103951ee5b4290f6f279cd3e887bee7088840f81d792f32e2fa9536c9d2daf1e55178906a1215303f8c00b3e9a98f3bf4c2d2abdd8795613fd651de09220f08011a0b088092b8c398feffffff01226808021214e5cba199e045e7036711d814e57e2b66c3cc03911a0c0891f8adb1061092d6df9f032240e90820842e245a8a5e89f06ca05f055952d9edf0dc25e827e537491125adb719a5aa7ac9d56b72e7083e4ae61451f0feea98947acb53f9e1d6769e1a9396b602226808021214894c56d6cfc3a8e09eb6d1a2e33467c4cf77c0f51a0c0891f8adb10610d7ace9a40322401caf0c34a54b9439b0fa19f6d7037a0d9d563947e945c25103bad6c6b21d4380ac0770d9c44669e2e39d9f8df9f94237fbc7fdf526deffb969c07c24d4021208226808021214c8969171f9b5a3354c712a20f007cde0648c990f1a0c0891f8adb10610c8a2c3f7022240289d36ff40a058f788a6a315e350765089117de8b48153f39048a12827ca8cc2243f3b6010b04cf449ebda57af228a2c71e0edd9d30dafa737cd178bc03ef705220f08011a0b088092b8c398feffffff01226808021214d4c41c1e17e9321d067ba4e3e476e766b2c2c2bd1a0c0891f8adb10610f1b2c5ff0222400d79c8aab526fa90859929b1b38b7516c428e4e7eccc4235aab0798124876114153e7609ccef2fb17346b213fa6ee4e4f31cac0a4f4062938ef64cb6e2a0c60d22680802121426f7777bd52918ae71801022b0e2deed97ddd5041a0c0891f8adb10610c8808d9c03224005dc4b69224fa7bf9f17c70f83c943807b067824b5cd76330f20961936bcad3d4d05c3f44333dd67ffa37f421fe7279ec4221c7faba11ac64f89d287fa99e701220f08011a0b088092b8c398feffffff0122680802121415fec10416e359cc1ddb424c69166b2671f251481a0c0891f8adb10610cce5a6a10322404b94cc63ad988877ac555fd0c1b54ffbfffd41f9437b412112011ae78dc4ffb85baae00bf09717e84c657efd7af1b6192194bb1ffbdb19a3f5c991c4bc6ae00b226808021214000a5959634b4296e4de536481de00a8a0eb9a581a0c0891f8adb10610d7b3a4980322406730de9564744d7b5438a723dadf9ec1efcaaced27a4ae3fb862ff184efe7fab8590aab76400c8a8b17ff580d1beae7599b588da5546a88275979b232296fa02220f08011a0b088092b8c398feffffff0122680802121460a433d28b08788c72e2133554bd5cc68769dcec1a0c0891f8adb10610c1f5d6b20322407024a827bc739462d72900e0b1fa7a63b73ae8afa3bed9f4e650cd3cff0c5cad338238c8a5879357f40b25b98b489fcda034f617c04759f25320293c562a9c0f22680802121406aa34bd6d1dd34119e3dc173efad94f430ab74e1a0c0891f8adb10610ceefe689032240007571e60a9a3c8c8ab1953b08230f9daf262abdee97914374317108eb3dcc492c7e6e3a19e1c2c7a8aa4a64eac0d084585874f24bdd974c7e80f974a2d69f07226808021214c9b753ed297e5f9894d4a43149cfc9f7b207b6b21a0c0891f8adb10610aabaca81032240f2a90890bf1432c1b4d343766e2dd9b34691d1ba06b07b63c969216b6f9a50e62684915f4dd790e113653387f9b68cb05528059e01d4b3b301f3560dfff5df0e2268080212143ff6c988799c1adf3aca0da56143c8163890859a1a0c0891f8adb10610ff98d4ab032240c7df020d87d2ceb62a8c106bb28a2455e88b513fe6fa6ed00add6fc68ed20c6889a230e2e90619c39fcb46e7e9bb0f0f449d13aab91d6d7cca5f298aacc6ae0b22680802121499938495407c09b343562aaec3ab551a5c2462321a0c0891f8adb10610819b8487032240df176419ffc31c5be1a972917d04cd35d6dd95ec237160b14c5813a38a0cbd431e0affbf4b871443ad18a66ed7e12675ae33c32b31efffafd1d9b0e157630f0f226808021214901fd122cc512ef13de8e1a3d7953bfddc0786d61a0c0891f8adb10610bcc3a6f7022240b6f807acad0d6bb402b261dfbdf3fd20a7262ac12252ad54b3f1b48fd3d8e94f76daa93039542cf43be463a266217947564aa5a3b7af9a0be92acb447efa480b226808021214f6783d8fb30e283081c16398293f482dca0e912d1a0c0891f8adb10610d9ca9599032240b44e28f14992928f8ec02e570fa3d6eeb0c063db315dd1c7e2dbbf7c5a826644bd15ea3f18c281015865f038033602ecb7bd91942cde6a0f856896b293b1f501226808021214a9c4e0e2af00183da11434ed413219905e9a868d1a0c0891f8adb1061092adfdff022240e00406d588efa60f644ef2d478f6966cdf7c8b62774c8b0d093aed5220da3ef4ed96496ddfeae7e302dacc35f72e2c8a5b01efe7c2fc240926df6f8e6a81b40522680802121419ec0a155a5be755e76d0059ef730ebca122b4f11a0c0891f8adb10610afacbdb2032240e39dc930607c7902afa961f4f06af45c416e2f823644bbfeb89eb256b8cc4c9a1f690d30c35e52f4cbab58654f5b0df6efde712e605845cf1dba8811db3b1202220f08011a0b088092b8c398feffffff01226808021214e06dadeb413829558f7c95339ffb61499c5a1bb91a0c0891f8adb1061080abb1f602224016accb54f00923474a024c4445fe1a34b11c97c15bf48c8e169fbd02453a6c2607a5ab4f96917748ca654ebcc9eb2f0fc494f464b0ca70daebc1127c1d9510022268080212142d159b72d40c1c1daddf24d2511200001b74ed841a0c0891f8adb10610fce0ccb9032240857c93456b8e7ae097d1dd2e8b522fe7dfd500ec6376404612ae1f4f49629ece71ad7ee155c6b90ceae26cdce4c5ba4e77d810663281cb7bb58bf55568d68008220f08011a0b088092b8c398feffffff0122680802121496da375d8a293f8f6580da36ea2376cd89ab20c41a0c0891f8adb10610d9b7f78c0322408a39a4c904e39d916f68af2aa9eb909cd688b8174e49774fa05552bc4e7143d117ce490463ddd7bd716f24acf4429130a2ae2d8f6e3e010ea2fbe8349ae1740a226808021214ce485517649e4f8c71469ef7dafcf9a558bf167f1a0c0891f8adb106108884abab0322400cabfb1fad5ddfe3f9e2e70072305854af2a2f1dd008d233b0ba4fb98aa9d229c41f2657d36871aaff32cd133160a45fae891df2b07b24cc85808d19fe886b0622680802121468275c37cff86bb53d29d6237ad370e8fd5097fc1a0c0891f8adb10610e9ba9c9b032240d137d1170083edf35f03f4e8bffd6d623e5b824286126f5b601fa4314d462804f69af3cb459694217a34c6445a4de4aa099714a05969d976025044572643b206220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212146e705424231dceec337eb451bc4c1d2c5fba48c91a0c0891f8adb10610fac9decd0322403b0b6bd8df17b57047639b0476ae3a5f6b1756292bd01312288866ee21aacbd3db637b4e70de1df21b838d8c582385536e6f363466c680d8a79384c23070c701220f08011a0b088092b8c398feffffff012268080212147c5aa87e5203c66ea35c64262f576edd29bad9801a0c0891f8adb10610e9bcdaa203224038bb0b5eb43117343cdbad85f636c367e053283427e6b72be36d0ad576d0ca7333d1234c11438f752d5822ce52174b1181ffd9e8e595046a9f42bc73cd443008226808021214451acecaa7dc4cce6e0b7cde02f455df973535e51a0c0891f8adb10610b6e4d4a00322403001ecd8967733ceb833f6da9c439818ba4bb4549e3e599a8734e7329bb77b16f16590d9db7440dfa847f86904b9229f8896ce895b26218c0fe00386c6a3ce0c220f08011a0b088092b8c398feffffff01226808021214583ae736e67df9d72fe87b9aa7d3210d3b4b0e5a1a0c0891f8adb1061091fdeafe0222407d864739f548cad9c514d41f9be988481b58aff9caf218ce74e7b32ba49e5da01c258f1828a990ed7daaef7a12ad1d2ed9ace2feedae3ba20c874f95a6e07c0f226808021214c5ed122e511ff9d7dea986fd7423c61aeb139d341a0c0891f8adb1061084b7f193032240cbbc875f3904e35924b8cfa947db505c8eb0b39dfa85849e40ba28cbc7890b437fa912ddf607d60db846027cead238561937426f6821747260d7dcbc45dc6b072268080212143519556ae84c5dcbcf6fdaf05fb644e40ff93c371a0c0891f8adb10610e0ebbea9032240136b25183906df2d45ef463cd5c1157833847623c9d6393351fec112faf0c89b68f0e2b5e70fa1385f2fd384f6b46b01ee9491872eb0accd8a12f07a82e30c042268080212141fada14dee843b733ecd5de2e74552ad234a54511a0c0891f8adb106109aa1c282032240f93d89cc8ba7ad2dbec4cb56e966632883bcb6ceeac1414cf9cfe762d676ea8a9e6b9ba2fe9fc0c981c5bd59857b323df3cb7b58b97cf40794d46df5279e2c02220f08011a0b088092b8c398feffffff012268080212142d387d95e13f681d33122e4475f9b7dfc2a68f641a0c0891f8adb10610cd8eb79e032240c2caeaa1ef37a1fc7f5e1c27aea2e168fd8b37df0408f4784b40978d637a7b318f21bde939f107df47257bd6200bf8559992b9e454e3a387c04d2ba19f4bc30a2268080212143ff719f1664bee93d482b480677c03a47ec0b6431a0c0891f8adb1061091e4df8a032240a182be9b395c0f8d04bfbd8258fdab670516671667cfb4671f132370dec7fb25fd0dfd764ee19751255d5440d10904519fa5c7f1160750b91a09fc3075bd3c05226808021214c02acba7653ac3782750b53d03a672e191f003611a0c0891f8adb1061089aaba9903224027139e3cde1fe0b20d18a1d7ad6bf40e130b4249f747c4e5e87d61bf09ab7704b7fceb7f8b3b7d353c0cf8c4bee5375c7266ac7aa426547b9bff79accaf0c90822680802121437714c4da407c9d13cda424aae78c3b28515a15c1a0c0891f8adb106109cb6d49203224006e1ec69ebf9d199c94c662b4c8bff3130d99f5d5684bb9f85364244f0a251b5cacf23b035785d8f90e5e875a9687f06babdfd684aa54c6741b050dee65a9d072268080212140614088c41e6a85fb5bf344552a5120e5a0139fc1a0c0891f8adb106108abdf084032240f4a94213b119bd23500053c63950aa37be2813331fa370610a29401c3dee509539a7d1608cb941b5ab2c63515446173a3849784aab52faac59044c792ba09f06220f08011a0b088092b8c398feffffff012268080212144146fd7a1ab8b861b7018978bcd13d2d1fa63ebe1a0c0891f8adb10610998eb89d032240379e6bf3735417ae3426c33bdc34f5844ede6b2af7809c87f888b98d5578b64607d99245f50c673fbde331e97bd74b2c2dbb2c9b7a23dbd16c86f922289cc7092268080212148014ba212ed388597510d064258f5e30aa30d5911a0c0891f8adb1061096958483032240ea651d5bf13f73b49c5cc1c379816365130774a62a88665ac03da82b6a78217e7d586c4e9e9e6f472d84b79a2b678bc94bba3acdbec7b6b58bd0a6841d7b8a0b226808021214373f86cb3755a1de78cc69d3e5f7ad5d7615b85d1a0c0891f8adb10610d59fb4b4032240bae9f3005dcef16c68d9e1a6e7d67deacd59bf1de564e224889f38dfd5f069cfe87e3da89ad93fdac22530e0717870b0c607f7c8c65f92e663374ced0887ad0322680802121422ba59ac2918afa4c1b56d3e6f86083e470cd8cb1a0c0891f8adb10610ee86b8ae032240feeca01e8afd7a6ea4d539472c4dcba314249d73b606a3469466f55c04e7d6386b99d2b2f760d111c92b234d9a114bf4266dadcf5cf6da3ae823e820b8fbd2032268080212147364be6cc7b6e404bd1c2050ccb6a7472786e3b61a0c0891f8adb10610bafb8c9c03224096a85a050ac1ef4ecd99b26ad1689cf7ccc11e7757d3b303b19e35d8ed4daf04f5ca2003eb4e32793bbd4a4b2176baba493a02eec486289455b7ce3c5c491f07226808021214972a684f364cce31469b37a9d439985115eb5a401a0c0891f8adb106109d9a858403224003e42967b586cf7aea44ad05eb82f7f55518f951d5bc2fac880f6e059bebb8c807967d02930e48571ddb0276fefe410e793353a99138f1e0445cf8e9e484f202220f08011a0b088092b8c398feffffff012268080212142f89d7d3d1e1478f88ef3ad8aad76a88189f61241a0c0891f8adb10610d2cde8a0032240493e1869c67f0a6cdbb0336929088b7987921039c810fbdbe68e7f3394520c9f77b5cf2ca8f03e735842c52622326d4696d6a9c259ef8e3b24835378a99f8503220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff01220f08011a0b088092b8c398feffffff012268080212142dd6d22969ee7c2ca1f8b428d13a8995c043044c1a0c0891f8adb10610b4f0e9c70322405e4fa9955d7bdfb1d01aa08303a214c96f773694d0cdc0887e4cf4f5c454c577581360ecf9320818eee835aa2805341c818594fcb9b8bcdb7435ce17b10c07082268080212149496535a8f2945bdb60572015d2d6f721ab6fed91a0c0891f8adb10610d2c2a987032240aa7ffc88a7319bfaab41ef4586ba2d7d800218efb562acf637cf90b78ccd28cf66c19d698a8ff624db49533b6d58cf1d39a61fb23781209b88f731c96f14840b220f08011a0b088092b8c398feffffff01226808021214b15069e41b1a60ff03ae8d8f741f78c7b1144fbe1a0c0891f8adb10610cce4f5fe022240ad41689cc023378457e12e47bde57832ccf72eb6eb00b594151005b5cd6a42f48c4d98c450b8154d7a5437d7551e66d229a5347e225e3174f09c7eb5df436206226808021214d0c2071d6f2fef021dbd3f5f1f72f1bf30a467b91a0c0891f8adb10610b7d19ef2022240b309c58d2afd98da14a927f45e4440fcbd85b80e771ec713216dfdf118a7cbd15c6e63b0d4c397811f82c2c5bb827afd36e3bfaf9a39d79ca6148dee281496012268080212145d564f844d411694b131b1c4a4fd3b389494f48f1a0c0891f8adb10610a0abb9a803224064cbc081c0cfa9b31019d6114732a8f4e6a46549621595396a19316e05717f752ab011d53f4f29e57661bd19f0009735808395d87fb73d41a487b3034389d905226808021214191e896a11c0a77a96a99abee986a2a40355c0441a0c0891f8adb10610c894cffb022240418448c382555a70b8112a54af3a8521b8547ffc1aead1f31b1bb6d40d6e86689e9b38d24e59f704d415c5436f7685068e2df370cb9e5b90c5866c3a5446ce0922680802121447c89621f47ba7ff2362c1b2f97a4f6311b646f91a0c0891f8adb10610bbe5c3d50322408f89f4199935f12b4307768a8a8e1bea50048d5079f76a5a6275300613d31923f8c10eb7a5e2fd374762b3c56fdcfbbe3b5172019affeb12e0817ce9743dfb06226808021214f0c8b6addaf7cc4ece57086607a9a0c7ea6275e01a0c0891f8adb10610a3e689a8032240dfdb55a803ac7cea544fefe21321cb5429144f9bb3bc11a1082db28efccb55fad97064d55b7a34016865d422b0988544de06450fd29737693e38d70f23ffa70a22680802121420658bf40ed48ed01a2d087c7ff7874f21a563331a0c0891f8adb10610b3adad8e03224045bf5c2e0a317b1852b740a57d726220bafdecca953466cbb78b6ea58b35475d6f41c88dbabbe7df126c4216225a1a3775e4f2967f994daa7edd107686ccc70d2268080212142335465b27b9548313aaf465217787fd8e6113d31a0c0891f8adb106108cdde6f20222400139b937efc50cd563dbd8011211e1b13fa47abe176f483b3a0effb4fc7577107f254d84f21423a5bb2d0bab7846230db9a6652b512425102924b51dc7e5f50212804c0a3f0a14cb5a63b91e8f4ee8db935942cbe25724636479e012220a20e8dcf4f58187cf05b18dccc6d0884ae08bf4a98d88717d0fff92a2b6f4574d4718a6bf9b0a0a3f0a141f7249f418b90714bf52797336b771b5ad46753312220a20b1fd3b167a4803d77810f675179821d28a5c6c9881eaee96cc61d9eeaaba1563189ebd920a0a3f0a14e08fba0fe999707d1496baab743eab27784dc1c512220a20de0e4a0ba7c9d98611a0de7cde629db2d2e2e5e830b760a4c91d32896211950c1888808e080a3f0a14765550228cf309bdd33f3f5e768350ba3d69c3b112220a2056dc9cdd103251ff6f5a1439465b1075a40d14bb76d99158c6f48753a77420a718a5c8e2060a3f0a1440cc723314b6ebb93b49fbd9d330eec8b4641cab12220a200609deffc6b7a9425f2cbe1666f54a14763a165b95125a73986ed70aa046690018b8e0bc060a3f0a149d0281786872d3bbe53c58fbeca118d86fa8217712220a2075f4c477afa4ad6633aac05ca6a771c92abe8b087b4867309c13bc5da5b6a8a618ccf3e3050a3f0a14d82343fcd5a74969c0b48457d70e8d55d8f6b80112220a207fc4e3176964df4b4c1ac8c52bf17b2e0be3cf6e1dde187112eba14729c43d5b18eacde8030a3f0a1466b69666ebf776e7ebcbe197aba466a712e2707612220a20c01db94ad2f16f3983d2e4e21621fac724997741f5de4c9a9cd52fbe55296b7e18acc7a5030a3f0a14a16e480524d636b2da2ad18483327c2e10a5e8a012220a2061dd91607c82d08dc6df864c95de6bb3de1ee12e4bd539d66810da0c8861a52818b2ce9b030a3f0a1472b1489efb57a680577a838a5baaebe162a7c80212220a2070d454aceb78239ac972c0158543a206f38b611485c7876ca36d9b714121b6721882de80030a3f0a1451d7d05a659208a6576190aebbe8f0760385151512220a2062eb1eccaf40fe2bd5798425f403b4d31eda4b89c593111b8a7c191e1b2054f818d5a6e2020a3f0a141b002b6ebeb8653c721301b1b56472b1b4de724712220a2081a971e0937b15b8c5dac7312a3d2eee1d69c0d43f3723eef7aae121eae60bab18e3b6d4020a3f0a14d24b7a32413338c2aa26fc0016d91fbe73bb5eae12220a20a7bbec0268402a52a3ecc398131e47b74374c06b9ad0e9f7e56cd6eeadde161e188596cc020a3f0a1471df8d9879c20563a4e2abeda95cd1fc57dbf6aa12220a200c2261f753aa87d3fbea0602ef5a454b37747319efa910f267afcf2c565f80b118e0f0b6020a3f0a14131fc79e7a012d9e7eef21de3ba5d5033fcdbc1f12220a208dde03c27dc6aea053730369b9768e9a07b580dca36bd4a6619b28e9ef31007018e1cbaf020a3f0a1439327692c258a57970ef53f0aa4d3c00f95988b812220a2055983a8520d191a7846ac4fd06e62ffda350d744682cc7931307a2b7229536bf18a8da8f020a3f0a147341e970b9b3eff82b2060d3469fc50d7af0414612220a203bfb06eb87e63bdfeb9d17e425f0990cd9bb298de279133cbc2539842772533518a99089020a3f0a1403c016ab7ec32d9f8d77afdb191fbf53ea08d91712220a2039d5694df2c2bcfc812de13a8cdc5eb20cb71e0d48880fb5eb9952bac64380bb18ddf8fa010a3f0a142022fe8cc49e48630c76160e11a880459219d24412220a209eaebea0305761228b211daf92c39e18cf62553dfe46d23258058452a70ea0ee188bd0f9010a3f0a149e7cae009efff4d163f3fb8781a07b25c2b10b3212220a209bf9fb4b564efa452d23bfb18021a7925a3989780c748f50be27f655cbc7623818f4fef6010a3f0a1499063b919404b6950a79a6a31e370378fe07020d12220a204f5c29e442f3bea54ea819ba78662241059ed13682d8b576053847695c61feb918e7f9f5010a3f0a1416a169951a878247dbe258fddc71638f6606d15612220a206fbef30a1fd5b11815bdf197b96e1d07e0e18383eb3165810b91b62bfa85822518a4f7ef010a3f0a14768a82700e3046e6daf849664579e649597cc1b412220a2036edd800b9957fb92f4576c20b1962c1c3c7983f2f99132bf50dfd95b2b8d70e18bcfcee010a3f0a1404c83aa20f7563bbcbcf6aa150ef6b0c81808daa12220a20f791cc0d6e74d3ab2c879d0d3bad6a4978fde19a915c67b54daefcab2eeee99d18a1e9dc010a3f0a147edb006522610c58283e30644a14f27bcc0d32ed12220a20cf3656640a5109a097d58233650031707479257fabff3589bff9d3ee67a4e2dd18f5b0da010a3f0a14a06b5b682b425ad206a35caf246fd70dd098e50612220a20d34546b9914079e9e7fd97fcad8a8da30c949d3ccfa37cdcbbf2caa6d1889c7518cf88d3010a3f0a1497afe45395b74e784c88d45e5cca2995019fae0812220a20647d935af93b6ddf0c2e30c72c8b6f38952ff849607c8b493b85785e75de755c18dfddce010a3f0a146239a498c22df3ec3fb0ca2f96d15535f6f3387a12220a20fe4ed7f1810e1371ed442f751aaf6b5a1dca75d93696ce60c9e5138598eae03a1886f7cc010a3f0a145f999a4be254869925a7f2fea04d7b3b836cff0b12220a2014fa59625697d678dc64d5d2f96d29026ddab8faa8390e9e7286587c4501779518b2e0c4010a3f0a14f3f55da24bb47da60b0fb71ec1a9c9274bceedb212220a208e371214d150f2afadff11ebd6e61d236fdcd6c3f0003d7bb8a83e0323964dee18ebc7c3010a3f0a149cbec8cbd4ed3aad4bb2b0346efc86a6c41f916012220a206fce05c68686e24f4829060da73a87d7a9c2037e73980ba6ae1b523c9bcc21c718cb8abb010a3f0a14af195943e44fe1d6250076b8bc1910eabc85f1f212220a208f8321eb499cf5bf3c1f8b823a998e4388d893305b5f8d71f803fe0855a6dcdb18cfddba010a3f0a14dbcd765db2640631946c1393ba255876c76da38e12220a2050ddda931e0b3714fafaf5637f4d9dce461be673e9d976f5881f55062b311de8189692b8010a3f0a146912e0ba38cd00c9f2fc9e71e971eced507b42fd12220a20a3502e5f79a9b874ece86cf806853c47d263d3ccfbfe327ac95568a9cd95149018aba4b7010a3f0a148b1d5676f4c0c871a0c7864850d451d6a8ac8e3b12220a20b6a687464d7092ea873237cdea40d2d72994e556430b55cb98534521192da37a18b5b3b6010a3f0a1440c48839cd487d8a13d65955b7fc6c4f560d8f7212220a20bba89921518cd62976f9e6a2b21b8233580e8c930994cea63cbe6dad65ac6daa18cccdb5010a3f0a148e0545b1222e7b5c85ce69edc78f280cb2b79d1812220a20bd8353656c4a85edd49fa805faa5fa715077a3f286e18c4c0b8fc88114cad33e18d0b3ac010a3f0a14c02f531d9bbba4907511ef2680421ce714a11e3b12220a2023db1f4a9b6c7e7c0438863c7d14f719ecc088eb3b1fc8a7fe607496447fac4e18b3eeab010a3f0a14b0b35fed40daa5ff9d4bc685c75925187f62211912220a20c3f71800b9f35141df3f4123fcdd0671693c2a5eaae7e0a722ac5bad7e00daf918a6bbab010a3f0a14138fd9ab7abe0baed14ca7d41d885b78052a4aa112220a209a66109b69c09eb50a2b928dcb7d45095f6504c97dfca81195ae2f06c87f257018eb80ab010a3f0a14273f72ee55987afa771b27d370fa131f608b83ac12220a2018f96b749e73fc46d76d429cdf121c427f8b394d54685e24ca4ec27ef7a9849818fcc4a8010a3f0a1495b002de67707313d123d06492f1a7a58478e54612220a203c0f91bd2a554dc016043ffe9f15e5b472da39d694cdbae93467e331a93fbac518debea0010a3f0a14f9a968a405fb0429410ae5165e5f2193271e678a12220a20c168ae411e8262ad92df5a20beb0eb603f2223757572120b27ac627be26b449f18fdbb9d010a3f0a145e809e91eab69d385784d191140e9c8cf6dd103712220a202c20ade02052ae40ef4831d6301eef7a9619e2cc28ab5034acea6644ce3e63a71887919d010a3f0a147ef244868c304aa5b34889372e2df874afd635cd12220a2002647063f76a3d20570d8fd83bf86e3e89222279ec5e6d21fb0338391c108af618cbba9c010a3f0a14e191e654d06b9f721568bb945b2eb51ddc1c8fdc12220a204888a709fe062a6baa1b5bb4d44642cbe3cd63f7fef2c4233f0ca71b66a4920f18c6a59a010a3f0a147e0ed7689b65c345d1c817c5b0332fd132de587512220a2045f10c8fe0408a0f3e6088f0225aae19603b5513b508c7e2827e8fb7011cb7a918cdb498010a3f0a149f8ec2ef581ce25630c819f19b5484039e748d1a12220a207768735ffdf0ae68edadbfa300a514bcef7955e7a3751a314c775063bffc80ba18f29996010a3f0a14ca0f2a7121f86d3b6d91349730155b9a5a31c55412220a2040b4e0084232d339f67f9d7d4fa307bda88af7ee76b104e3cec9d3c39f75e9d118f39395010a3f0a14966fd89b1db51535f2d898cf9b0f14da374efb9612220a20465758a584028f6e80799abab47eae0b4c92a7dbcc62bc08b89a30c96895693818cfc690010a3f0a1476f706ae73a8251652bc72cb801e4294e2135afb12220a20bcdc9ae9179e22c81347787b70dab4b83c085fd65c9f84b1fd9005416f684bb5189ea790010a3f0a1406f45c36fcb957e55d923a6d4e905c2d715115ad12220a202ce51a0d34b46194bbd078c1c2bf4045ead73176d7c453ec4b1438eee36602f018d88d90010a3f0a14e12cef3871b9595ef15401eed2466e9310e4816b12220a200b79d897e14b01d6e44e4aef3fc3a181dc94407e03a480f9a53dbba128fc5e5a18eba88c010a3f0a147d53d76f2db86be30a9b26cadea69078531ab9bb12220a2042e7a3b3d0df9c2b201849535f150bb25014d3a7386f3cabc43493b4367a54ef1882af8a010a3f0a1420efe186da91a00ac7f042cd6cb6a1e882c583c712220a20fc99fa517d1055654eaae120e51594c4c91447c43d751c9cee0926bfdd830494189c9487010a3f0a14cefe7d654b523dea2a9ed718a591126c7417168912220a20245043a3bb3f3655a7a08ea16f2e1acaab2d4b3b220fc4fa29a6f15530d9533d18829b86010a3f0a14d8a6c54c54a236d4843ba566520ba03f60f09e3512220a20f1846413861dac13d754af618222d829bae09cd51826c1867dcf0a77fb4e5aea1895a684010a3f0a1417386b308ef9670cdd412fb2f3c09c5b875fb8b812220a205ef60c3c37dfbc78650721fe4f698a0845dccca67416851058fb68bb4438d7e518d38180010a3e0a14e03b985e6c8905e184d88c995cc632aa278981eb12220a20240f81848de789ef6d47e9510836f79f2641eb4b5b8475e1ecc356a536ab26e2189f8e7f0a3e0a14c9e615289d1d92e50292c3b0bd8358d9b2e4029012220a20816b7aabef362d1da73161e8ee4daae4b18bb17cee6466a3650545caa933ca0618dfa37b0a3e0a14f6c3f7872b046da7198905e6cb58c1b775b48bea12220a204780e053ea721ee174ed3a32dcdee5b03342a0be58820c8e130f37d00c17056018a3e3780a3e0a1404446da0bcc4310003f97b1bed07ab2abec6fea712220a2030a3d1f6e481631b82b300484ea1aed0c503c7f3417763ca3e43b266a65309b118c4ed770a3e0a1446dea137cfb10bc419b2577aa9a58718680e18ba12220a2024c1759b31bc7e3d1ad204a5beaf6d3f56832fb6677135a5feaecba2ba32b51b18ace4750a3e0a14f194dd4a8ad83323c3e9c2a93db25f049621c7b412220a20a1ba22dfd695c326a9db618d1273bfc55dfd2afbfefe78d894acea5c31d0feee18a3ab750a3e0a14692174b3ffbba80394a94dc92665dc0144fba83712220a20fa27065157b26cd698738de23432f48af7269bdb7dfe25a2dbfd40738175adc518c396730a3e0a148445cf55cb51278e63b2131adb65a81dc2389d8e12220a20f7925a8c92547bfe5d332151387406a5bc5b68ec008447d0dd2cbc3b934be667189ff06f0a3e0a1463481f6dcaaf733d2fc953a335c2200ee190862c12220a206770347c291a291d3dbef0d3ef1d7c23621ccf1bd5a5ece4b0fa6c6322b59f6618eedf6d0a3e0a142712cf68af6982b4bd7536b94cdd0d104a0313f412220a20e0809a9daf10bc212e01c5e6fcedf92abe931444164213fa294d6f0b23a6e78818eccd6b0a3e0a14712bc891aeb721da72732bc30d531e0c1eaedae012220a20a24b638d97169fb79d8f1d786e558eed5d668610a482f05e817cd7583f6cf5a0189bc86b0a3e0a14bd4f80f0c1a67b4950772662f6ebcad58a25893312220a204313e1cd7143fe17815536a4f3499bde0d1c00de1fa3788801f1a1cd6dcab64b1899d5690a3e0a1468a393c7ed496871150c0a7cad0cac09b8e458fb12220a206d4d66dda0d0c31229a8562e6e3648852bd80a26b531049f4da697241837f27c18afb2680a3e0a14943547cacb29c55797e121acb4e586c49d9d39fd12220a20f9629f36e6e8a02a4474913dddafa428c7e7fd88c9862f4307969964d4bd769e1894c6640a3e0a145fecec9408a2710833f2f7d848339462c29c144412220a20092485a5e4e61776e2e90e061d39d467dd3b8211d3433af6de09bf047e37f40118ed80630a3e0a14d5b93190771a50604a5f7849aaf067c4a9daaf9c12220a20fa8b07c0107fa92f6b2c3c6f2994815818e88e870919f7c5af44147b4426ed59189a89610a3e0a14844290531ee59b40feefde5259857368bf7119ec12220a2038fb199ef4f2dd2f74ac0f24bf615010a9858a04e7e611dd028a74a8d660353718abee600a3e0a144e154c9288e31436ba814dd92d17c4ed6cefd3f112220a207746dd5053e9a341e19629331c95112e8217bd489412f3b6f2ae089dc8cfcbd518eee2600a3e0a140a70912d18e13d78cb32e6322a4e57f861e6c3c812220a2006a6acbd97c4de13c3b27f683fe800b42892339bebae87196c995af276a1a80518aaa95f0a3e0a14e80d1f5519a5b3c9d290d3ea314fa05564535c1a12220a206c39d4c79d4e0a531a063b729c4dd12e609bd2694f9646962d5643066ac2d547188ffa5d0a3e0a14b5c33a409a589c094e89f77d24139f25c6a6dee912220a20fab7fe2b2e8475fa64e64a9d36ebf7fa79fb9a85a66d11425702e0330312475518e7a95c0a3e0a1469d0605229c665974ebb736fc77e16245c3f79aa12220a20fae63b08b0b55a3d7afda479d2fc372dc25bc08976fc5ff3a2b6d42212aa2bf118b1805c0a3e0a147fc1da40b2568ddbd53cff3b76c49ce89ae2868012220a20e5bd157cc917235604a2da99fc0bed4fc4cec2ea27efe46080a2f867a6f66d9818f1f05a0a3e0a14da4af19a378c09b54c26c3467cb0adf88929295412220a2074e936a54cd5647abc24377234b3b21c7f64fabcbf5efc65eddfef662bd8134218ec97570a3e0a143e88e7c54f64642a98b2e1ddd5bdba48794f06c712220a207ae26e6ddc29d163635fdc4f55161c31a04f7743423fd98a28c71456d3e1a90918b08f530a3e0a142c2467180bba84f2f1d4565e66f565a34003ee4f12220a20b5decf8ce19ca9af58ae969e37cc7b83aefdf9397f8168a191124618bc241f5d18bff5510a3e0a14e5cba199e045e7036711d814e57e2b66c3cc039112220a2053d278baae62eb328a1e445e50ab0c7ad252bf208dac26aa2c80b2228a97504c18b2bf4a0a3e0a14894c56d6cfc3a8e09eb6d1a2e33467c4cf77c0f512220a208864359c180879b0a2967090c2ba9ff64ccabe80310f30327f58ff0474bc6f3f18a9bd470a3e0a14c8969171f9b5a3354c712a20f007cde0648c990f12220a20adf42dfaf009e085fe92901a0400eb1792c93e3de94c16ac2c92f87cafca8c2c18bcc2460a3e0a149cbf2effd5570b3a9a41346244757cda3e18d40112220a203f04eb31298aba5da5f317cddd1980af2c95bf6f8fbf01bd5e96717f855ce2e318dc8a460a3e0a14d4c41c1e17e9321d067ba4e3e476e766b2c2c2bd12220a204a8f6a0a1999e845ddbfd2bf57559cb8ba878633dd9d8691dd6b79f5fa022fdc18be88460a3e0a1426f7777bd52918ae71801022b0e2deed97ddd50412220a20cd8a1cc7079a9999ba18e13834c67e57368fa5e19da1222c908038407a3efe8118e7dc3e0a3e0a14f233e036248a36fc73c154ffa79261bcbdc4bb7612220a20baa8697cae1a67c31a4c2f19c43e318607205c30a7928e1e77acc4773ee30deb18a3fd3d0a3e0a1415fec10416e359cc1ddb424c69166b2671f2514812220a203a324933e9423e8e7c94d5838040ea684e8a9aa2045c68f89a7d41fdf025994718ea983c0a3e0a14000a5959634b4296e4de536481de00a8a0eb9a5812220a205d80af85d70e966ff983580748efbbfe102e090d2464f53b5cabdcd42e5ed54e18b882380a3e0a144b65255857e4393754f049dbe945c5ac87f563d812220a20d950a6e1f7252e5ca5b4a99c62e25913af94819f87b4bd6e85ac67462b6d5c1418b1d3370a3e0a1460a433d28b08788c72e2133554bd5cc68769dcec12220a201e8df872a211c43bb6f22a1ceb8fd5b8879b7ca792de6723bf3065fa6c4266f118aeb6360a3e0a1406aa34bd6d1dd34119e3dc173efad94f430ab74e12220a20b95650373a6194c59e18456f4a26cab57f4d3c277669caafa530b6c5023b4dcf18fe99360a3e0a14c9b753ed297e5f9894d4a43149cfc9f7b207b6b212220a20404a57c540daba7bf6c269da435430d33612ff31c239adf02482264889e18dac18cbc4350a3e0a143ff6c988799c1adf3aca0da56143c8163890859a12220a209776967a589fe2a4b09f1777f0f731bce07d17ca28778a01231c108dc29bfe881892a7330a3e0a1499938495407c09b343562aaec3ab551a5c24623212220a2012f31aeac3e9109433f1ba9a94630448ebc32aad986173e8f7e89bdeaabe9b3f18c598330a3e0a14901fd122cc512ef13de8e1a3d7953bfddc0786d612220a205e022ed655f7d7c2d227296ba022f3463025889a0e23e9f27bbaf7bc6f12ec5718e39d310a3e0a14f6783d8fb30e283081c16398293f482dca0e912d12220a20d9cb95a9421bcb4e7bc59f2776fa2c0a4ddfba8bf30682462ccc81ef826c64d8188caa300a3e0a14a9c4e0e2af00183da11434ed413219905e9a868d12220a20b579e685431c2326c86fd5b39b1e6d88b0f8c688c641ce62adb39c35bfd14e1a18e685300a3e0a1419ec0a155a5be755e76d0059ef730ebca122b4f112220a2079acf837378aeafb95dcb3c5700e19dd4214587c06480ea748d7ca833d311d7f18a3cd2f0a3e0a143749086b6d85bde3dacfbe4485e3df95e709b6db12220a20d7ffe9e33ffdc09bfaeaaf5705975f02b762437f26e0bd871687ecdbdac6e3f118c0942e0a3e0a14e06dadeb413829558f7c95339ffb61499c5a1bb912220a20777a8d93635ce43cdaa5144f349fff7636fa509f1c465251b58c5ee3c4255be818d9fe2d0a3e0a142d159b72d40c1c1daddf24d2511200001b74ed8412220a207163b2c1debfbad1baec5b898d3c979fca2ed5d201359b5aa9229b1fad96821b18f09f2d0a3e0a140ceb917de4df1c4b4f8edfc4ace6fd6d39f1e61e12220a20d578e01a2bf304f866055801d4e205a67ef30abc1c4d869e9b2bbc83194124d018d5b02b0a3e0a1496da375d8a293f8f6580da36ea2376cd89ab20c412220a2030197360e96eaf5f9b5464d777ab6e1de1b12dadbf859e612bc6204c92c6171318b78f2b0a3e0a14ce485517649e4f8c71469ef7dafcf9a558bf167f12220a204d686b80b7be4fe2c510b52a507cdcbe6168454cbe03e34bd59bca20675cd4d5188d812b0a3e0a1468275c37cff86bb53d29d6237ad370e8fd5097fc12220a2051abf57604223a142e097b5c41b43419dd362115018930f598e807086afaef1118d4bc280a3e0a14e23afcf0035fb01acd02fe96f680066974d7072b12220a20d601d0fa5338d6bcd586ac6fc0afe096d20c748880d8aceb2aeed126b639afb418b7d3270a3e0a14e242db2cb929d6f44a1a2fe485cc7d3f620ffaeb12220a20b393d2e4dfe27218cec720e8c11a30823a990a113743fa84c1e4c82b74a7fd7e18b9cd270a3e0a146e705424231dceec337eb451bc4c1d2c5fba48c912220a20bc3910b78ef23877f10175f5253094d9c7fc1fae0c99de514d6c46236da1041218b0fc250a3e0a1441b543e91479a95cd5ca9f109c26dfac149126fa12220a200bcf2ea5bb5ee3af29e959d4631152b55ba0695f85ce2e82dd87242b8970a6021890b3230a3e0a147c5aa87e5203c66ea35c64262f576edd29bad98012220a2063303ccb21d2bf29aa0a996b874af9d13d4346194db1c9b12b7f10e13d14e28218dfa0230a3e0a14451acecaa7dc4cce6e0b7cde02f455df973535e512220a20dbaa8e762cbd93c2e05a4205eab0ceaa0b0597bcb4fea2e0367f8d43f41856581896d8210a3e0a149127dfa61750dd1d56cb1d2a88f8831a2b3f9b0e12220a2022b43613ebabee0c6193beff81ac47c43d033f2211596d36220ba8e7b1ffdd9c18f7ff200a3e0a14583ae736e67df9d72fe87b9aa7d3210d3b4b0e5a12220a2043e39d798df8ea39bb8c32d0c57066fba79465bf0c0d29a788e47c755ab9df2618a8ef1f0a3e0a14c5ed122e511ff9d7dea986fd7423c61aeb139d3412220a20e46d6c3bbb10120804a4d4cea154c6023904ebb5b998bef0d3ebb9f65793776b18f7cd1e0a3e0a143519556ae84c5dcbcf6fdaf05fb644e40ff93c3712220a20866eba71a55f2d51c3c0ca1760de4b6abd0bc7bb79ece9eae9ca77d446a3dcea189fa71e0a3e0a141fada14dee843b733ecd5de2e74552ad234a545112220a204d83d58408b8fb9eed8d39cdc23b4aaee403651eb39d86d28d282c274520b11718a5a51d0a3e0a141571038b5aaab431ec011f6ab1094463c6ed984212220a20f03f305e4319f5dfe9f3ab0ec48cecfd4bf730c6327abd40323e949ce29d716d1880bb1c0a3e0a142d387d95e13f681d33122e4475f9b7dfc2a68f6412220a20e17d393a4c8e3f540a0a24c57d9b084131e2ee85ea894f45b4dfdb89ba670ab618e9e41b0a3e0a143ff719f1664bee93d482b480677c03a47ec0b64312220a20809be43cb887a36fb5d89246a6b87056c0010125f35cefdd496b67934cb0341e1896ae1b0a3e0a14c02acba7653ac3782750b53d03a672e191f0036112220a201c6dea720e32a82ce5046e4da98b596912ad569e5629cc67113419af419326661894891a0a3e0a1437714c4da407c9d13cda424aae78c3b28515a15c12220a20f31c0c1100c8e31a03d99df4d1ff2fa636f891b61056e779ed1816865aed06d318f4ed190a3e0a140614088c41e6a85fb5bf344552a5120e5a0139fc12220a20c30b1b43a9a4130799b766613da9e741aa7f1629b5b03be218e750a5ad20c80f18b0fe180a3e0a14cdc018822747024beafd10a45abecc7ac19cbab012220a20e520358447f8fabcb99fba8e5a3c6b37b70145fc1bf52ab03e66f0233124017918f7dd180a3e0a144146fd7a1ab8b861b7018978bcd13d2d1fa63ebe12220a20aeab33dcf6b9fc06e90ae40425497f9a1ea8cf607f99b92724ec5d553780914318acda170a3e0a148014ba212ed388597510d064258f5e30aa30d59112220a20c4fd38b1d83bc7066a3e93986a84c88ce8428108d72b969d8208502e990fe8c31884d2170a3e0a14373f86cb3755a1de78cc69d3e5f7ad5d7615b85d12220a2060ca20064ab1ad2b4e9a374ab9039f5296d483d382ed2b0e4e6aa04b5663256d18f8b9170a3e0a1422ba59ac2918afa4c1b56d3e6f86083e470cd8cb12220a206f60d53412eb2055e4435f565e66f39542a1fac42b05a498d6cf2148f90514c618fbd1160a3e0a147364be6cc7b6e404bd1c2050ccb6a7472786e3b612220a20565ca17b5443d0c23d38435b6cddb28e64d3b552604986193a248d0be93426e518e8ff150a3e0a14972a684f364cce31469b37a9d439985115eb5a4012220a2003f3653f1603cc8ddc80d66497c5526075c17bdd010afd6682a7795fcf1e618d18b9ca150a3e0a14e20004515311b205618fad504fb529a3deee2e7112220a20a26c465c7f397649867ac4391b0432d18299eaabe6fbfd9ef1fc686a194aa2b418f993150a3e0a142f89d7d3d1e1478f88ef3ad8aad76a88189f612412220a209c20fbc290606879b909332fb16ae8e16f4e0e6bf3bcbce9858a08026496e51f18fac3130a3e0a14d807a55c7d69a84fb759fb0bd96bb4da50adba2712220a203e5af5f6a5b9082eada869be15caae91da9252dc51b5257099554b0b5382b86d18b9bd130a3e0a147e11ed7dd06fae7b0bedb469721151f2f31cbb6a12220a204c769c063525f04c7d63616b94a32b8f9a196e8abfb15a5358cb5a9b0516968418d1ae130a3e0a14da96564d2379acee00dd9faa558681bb499757fd12220a2085970175f1508b3d02d443a410f92ac02e5fa7bf358ee0739ce72dbc5008b3521880a8130a3e0a142dd6d22969ee7c2ca1f8b428d13a8995c043044c12220a2070cd875336aed8bdc3db4eb72ca2396069877216bbf6ee6f990156c8aa3703fe18f292130a3e0a149496535a8f2945bdb60572015d2d6f721ab6fed912220a2078078050a9cfbc6c5bea1110e15c7354efba656bf2aa7d4e8edcc18eacc12b1418f3f7120a3e0a14634d2f5ed7c9d82f42298d8922304d1b4adb20f712220a20d83196705de4b81d0b640cea0782e0f1b5c00e86fb8d46e37b07a8fbe7ad788618bbde120a3e0a14b15069e41b1a60ff03ae8d8f741f78c7b1144fbe12220a2058ac62882707e85b1e71847be0e73ea357f5e19dbfeeafa4cc9b83dbdc512ea918c99f120a3e0a14d0c2071d6f2fef021dbd3f5f1f72f1bf30a467b912220a207d853241b6851a9f0d5d7b6ea3f132a27550db5a5a1afad4c8290b0dcd4c6eb518ebbf110a3e0a145d564f844d411694b131b1c4a4fd3b389494f48f12220a20b83c55ca97fa78478f5c2b4507cbf71912ab5f11b12d0ab1a863ba11104d8b5e189696110a3e0a14191e896a11c0a77a96a99abee986a2a40355c04412220a208c6dd838fccbc443a67c2db137cab1aad17e0352062ef9f5f40853be14a6a2bf18c0c7100a3e0a1447c89621f47ba7ff2362c1b2f97a4f6311b646f912220a20c97c7e96077a90368c8dfc33bf5ec3098f5669b205c770ba1ed2198d73eb070318849f100a3e0a14f0c8b6addaf7cc4ece57086607a9a0c7ea6275e012220a2027ca4761fea7ebcb5fefbc1542b2c91b02d4dbde69e60adfe089e6099ec5eac318cf90100a3e0a1420658bf40ed48ed01a2d087c7ff7874f21a5633312220a2071ff973e6020b5734afc1e06bb3bc4a49761c1a145a357e7ebd28f85a3d740e518819e0f0a3e0a142335465b27b9548313aaf465217787fd8e6113d312220a20ad83cce6cc2dd83266285808eefd01cedffbc9421a51617e2ead21bbaa85fdf718c4920f123e0a1404446da0bcc4310003f97b1bed07ab2abec6fea712220a2030a3d1f6e481631b82b300484ea1aed0c503c7f3417763ca3e43b266a65309b118c4ed7718ffbd9eaf011a07080110b3d5a10722814c0a3f0a14cb5a63b91e8f4ee8db935942cbe25724636479e012220a20e8dcf4f58187cf05b18dccc6d0884ae08bf4a98d88717d0fff92a2b6f4574d4718a6bf9b0a0a3f0a141f7249f418b90714bf52797336b771b5ad46753312220a20b1fd3b167a4803d77810f675179821d28a5c6c9881eaee96cc61d9eeaaba1563189ebd920a0a3f0a14e08fba0fe999707d1496baab743eab27784dc1c512220a20de0e4a0ba7c9d98611a0de7cde629db2d2e2e5e830b760a4c91d32896211950c1888808e080a3f0a14765550228cf309bdd33f3f5e768350ba3d69c3b112220a2056dc9cdd103251ff6f5a1439465b1075a40d14bb76d99158c6f48753a77420a718a5c8e2060a3f0a1440cc723314b6ebb93b49fbd9d330eec8b4641cab12220a200609deffc6b7a9425f2cbe1666f54a14763a165b95125a73986ed70aa046690018b8e0bc060a3f0a149d0281786872d3bbe53c58fbeca118d86fa8217712220a2075f4c477afa4ad6633aac05ca6a771c92abe8b087b4867309c13bc5da5b6a8a618ccf3e3050a3f0a14d82343fcd5a74969c0b48457d70e8d55d8f6b80112220a207fc4e3176964df4b4c1ac8c52bf17b2e0be3cf6e1dde187112eba14729c43d5b18eacde8030a3f0a1466b69666ebf776e7ebcbe197aba466a712e2707612220a20c01db94ad2f16f3983d2e4e21621fac724997741f5de4c9a9cd52fbe55296b7e18acc7a5030a3f0a14a16e480524d636b2da2ad18483327c2e10a5e8a012220a2061dd91607c82d08dc6df864c95de6bb3de1ee12e4bd539d66810da0c8861a52818b2ce9b030a3f0a1472b1489efb57a680577a838a5baaebe162a7c80212220a2070d454aceb78239ac972c0158543a206f38b611485c7876ca36d9b714121b6721882de80030a3f0a1451d7d05a659208a6576190aebbe8f0760385151512220a2062eb1eccaf40fe2bd5798425f403b4d31eda4b89c593111b8a7c191e1b2054f818d5a6e2020a3f0a141b002b6ebeb8653c721301b1b56472b1b4de724712220a2081a971e0937b15b8c5dac7312a3d2eee1d69c0d43f3723eef7aae121eae60bab18e3b6d4020a3f0a14d24b7a32413338c2aa26fc0016d91fbe73bb5eae12220a20a7bbec0268402a52a3ecc398131e47b74374c06b9ad0e9f7e56cd6eeadde161e188596cc020a3f0a1471df8d9879c20563a4e2abeda95cd1fc57dbf6aa12220a200c2261f753aa87d3fbea0602ef5a454b37747319efa910f267afcf2c565f80b118e0f0b6020a3f0a14131fc79e7a012d9e7eef21de3ba5d5033fcdbc1f12220a208dde03c27dc6aea053730369b9768e9a07b580dca36bd4a6619b28e9ef31007018e1cbaf020a3f0a1439327692c258a57970ef53f0aa4d3c00f95988b812220a2055983a8520d191a7846ac4fd06e62ffda350d744682cc7931307a2b7229536bf18a8da8f020a3f0a147341e970b9b3eff82b2060d3469fc50d7af0414612220a203bfb06eb87e63bdfeb9d17e425f0990cd9bb298de279133cbc2539842772533518a99089020a3f0a1403c016ab7ec32d9f8d77afdb191fbf53ea08d91712220a2039d5694df2c2bcfc812de13a8cdc5eb20cb71e0d48880fb5eb9952bac64380bb18ddf8fa010a3f0a142022fe8cc49e48630c76160e11a880459219d24412220a209eaebea0305761228b211daf92c39e18cf62553dfe46d23258058452a70ea0ee188bd0f9010a3f0a149e7cae009efff4d163f3fb8781a07b25c2b10b3212220a209bf9fb4b564efa452d23bfb18021a7925a3989780c748f50be27f655cbc7623818f4fef6010a3f0a1499063b919404b6950a79a6a31e370378fe07020d12220a204f5c29e442f3bea54ea819ba78662241059ed13682d8b576053847695c61feb918e7f9f5010a3f0a1416a169951a878247dbe258fddc71638f6606d15612220a206fbef30a1fd5b11815bdf197b96e1d07e0e18383eb3165810b91b62bfa85822518a4f7ef010a3f0a14768a82700e3046e6daf849664579e649597cc1b412220a2036edd800b9957fb92f4576c20b1962c1c3c7983f2f99132bf50dfd95b2b8d70e18f4fcee010a3f0a1404c83aa20f7563bbcbcf6aa150ef6b0c81808daa12220a20f791cc0d6e74d3ab2c879d0d3bad6a4978fde19a915c67b54daefcab2eeee99d18a1e9dc010a3f0a147edb006522610c58283e30644a14f27bcc0d32ed12220a20cf3656640a5109a097d58233650031707479257fabff3589bff9d3ee67a4e2dd18f5b0da010a3f0a14a06b5b682b425ad206a35caf246fd70dd098e50612220a20d34546b9914079e9e7fd97fcad8a8da30c949d3ccfa37cdcbbf2caa6d1889c7518cf88d3010a3f0a1497afe45395b74e784c88d45e5cca2995019fae0812220a20647d935af93b6ddf0c2e30c72c8b6f38952ff849607c8b493b85785e75de755c18dfddce010a3f0a146239a498c22df3ec3fb0ca2f96d15535f6f3387a12220a20fe4ed7f1810e1371ed442f751aaf6b5a1dca75d93696ce60c9e5138598eae03a18e2f9cc010a3f0a145f999a4be254869925a7f2fea04d7b3b836cff0b12220a2014fa59625697d678dc64d5d2f96d29026ddab8faa8390e9e7286587c4501779518b2e0c4010a3f0a14f3f55da24bb47da60b0fb71ec1a9c9274bceedb212220a208e371214d150f2afadff11ebd6e61d236fdcd6c3f0003d7bb8a83e0323964dee18ebc7c3010a3f0a149cbec8cbd4ed3aad4bb2b0346efc86a6c41f916012220a206fce05c68686e24f4829060da73a87d7a9c2037e73980ba6ae1b523c9bcc21c718cb8abb010a3f0a14af195943e44fe1d6250076b8bc1910eabc85f1f212220a208f8321eb499cf5bf3c1f8b823a998e4388d893305b5f8d71f803fe0855a6dcdb18cfddba010a3f0a14dbcd765db2640631946c1393ba255876c76da38e12220a2050ddda931e0b3714fafaf5637f4d9dce461be673e9d976f5881f55062b311de818fcbbb8010a3f0a146912e0ba38cd00c9f2fc9e71e971eced507b42fd12220a20a3502e5f79a9b874ece86cf806853c47d263d3ccfbfe327ac95568a9cd95149018aba4b7010a3f0a148b1d5676f4c0c871a0c7864850d451d6a8ac8e3b12220a20b6a687464d7092ea873237cdea40d2d72994e556430b55cb98534521192da37a18b5b3b6010a3f0a1440c48839cd487d8a13d65955b7fc6c4f560d8f7212220a20bba89921518cd62976f9e6a2b21b8233580e8c930994cea63cbe6dad65ac6daa18cccdb5010a3f0a148e0545b1222e7b5c85ce69edc78f280cb2b79d1812220a20bd8353656c4a85edd49fa805faa5fa715077a3f286e18c4c0b8fc88114cad33e18d0b3ac010a3f0a14c02f531d9bbba4907511ef2680421ce714a11e3b12220a2023db1f4a9b6c7e7c0438863c7d14f719ecc088eb3b1fc8a7fe607496447fac4e18b3eeab010a3f0a14b0b35fed40daa5ff9d4bc685c75925187f62211912220a20c3f71800b9f35141df3f4123fcdd0671693c2a5eaae7e0a722ac5bad7e00daf918a6bbab010a3f0a14138fd9ab7abe0baed14ca7d41d885b78052a4aa112220a209a66109b69c09eb50a2b928dcb7d45095f6504c97dfca81195ae2f06c87f257018eb80ab010a3f0a14273f72ee55987afa771b27d370fa131f608b83ac12220a2018f96b749e73fc46d76d429cdf121c427f8b394d54685e24ca4ec27ef7a9849818fcc4a8010a3f0a1495b002de67707313d123d06492f1a7a58478e54612220a203c0f91bd2a554dc016043ffe9f15e5b472da39d694cdbae93467e331a93fbac518debea0010a3f0a14f9a968a405fb0429410ae5165e5f2193271e678a12220a20c168ae411e8262ad92df5a20beb0eb603f2223757572120b27ac627be26b449f18fdbb9d010a3f0a145e809e91eab69d385784d191140e9c8cf6dd103712220a202c20ade02052ae40ef4831d6301eef7a9619e2cc28ab5034acea6644ce3e63a71887919d010a3f0a147ef244868c304aa5b34889372e2df874afd635cd12220a2002647063f76a3d20570d8fd83bf86e3e89222279ec5e6d21fb0338391c108af618cbba9c010a3f0a14e191e654d06b9f721568bb945b2eb51ddc1c8fdc12220a204888a709fe062a6baa1b5bb4d44642cbe3cd63f7fef2c4233f0ca71b66a4920f18c6a59a010a3f0a147e0ed7689b65c345d1c817c5b0332fd132de587512220a2045f10c8fe0408a0f3e6088f0225aae19603b5513b508c7e2827e8fb7011cb7a918cdb498010a3f0a149f8ec2ef581ce25630c819f19b5484039e748d1a12220a207768735ffdf0ae68edadbfa300a514bcef7955e7a3751a314c775063bffc80ba18f29996010a3f0a14ca0f2a7121f86d3b6d91349730155b9a5a31c55412220a2040b4e0084232d339f67f9d7d4fa307bda88af7ee76b104e3cec9d3c39f75e9d118f39395010a3f0a14966fd89b1db51535f2d898cf9b0f14da374efb9612220a20465758a584028f6e80799abab47eae0b4c92a7dbcc62bc08b89a30c96895693818cfc690010a3f0a1476f706ae73a8251652bc72cb801e4294e2135afb12220a20bcdc9ae9179e22c81347787b70dab4b83c085fd65c9f84b1fd9005416f684bb5189ea790010a3f0a1406f45c36fcb957e55d923a6d4e905c2d715115ad12220a202ce51a0d34b46194bbd078c1c2bf4045ead73176d7c453ec4b1438eee36602f018d88d90010a3f0a14e12cef3871b9595ef15401eed2466e9310e4816b12220a200b79d897e14b01d6e44e4aef3fc3a181dc94407e03a480f9a53dbba128fc5e5a18eba88c010a3f0a147d53d76f2db86be30a9b26cadea69078531ab9bb12220a2042e7a3b3d0df9c2b201849535f150bb25014d3a7386f3cabc43493b4367a54ef1882af8a010a3f0a1420efe186da91a00ac7f042cd6cb6a1e882c583c712220a20fc99fa517d1055654eaae120e51594c4c91447c43d751c9cee0926bfdd830494189c9487010a3f0a14cefe7d654b523dea2a9ed718a591126c7417168912220a20245043a3bb3f3655a7a08ea16f2e1acaab2d4b3b220fc4fa29a6f15530d9533d18829b86010a3f0a14d8a6c54c54a236d4843ba566520ba03f60f09e3512220a20f1846413861dac13d754af618222d829bae09cd51826c1867dcf0a77fb4e5aea1895a684010a3f0a1417386b308ef9670cdd412fb2f3c09c5b875fb8b812220a205ef60c3c37dfbc78650721fe4f698a0845dccca67416851058fb68bb4438d7e518d38180010a3e0a14e03b985e6c8905e184d88c995cc632aa278981eb12220a20240f81848de789ef6d47e9510836f79f2641eb4b5b8475e1ecc356a536ab26e2189f8e7f0a3e0a14c9e615289d1d92e50292c3b0bd8358d9b2e4029012220a20816b7aabef362d1da73161e8ee4daae4b18bb17cee6466a3650545caa933ca0618dfa37b0a3e0a14f6c3f7872b046da7198905e6cb58c1b775b48bea12220a204780e053ea721ee174ed3a32dcdee5b03342a0be58820c8e130f37d00c17056018a3e3780a3e0a1404446da0bcc4310003f97b1bed07ab2abec6fea712220a2030a3d1f6e481631b82b300484ea1aed0c503c7f3417763ca3e43b266a65309b118c4ed770a3e0a1446dea137cfb10bc419b2577aa9a58718680e18ba12220a2024c1759b31bc7e3d1ad204a5beaf6d3f56832fb6677135a5feaecba2ba32b51b18ace4750a3e0a14f194dd4a8ad83323c3e9c2a93db25f049621c7b412220a20a1ba22dfd695c326a9db618d1273bfc55dfd2afbfefe78d894acea5c31d0feee18a3ab750a3e0a14692174b3ffbba80394a94dc92665dc0144fba83712220a20fa27065157b26cd698738de23432f48af7269bdb7dfe25a2dbfd40738175adc518c396730a3e0a148445cf55cb51278e63b2131adb65a81dc2389d8e12220a20f7925a8c92547bfe5d332151387406a5bc5b68ec008447d0dd2cbc3b934be667189ff06f0a3e0a1463481f6dcaaf733d2fc953a335c2200ee190862c12220a206770347c291a291d3dbef0d3ef1d7c23621ccf1bd5a5ece4b0fa6c6322b59f6618eedf6d0a3e0a142712cf68af6982b4bd7536b94cdd0d104a0313f412220a20e0809a9daf10bc212e01c5e6fcedf92abe931444164213fa294d6f0b23a6e78818eccd6b0a3e0a14712bc891aeb721da72732bc30d531e0c1eaedae012220a20a24b638d97169fb79d8f1d786e558eed5d668610a482f05e817cd7583f6cf5a0189bc86b0a3e0a14bd4f80f0c1a67b4950772662f6ebcad58a25893312220a204313e1cd7143fe17815536a4f3499bde0d1c00de1fa3788801f1a1cd6dcab64b1899d5690a3e0a1468a393c7ed496871150c0a7cad0cac09b8e458fb12220a206d4d66dda0d0c31229a8562e6e3648852bd80a26b531049f4da697241837f27c18afb2680a3e0a14943547cacb29c55797e121acb4e586c49d9d39fd12220a20f9629f36e6e8a02a4474913dddafa428c7e7fd88c9862f4307969964d4bd769e1894c6640a3e0a145fecec9408a2710833f2f7d848339462c29c144412220a20092485a5e4e61776e2e90e061d39d467dd3b8211d3433af6de09bf047e37f40118ed80630a3e0a14d5b93190771a50604a5f7849aaf067c4a9daaf9c12220a20fa8b07c0107fa92f6b2c3c6f2994815818e88e870919f7c5af44147b4426ed59189a89610a3e0a14844290531ee59b40feefde5259857368bf7119ec12220a2038fb199ef4f2dd2f74ac0f24bf615010a9858a04e7e611dd028a74a8d660353718abee600a3e0a144e154c9288e31436ba814dd92d17c4ed6cefd3f112220a207746dd5053e9a341e19629331c95112e8217bd489412f3b6f2ae089dc8cfcbd518eee2600a3e0a140a70912d18e13d78cb32e6322a4e57f861e6c3c812220a2006a6acbd97c4de13c3b27f683fe800b42892339bebae87196c995af276a1a80518aaa95f0a3e0a14e80d1f5519a5b3c9d290d3ea314fa05564535c1a12220a206c39d4c79d4e0a531a063b729c4dd12e609bd2694f9646962d5643066ac2d547188ffa5d0a3e0a14b5c33a409a589c094e89f77d24139f25c6a6dee912220a20fab7fe2b2e8475fa64e64a9d36ebf7fa79fb9a85a66d11425702e0330312475518e7a95c0a3e0a1469d0605229c665974ebb736fc77e16245c3f79aa12220a20fae63b08b0b55a3d7afda479d2fc372dc25bc08976fc5ff3a2b6d42212aa2bf118b1805c0a3e0a147fc1da40b2568ddbd53cff3b76c49ce89ae2868012220a20e5bd157cc917235604a2da99fc0bed4fc4cec2ea27efe46080a2f867a6f66d9818f1f05a0a3e0a14da4af19a378c09b54c26c3467cb0adf88929295412220a2074e936a54cd5647abc24377234b3b21c7f64fabcbf5efc65eddfef662bd8134218ec97570a3e0a143e88e7c54f64642a98b2e1ddd5bdba48794f06c712220a207ae26e6ddc29d163635fdc4f55161c31a04f7743423fd98a28c71456d3e1a90918b08f530a3e0a142c2467180bba84f2f1d4565e66f565a34003ee4f12220a20b5decf8ce19ca9af58ae969e37cc7b83aefdf9397f8168a191124618bc241f5d18bff5510a3e0a14e5cba199e045e7036711d814e57e2b66c3cc039112220a2053d278baae62eb328a1e445e50ab0c7ad252bf208dac26aa2c80b2228a97504c18b2bf4a0a3e0a14894c56d6cfc3a8e09eb6d1a2e33467c4cf77c0f512220a208864359c180879b0a2967090c2ba9ff64ccabe80310f30327f58ff0474bc6f3f18a9bd470a3e0a14c8969171f9b5a3354c712a20f007cde0648c990f12220a20adf42dfaf009e085fe92901a0400eb1792c93e3de94c16ac2c92f87cafca8c2c18bcc2460a3e0a149cbf2effd5570b3a9a41346244757cda3e18d40112220a203f04eb31298aba5da5f317cddd1980af2c95bf6f8fbf01bd5e96717f855ce2e318dc8a460a3e0a14d4c41c1e17e9321d067ba4e3e476e766b2c2c2bd12220a204a8f6a0a1999e845ddbfd2bf57559cb8ba878633dd9d8691dd6b79f5fa022fdc18be88460a3e0a1426f7777bd52918ae71801022b0e2deed97ddd50412220a20cd8a1cc7079a9999ba18e13834c67e57368fa5e19da1222c908038407a3efe8118e7dc3e0a3e0a14f233e036248a36fc73c154ffa79261bcbdc4bb7612220a20baa8697cae1a67c31a4c2f19c43e318607205c30a7928e1e77acc4773ee30deb18a3fd3d0a3e0a1415fec10416e359cc1ddb424c69166b2671f2514812220a203a324933e9423e8e7c94d5838040ea684e8a9aa2045c68f89a7d41fdf025994718ea983c0a3e0a14000a5959634b4296e4de536481de00a8a0eb9a5812220a205d80af85d70e966ff983580748efbbfe102e090d2464f53b5cabdcd42e5ed54e18b882380a3e0a144b65255857e4393754f049dbe945c5ac87f563d812220a20d950a6e1f7252e5ca5b4a99c62e25913af94819f87b4bd6e85ac67462b6d5c1418b1d3370a3e0a1460a433d28b08788c72e2133554bd5cc68769dcec12220a201e8df872a211c43bb6f22a1ceb8fd5b8879b7ca792de6723bf3065fa6c4266f118aeb6360a3e0a1406aa34bd6d1dd34119e3dc173efad94f430ab74e12220a20b95650373a6194c59e18456f4a26cab57f4d3c277669caafa530b6c5023b4dcf18fe99360a3e0a14c9b753ed297e5f9894d4a43149cfc9f7b207b6b212220a20404a57c540daba7bf6c269da435430d33612ff31c239adf02482264889e18dac18cbc4350a3e0a143ff6c988799c1adf3aca0da56143c8163890859a12220a209776967a589fe2a4b09f1777f0f731bce07d17ca28778a01231c108dc29bfe881892a7330a3e0a1499938495407c09b343562aaec3ab551a5c24623212220a2012f31aeac3e9109433f1ba9a94630448ebc32aad986173e8f7e89bdeaabe9b3f18c598330a3e0a14901fd122cc512ef13de8e1a3d7953bfddc0786d612220a205e022ed655f7d7c2d227296ba022f3463025889a0e23e9f27bbaf7bc6f12ec5718e39d310a3e0a14f6783d8fb30e283081c16398293f482dca0e912d12220a20d9cb95a9421bcb4e7bc59f2776fa2c0a4ddfba8bf30682462ccc81ef826c64d8188caa300a3e0a14a9c4e0e2af00183da11434ed413219905e9a868d12220a20b579e685431c2326c86fd5b39b1e6d88b0f8c688c641ce62adb39c35bfd14e1a18e685300a3e0a1419ec0a155a5be755e76d0059ef730ebca122b4f112220a2079acf837378aeafb95dcb3c5700e19dd4214587c06480ea748d7ca833d311d7f18a3cd2f0a3e0a143749086b6d85bde3dacfbe4485e3df95e709b6db12220a20d7ffe9e33ffdc09bfaeaaf5705975f02b762437f26e0bd871687ecdbdac6e3f118c0942e0a3e0a14e06dadeb413829558f7c95339ffb61499c5a1bb912220a20777a8d93635ce43cdaa5144f349fff7636fa509f1c465251b58c5ee3c4255be818d9fe2d0a3e0a142d159b72d40c1c1daddf24d2511200001b74ed8412220a207163b2c1debfbad1baec5b898d3c979fca2ed5d201359b5aa9229b1fad96821b18f09f2d0a3e0a140ceb917de4df1c4b4f8edfc4ace6fd6d39f1e61e12220a20d578e01a2bf304f866055801d4e205a67ef30abc1c4d869e9b2bbc83194124d018d5b02b0a3e0a1496da375d8a293f8f6580da36ea2376cd89ab20c412220a2030197360e96eaf5f9b5464d777ab6e1de1b12dadbf859e612bc6204c92c6171318b78f2b0a3e0a14ce485517649e4f8c71469ef7dafcf9a558bf167f12220a204d686b80b7be4fe2c510b52a507cdcbe6168454cbe03e34bd59bca20675cd4d5188d812b0a3e0a1468275c37cff86bb53d29d6237ad370e8fd5097fc12220a2051abf57604223a142e097b5c41b43419dd362115018930f598e807086afaef1118d4bc280a3e0a14e23afcf0035fb01acd02fe96f680066974d7072b12220a20d601d0fa5338d6bcd586ac6fc0afe096d20c748880d8aceb2aeed126b639afb418b7d3270a3e0a14e242db2cb929d6f44a1a2fe485cc7d3f620ffaeb12220a20b393d2e4dfe27218cec720e8c11a30823a990a113743fa84c1e4c82b74a7fd7e18b9cd270a3e0a146e705424231dceec337eb451bc4c1d2c5fba48c912220a20bc3910b78ef23877f10175f5253094d9c7fc1fae0c99de514d6c46236da1041218b0fc250a3e0a1441b543e91479a95cd5ca9f109c26dfac149126fa12220a200bcf2ea5bb5ee3af29e959d4631152b55ba0695f85ce2e82dd87242b8970a6021890b3230a3e0a147c5aa87e5203c66ea35c64262f576edd29bad98012220a2063303ccb21d2bf29aa0a996b874af9d13d4346194db1c9b12b7f10e13d14e28218dfa0230a3e0a14451acecaa7dc4cce6e0b7cde02f455df973535e512220a20dbaa8e762cbd93c2e05a4205eab0ceaa0b0597bcb4fea2e0367f8d43f41856581896d8210a3e0a149127dfa61750dd1d56cb1d2a88f8831a2b3f9b0e12220a2022b43613ebabee0c6193beff81ac47c43d033f2211596d36220ba8e7b1ffdd9c18f7ff200a3e0a14583ae736e67df9d72fe87b9aa7d3210d3b4b0e5a12220a2043e39d798df8ea39bb8c32d0c57066fba79465bf0c0d29a788e47c755ab9df2618a8ef1f0a3e0a14c5ed122e511ff9d7dea986fd7423c61aeb139d3412220a20e46d6c3bbb10120804a4d4cea154c6023904ebb5b998bef0d3ebb9f65793776b18f7cd1e0a3e0a143519556ae84c5dcbcf6fdaf05fb644e40ff93c3712220a20866eba71a55f2d51c3c0ca1760de4b6abd0bc7bb79ece9eae9ca77d446a3dcea189fa71e0a3e0a141fada14dee843b733ecd5de2e74552ad234a545112220a204d83d58408b8fb9eed8d39cdc23b4aaee403651eb39d86d28d282c274520b11718a5a51d0a3e0a141571038b5aaab431ec011f6ab1094463c6ed984212220a20f03f305e4319f5dfe9f3ab0ec48cecfd4bf730c6327abd40323e949ce29d716d1880bb1c0a3e0a142d387d95e13f681d33122e4475f9b7dfc2a68f6412220a20e17d393a4c8e3f540a0a24c57d9b084131e2ee85ea894f45b4dfdb89ba670ab618e9e41b0a3e0a143ff719f1664bee93d482b480677c03a47ec0b64312220a20809be43cb887a36fb5d89246a6b87056c0010125f35cefdd496b67934cb0341e1896ae1b0a3e0a14c02acba7653ac3782750b53d03a672e191f0036112220a201c6dea720e32a82ce5046e4da98b596912ad569e5629cc67113419af419326661894891a0a3e0a1437714c4da407c9d13cda424aae78c3b28515a15c12220a20f31c0c1100c8e31a03d99df4d1ff2fa636f891b61056e779ed1816865aed06d318f4ed190a3e0a140614088c41e6a85fb5bf344552a5120e5a0139fc12220a20c30b1b43a9a4130799b766613da9e741aa7f1629b5b03be218e750a5ad20c80f18b0fe180a3e0a14cdc018822747024beafd10a45abecc7ac19cbab012220a20e520358447f8fabcb99fba8e5a3c6b37b70145fc1bf52ab03e66f0233124017918f7dd180a3e0a144146fd7a1ab8b861b7018978bcd13d2d1fa63ebe12220a20aeab33dcf6b9fc06e90ae40425497f9a1ea8cf607f99b92724ec5d553780914318acda170a3e0a148014ba212ed388597510d064258f5e30aa30d59112220a20c4fd38b1d83bc7066a3e93986a84c88ce8428108d72b969d8208502e990fe8c31884d2170a3e0a14373f86cb3755a1de78cc69d3e5f7ad5d7615b85d12220a2060ca20064ab1ad2b4e9a374ab9039f5296d483d382ed2b0e4e6aa04b5663256d18f8b9170a3e0a1422ba59ac2918afa4c1b56d3e6f86083e470cd8cb12220a206f60d53412eb2055e4435f565e66f39542a1fac42b05a498d6cf2148f90514c618fbd1160a3e0a147364be6cc7b6e404bd1c2050ccb6a7472786e3b612220a20565ca17b5443d0c23d38435b6cddb28e64d3b552604986193a248d0be93426e518e8ff150a3e0a14972a684f364cce31469b37a9d439985115eb5a4012220a2003f3653f1603cc8ddc80d66497c5526075c17bdd010afd6682a7795fcf1e618d18b9ca150a3e0a14e20004515311b205618fad504fb529a3deee2e7112220a20a26c465c7f397649867ac4391b0432d18299eaabe6fbfd9ef1fc686a194aa2b418f993150a3e0a142f89d7d3d1e1478f88ef3ad8aad76a88189f612412220a209c20fbc290606879b909332fb16ae8e16f4e0e6bf3bcbce9858a08026496e51f18fac3130a3e0a14d807a55c7d69a84fb759fb0bd96bb4da50adba2712220a203e5af5f6a5b9082eada869be15caae91da9252dc51b5257099554b0b5382b86d18b9bd130a3e0a147e11ed7dd06fae7b0bedb469721151f2f31cbb6a12220a204c769c063525f04c7d63616b94a32b8f9a196e8abfb15a5358cb5a9b0516968418d1ae130a3e0a14da96564d2379acee00dd9faa558681bb499757fd12220a2085970175f1508b3d02d443a410f92ac02e5fa7bf358ee0739ce72dbc5008b3521880a8130a3e0a142dd6d22969ee7c2ca1f8b428d13a8995c043044c12220a2070cd875336aed8bdc3db4eb72ca2396069877216bbf6ee6f990156c8aa3703fe18f292130a3e0a149496535a8f2945bdb60572015d2d6f721ab6fed912220a2078078050a9cfbc6c5bea1110e15c7354efba656bf2aa7d4e8edcc18eacc12b1418f3f7120a3e0a14634d2f5ed7c9d82f42298d8922304d1b4adb20f712220a20d83196705de4b81d0b640cea0782e0f1b5c00e86fb8d46e37b07a8fbe7ad788618bbde120a3e0a14b15069e41b1a60ff03ae8d8f741f78c7b1144fbe12220a2058ac62882707e85b1e71847be0e73ea357f5e19dbfeeafa4cc9b83dbdc512ea918c99f120a3e0a14d0c2071d6f2fef021dbd3f5f1f72f1bf30a467b912220a207d853241b6851a9f0d5d7b6ea3f132a27550db5a5a1afad4c8290b0dcd4c6eb518ebbf110a3e0a145d564f844d411694b131b1c4a4fd3b389494f48f12220a20b83c55ca97fa78478f5c2b4507cbf71912ab5f11b12d0ab1a863ba11104d8b5e189696110a3e0a14191e896a11c0a77a96a99abee986a2a40355c04412220a208c6dd838fccbc443a67c2db137cab1aad17e0352062ef9f5f40853be14a6a2bf18c0c7100a3e0a1447c89621f47ba7ff2362c1b2f97a4f6311b646f912220a20c97c7e96077a90368c8dfc33bf5ec3098f5669b205c770ba1ed2198d73eb070318849f100a3e0a14f0c8b6addaf7cc4ece57086607a9a0c7ea6275e012220a2027ca4761fea7ebcb5fefbc1542b2c91b02d4dbde69e60adfe089e6099ec5eac318cf90100a3e0a1420658bf40ed48ed01a2d087c7ff7874f21a5633312220a2071ff973e6020b5734afc1e06bb3bc4a49761c1a145a357e7ebd28f85a3d740e518819e0f0a3e0a142335465b27b9548313aaf465217787fd8e6113d312220a20ad83cce6cc2dd83266285808eefd01cedffbc9421a51617e2ead21bbaa85fdf718c4920f123f0a14cb5a63b91e8f4ee8db935942cbe25724636479e012220a20e8dcf4f58187cf05b18dccc6d0884ae08bf4a98d88717d0fff92a2b6f4574d4718a6bf9b0a18f9ea9eaf01" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "ibc_client" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/ibc.core.channel.v1.MsgRecvPacket" + }, + { + "key": "sender", + "value": "archway1y8k9a33967dm9n7a8u2d2l6q9m7teecvnxy0t0" + } + ] + }, + { + "type": "recv_packet", + "attributes": [ + { + "key": "connection_id", + "value": "connection-1" + }, + { + "key": "packet_channel_ordering", + "value": "ORDER_UNORDERED" + }, + { + "key": "packet_connection", + "value": "connection-1" + }, + { + "key": "packet_data", + "value": "{\"amount\":\"366000000000000000000\",\"denom\":\"transfer/channel-1429/aarch\",\"receiver\":\"archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3\",\"sender\":\"osmo1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fxru365\"}" + }, + { + "key": "packet_data_hex", + "value": "7b22616d6f756e74223a22333636303030303030303030303030303030303030222c2264656e6f6d223a227472616e736665722f6368616e6e656c2d313432392f6161726368222c227265636569766572223a22617263687761793174386e703678723871723234796a7970336c6b67396a34777965617a676636666d6e6e397833222c2273656e646572223a226f736d6f3174386e703678723871723234796a7970336c6b67396a34777965617a67663666787275333635227d" + }, + { + "key": "packet_dst_channel", + "value": "channel-1" + }, + { + "key": "packet_dst_port", + "value": "transfer" + }, + { + "key": "packet_sequence", + "value": "96339" + }, + { + "key": "packet_src_channel", + "value": "channel-1429" + }, + { + "key": "packet_src_port", + "value": "transfer" + }, + { + "key": "packet_timeout_height", + "value": "0-0" + }, + { + "key": "packet_timeout_timestamp", + "value": "1714126034868000000" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "ibc_channel" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "366000000000000000000aarch" + }, + { + "key": "spender", + "value": "archway1kq2rzz6fq2q7fsu75a9g7cpzjeanmk68awem3r" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "366000000000000000000aarch" + }, + { + "key": "receiver", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "366000000000000000000aarch" + }, + { + "key": "recipient", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + }, + { + "key": "sender", + "value": "archway1kq2rzz6fq2q7fsu75a9g7cpzjeanmk68awem3r" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1kq2rzz6fq2q7fsu75a9g7cpzjeanmk68awem3r" + } + ] + }, + { + "type": "fungible_token_packet", + "attributes": [ + { + "key": "amount", + "value": "366000000000000000000" + }, + { + "key": "denom", + "value": "transfer/channel-1429/aarch" + }, + { + "key": "memo", + "value": "" + }, + { + "key": "module", + "value": "transfer" + }, + { + "key": "receiver", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + }, + { + "key": "sender", + "value": "osmo1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fxru365" + }, + { + "key": "success", + "value": "true" + } + ] + }, + { + "type": "write_acknowledgement", + "attributes": [ + { + "key": "connection_id", + "value": "connection-1" + }, + { + "key": "packet_ack", + "value": "{\"result\":\"AQ==\"}" + }, + { + "key": "packet_ack_hex", + "value": "7b22726573756c74223a2241513d3d227d" + }, + { + "key": "packet_connection", + "value": "connection-1" + }, + { + "key": "packet_data", + "value": "{\"amount\":\"366000000000000000000\",\"denom\":\"transfer/channel-1429/aarch\",\"receiver\":\"archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3\",\"sender\":\"osmo1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fxru365\"}" + }, + { + "key": "packet_data_hex", + "value": "7b22616d6f756e74223a22333636303030303030303030303030303030303030222c2264656e6f6d223a227472616e736665722f6368616e6e656c2d313432392f6161726368222c227265636569766572223a22617263687761793174386e703678723871723234796a7970336c6b67396a34777965617a676636666d6e6e397833222c2273656e646572223a226f736d6f3174386e703678723871723234796a7970336c6b67396a34777965617a67663666787275333635227d" + }, + { + "key": "packet_dst_channel", + "value": "channel-1" + }, + { + "key": "packet_dst_port", + "value": "transfer" + }, + { + "key": "packet_sequence", + "value": "96339" + }, + { + "key": "packet_src_channel", + "value": "channel-1429" + }, + { + "key": "packet_src_port", + "value": "transfer" + }, + { + "key": "packet_timeout_height", + "value": "0-0" + }, + { + "key": "packet_timeout_timestamp", + "value": "1714126034868000000" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "ibc_channel" + } + ] + } + ], + "codespace": "" + }, + { + "code": 0, + "data": "Ei4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNl", + "info": "", + "gas_wanted": "450000", + "gas_used": "311552", + "events": [ + { + "type": "use_feegrant", + "attributes": [ + { + "key": "grantee", + "value": "archway14jxettnrywm088ja5g36nsr66y08ts0mu0y48a" + }, + { + "key": "granter", + "value": "archway1gpyqzc0aerc85cpk2cm8ec6zkc95x5yqrakskv" + } + ] + }, + { + "type": "update_feegrant", + "attributes": [ + { + "key": "grantee", + "value": "archway14jxettnrywm088ja5g36nsr66y08ts0mu0y48a" + }, + { + "key": "granter", + "value": "archway1gpyqzc0aerc85cpk2cm8ec6zkc95x5yqrakskv" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "31500000000000000aarch" + }, + { + "key": "spender", + "value": "archway1gpyqzc0aerc85cpk2cm8ec6zkc95x5yqrakskv" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "31500000000000000aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "31500000000000000aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1gpyqzc0aerc85cpk2cm8ec6zkc95x5yqrakskv" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1gpyqzc0aerc85cpk2cm8ec6zkc95x5yqrakskv" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "31500000000000000aarch" + }, + { + "key": "spender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "burn", + "attributes": [ + { + "key": "amount", + "value": "31500000000000000aarch" + }, + { + "key": "burner", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "31500000000000000aarch" + }, + { + "key": "spender", + "value": "archway1gpyqzc0aerc85cpk2cm8ec6zkc95x5yqrakskv" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "31500000000000000aarch" + }, + { + "key": "receiver", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "31500000000000000aarch" + }, + { + "key": "recipient", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + }, + { + "key": "sender", + "value": "archway1gpyqzc0aerc85cpk2cm8ec6zkc95x5yqrakskv" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1gpyqzc0aerc85cpk2cm8ec6zkc95x5yqrakskv" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "63000000000000000aarch" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "archway14jxettnrywm088ja5g36nsr66y08ts0mu0y48a/78947" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "Sbc3d6pYIjT6jegsMGhDcWaRfQC1+IodCi2erEDIa9Zb/auoex17aWfIy1DwaS/PrsUTsNssJufbuNLrqmhEyA==" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmwasm.wasm.v1.MsgExecuteContract" + }, + { + "key": "module", + "value": "wasm" + }, + { + "key": "sender", + "value": "archway14jxettnrywm088ja5g36nsr66y08ts0mu0y48a" + } + ] + }, + { + "type": "execute", + "attributes": [ + { + "key": "_contract_address", + "value": "archway1zlc00gjw4ecan3tkk5g0lfd78gyfldh4hvkv2g8z5qnwlkz9vqmsdfvs7q" + } + ] + }, + { + "type": "wasm-astrovault-ratio_pool_factory-update_direct_ratios", + "attributes": [ + { + "key": "_contract_address", + "value": "archway1zlc00gjw4ecan3tkk5g0lfd78gyfldh4hvkv2g8z5qnwlkz9vqmsdfvs7q" + }, + { + "key": "new_expiration_time", + "value": "1714128540" + }, + { + "key": "new_expiration_time", + "value": "1714128540" + }, + { + "key": "new_expiration_time", + "value": "1714128540" + }, + { + "key": "new_expiration_time", + "value": "1714128540" + }, + { + "key": "new_expiration_time", + "value": "1714128540" + }, + { + "key": "new_ratio", + "value": "64432567433" + }, + { + "key": "new_ratio", + "value": "169906" + }, + { + "key": "new_ratio", + "value": "925770" + }, + { + "key": "new_ratio", + "value": "1019605" + }, + { + "key": "new_ratio", + "value": "8241758" + }, + { + "key": "pool_addr", + "value": "archway1alukarfvkx5m2uzazlye7yu0vmyre76rvm63znytjl996thwjtzst5mjx0" + }, + { + "key": "pool_addr", + "value": "archway1z9trdrva47g4wvudpnwhfrsz2dpnsp6zzdeaxax3mxcyfylmr58qt2w2x9" + }, + { + "key": "pool_addr", + "value": "archway1z424j4jhjf92dsg56qt9ws2q5znhxpakfdkzesfe2xx7qyn26v8qy37c2g" + }, + { + "key": "pool_addr", + "value": "archway1l2mmr0vpndgv8vstwnj7qhn0px4fn80e0vxdnuenudfwa57n52fqfk9fe3" + }, + { + "key": "pool_addr", + "value": "archway1csty6kltj5ny7vw2vnn33t5hlz704ln8a4xfyf28dt4jss45l4yqm3gx9a" + } + ] + } + ], + "codespace": "" + }, + { + "code": 0, + "data": "Ei4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNlEi4KLC9jb3Ntd2FzbS53YXNtLnYxLk1zZ0V4ZWN1dGVDb250cmFjdFJlc3BvbnNl", + "info": "", + "gas_wanted": "635970", + "gas_used": "506587", + "events": [ + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "62325060000000000aarch" + }, + { + "key": "spender", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "62325060000000000aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "62325060000000000aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "62325060000000000aarch" + }, + { + "key": "spender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "burn", + "attributes": [ + { + "key": "amount", + "value": "62325060000000000aarch" + }, + { + "key": "burner", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "62325060000000000aarch" + }, + { + "key": "spender", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "62325060000000000aarch" + }, + { + "key": "receiver", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "62325060000000000aarch" + }, + { + "key": "recipient", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + }, + { + "key": "sender", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "124650120000000000aarch" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k/8" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "V3S38fWavl3jJoNmr1+6s3ti9HZYZhxKGnRUvnH2ZZg9eXPrJDDZTJsYbPXMExRbXV1IYVaCEXdHwRcXd56WnQ==" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmwasm.wasm.v1.MsgExecuteContract" + }, + { + "key": "module", + "value": "wasm" + }, + { + "key": "sender", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "execute", + "attributes": [ + { + "key": "_contract_address", + "value": "archway153l9pc7acv7qw43lyx3f0d3tt02gu80zdlllr4lvwtj9gpk7nu0q7qdagg" + } + ] + }, + { + "type": "wasm", + "attributes": [ + { + "key": "_contract_address", + "value": "archway153l9pc7acv7qw43lyx3f0d3tt02gu80zdlllr4lvwtj9gpk7nu0q7qdagg" + }, + { + "key": "action", + "value": "unstake" + }, + { + "key": "amount", + "value": "10000000000000000" + } + ] + }, + { + "type": "execute", + "attributes": [ + { + "key": "_contract_address", + "value": "archway1paztmpff88sjjcrwwej8qlyfz7dlletq640wuxgg4lrpvhvqucqs92wwnj" + } + ] + }, + { + "type": "wasm", + "attributes": [ + { + "key": "_contract_address", + "value": "archway1paztmpff88sjjcrwwej8qlyfz7dlletq640wuxgg4lrpvhvqucqs92wwnj" + }, + { + "key": "action", + "value": "transfer" + }, + { + "key": "amount", + "value": "10000000000000000" + }, + { + "key": "from", + "value": "archway153l9pc7acv7qw43lyx3f0d3tt02gu80zdlllr4lvwtj9gpk7nu0q7qdagg" + }, + { + "key": "to", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/cosmwasm.wasm.v1.MsgExecuteContract" + }, + { + "key": "module", + "value": "wasm" + }, + { + "key": "sender", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + } + ] + }, + { + "type": "execute", + "attributes": [ + { + "key": "_contract_address", + "value": "archway1paztmpff88sjjcrwwej8qlyfz7dlletq640wuxgg4lrpvhvqucqs92wwnj" + } + ] + }, + { + "type": "wasm", + "attributes": [ + { + "key": "_contract_address", + "value": "archway1paztmpff88sjjcrwwej8qlyfz7dlletq640wuxgg4lrpvhvqucqs92wwnj" + }, + { + "key": "action", + "value": "send" + }, + { + "key": "amount", + "value": "10000000000000000" + }, + { + "key": "from", + "value": "archway1vn5xlxyp6e50hhmxpy87h42yr8ga3np5j50e5k" + }, + { + "key": "to", + "value": "archway153l9pc7acv7qw43lyx3f0d3tt02gu80zdlllr4lvwtj9gpk7nu0q7qdagg" + } + ] + }, + { + "type": "execute", + "attributes": [ + { + "key": "_contract_address", + "value": "archway153l9pc7acv7qw43lyx3f0d3tt02gu80zdlllr4lvwtj9gpk7nu0q7qdagg" + } + ] + }, + { + "type": "wasm", + "attributes": [ + { + "key": "_contract_address", + "value": "archway153l9pc7acv7qw43lyx3f0d3tt02gu80zdlllr4lvwtj9gpk7nu0q7qdagg" + }, + { + "key": "action", + "value": "stake" + }, + { + "key": "amount", + "value": "10000000000000000" + } + ] + } + ], + "codespace": "" + }, + { + "code": 0, + "data": "EjgKMS9pYmMuYXBwbGljYXRpb25zLnRyYW5zZmVyLnYxLk1zZ1RyYW5zZmVyUmVzcG9uc2USAwjZVQ==", + "info": "", + "gas_wanted": "140000", + "gas_used": "122080", + "events": [ + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "140000000000000000aarch" + }, + { + "key": "spender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "140000000000000000aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "140000000000000000aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "fee", + "value": "140000000000000000aarch" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "acc_seq", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3/66438" + } + ] + }, + { + "type": "tx", + "attributes": [ + { + "key": "signature", + "value": "DpmkxVmQaQXFDASxZnozMcqf99XKcSn8NkJjMCEYtDld3W2XIHfhPRWx1tBtE43wsncCwO5fY/Jhq0rlyB99iA==" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "action", + "value": "/ibc.applications.transfer.v1.MsgTransfer" + }, + { + "key": "sender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "497840000ibc/8CB56C813A5C2387140BBEAABCCE797AFA0960C8D07B171F71A5188726CFED2C" + }, + { + "key": "spender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "497840000ibc/8CB56C813A5C2387140BBEAABCCE797AFA0960C8D07B171F71A5188726CFED2C" + }, + { + "key": "receiver", + "value": "archway1yl6hdjhmkf37639730gffanpzndzdpmhm52da5" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "497840000ibc/8CB56C813A5C2387140BBEAABCCE797AFA0960C8D07B171F71A5188726CFED2C" + }, + { + "key": "recipient", + "value": "archway1yl6hdjhmkf37639730gffanpzndzdpmhm52da5" + }, + { + "key": "sender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "497840000ibc/8CB56C813A5C2387140BBEAABCCE797AFA0960C8D07B171F71A5188726CFED2C" + }, + { + "key": "spender", + "value": "archway1yl6hdjhmkf37639730gffanpzndzdpmhm52da5" + } + ] + }, + { + "type": "burn", + "attributes": [ + { + "key": "amount", + "value": "497840000ibc/8CB56C813A5C2387140BBEAABCCE797AFA0960C8D07B171F71A5188726CFED2C" + }, + { + "key": "burner", + "value": "archway1yl6hdjhmkf37639730gffanpzndzdpmhm52da5" + } + ] + }, + { + "type": "send_packet", + "attributes": [ + { + "key": "connection_id", + "value": "connection-21" + }, + { + "key": "packet_channel_ordering", + "value": "ORDER_UNORDERED" + }, + { + "key": "packet_connection", + "value": "connection-21" + }, + { + "key": "packet_data", + "value": "{\"amount\":\"497840000\",\"denom\":\"transfer/channel-20/ubld\",\"receiver\":\"agoric1ccr2m407rvh7n0whcrhq0twawxkry2cy9yqk0f\",\"sender\":\"archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3\"}" + }, + { + "key": "packet_data_hex", + "value": "7b22616d6f756e74223a22343937383430303030222c2264656e6f6d223a227472616e736665722f6368616e6e656c2d32302f75626c64222c227265636569766572223a2261676f72696331636372326d343037727668376e307768637268713074776177786b72793263793979716b3066222c2273656e646572223a22617263687761793174386e703678723871723234796a7970336c6b67396a34777965617a676636666d6e6e397833227d" + }, + { + "key": "packet_dst_channel", + "value": "channel-60" + }, + { + "key": "packet_dst_port", + "value": "transfer" + }, + { + "key": "packet_sequence", + "value": "10969" + }, + { + "key": "packet_src_channel", + "value": "channel-20" + }, + { + "key": "packet_src_port", + "value": "transfer" + }, + { + "key": "packet_timeout_height", + "value": "0-0" + }, + { + "key": "packet_timeout_timestamp", + "value": "1714126042659000000" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "ibc_channel" + } + ] + }, + { + "type": "ibc_transfer", + "attributes": [ + { + "key": "amount", + "value": "497840000" + }, + { + "key": "denom", + "value": "ibc/8CB56C813A5C2387140BBEAABCCE797AFA0960C8D07B171F71A5188726CFED2C" + }, + { + "key": "memo", + "value": "" + }, + { + "key": "receiver", + "value": "agoric1ccr2m407rvh7n0whcrhq0twawxkry2cy9yqk0f" + }, + { + "key": "sender", + "value": "archway1t8np6xr8qr24yjyp3lkg9j4wyeazgf6fmnn9x3" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "module", + "value": "transfer" + } + ] + } + ], + "codespace": "" + } + ], + "begin_block_events": [ + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "20639843594155070494aarch" + }, + { + "key": "receiver", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coinbase", + "attributes": [ + { + "key": "amount", + "value": "20639843594155070494aarch" + }, + { + "key": "minter", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "15479882695616302871aarch" + }, + { + "key": "spender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "15479882695616302871aarch" + }, + { + "key": "receiver", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "15479882695616302871aarch" + }, + { + "key": "recipient", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + }, + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "5159960898538767623aarch" + }, + { + "key": "spender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "5159960898538767623aarch" + }, + { + "key": "receiver", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "5159960898538767623aarch" + }, + { + "key": "recipient", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + }, + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1m3h30wlvsf8llruxtpukdvsy0km2kum8a6mudh" + } + ] + }, + { + "type": "archway.rewards.v1.MinConsensusFeeSetEvent", + "attributes": [ + { + "key": "fee", + "value": "{\"denom\":\"aarch\",\"amount\":\"34399739323.591784153333333333\"}" + } + ] + }, + { + "type": "mint", + "attributes": [ + { + "key": "amount", + "value": "20639843594155070494" + }, + { + "key": "annual_provisions", + "value": "108557321367818008772980709.400000000000000000" + }, + { + "key": "bonded_ratio", + "value": "0.475274953043275645" + }, + { + "key": "inflation", + "value": "0.100000000000000000" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "15523381418216302871aarch" + }, + { + "key": "spender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "15523381418216302871aarch" + }, + { + "key": "receiver", + "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "15523381418216302871aarch" + }, + { + "key": "recipient", + "value": "archway1jv65s3grqf6v6jl3dp4t6c9t9rk99cd8j5ccrg" + }, + { + "key": "sender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway17xpfvakm2amg962yls6f84z3kell8c5l9jlyp2" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "47555033216295305.062431351508006959aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "951100664325906101.248627030160139177aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16pj5gljqnqs0ajxakccfjhu05yczp987nad4gt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "38726904613077824.493826584428693992aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "774538092261556489.876531688573879841aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zttnm2cl60m5ffsrfeqtzkmtvepl4hwndvgtka" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "25510651962442731.678907086289926827aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "510213039248854633.578141725798536545aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16ktf3yu7cnkpx5n7qwmpkaxten8lw2k7etjm70" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "37691415595742688.936562478994384581aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "471142694946783611.707030987429807264aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ra4y9k2lle29ztcztcf7chvr7ayjr7uvrj9lam" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "21254081657251497.571358733133274576aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "425081633145029951.427174662665491518aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lq9la9sh5kjla8x7pg74p7djy2f74u6g60nl9e" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "18385211721970547.873230777331645442aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "367704234439410957.464615546632908830aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pkqd2k3g6tyq8n8xf85mutngevt7ckxuegk4vm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "16467899714458333.339157937799265476aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "329357994289166666.783158755985309512aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10m7wk6jk2k90s0k8k0v6lmcrn0xaveu9u20hay" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "323430482170869842.431768071569032874aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "323430482170869842.431768071569032874aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qssp5q303cq2hcp38v5tk80n8q3vzphtlr0la8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "15576698411710626.935779789057907199aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "311533968234212538.715595781158143972aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qsw3w58yaca87v0g86eqsec0rjxegzjd75gvt4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "14476146643866670.797661133006243325aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "289522932877333415.953222660124866508aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17qv63dpkg2zwxj5mypgh9ryldpmvsew4pfnvva" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13969358583600371.752135011453621066aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "279387171672007435.042700229072421322aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ce7vq2ektpgzl5v7qhgvlv22h2se9aagtk42zy" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13858070311435760.920099325171649396aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "277161406228715218.401986503432987921aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1skc8aut895jvg4hdxx7q89sus5x63ede7qxs2c" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13044368770514526.957317475365593951aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "260887375410290539.146349507311879023aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1p4n7pw4rdfyn3rgc4cndcqedwmcu3dt6kfdwpt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "12115593411175429.620950839957958010aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "242311868223508592.419016799159160203aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xjyw0swav97upg2f5trvuxrmzympm0gu092alx" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11252503006436088.090979298517045918aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "225050060128721761.819585970340918368aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c9ye54e3pzwm3e0zpdlel6pnavrj9qqvnrxcyw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "22427468070340124.371098667506767639aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "224274680703401243.710986675067676388aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wr8v2eept0n26nsa706k5a9kssnw7kdajfxm34" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "10672494251568696.563445012404068467aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "213449885031373931.268900248081369339aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1l54f8nfhtmd9m6sheancpeyse7qtax48duypsc" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4245083569212464.944047719605376636aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "212254178460623247.202385980268831783aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hgzw3udgagqylcvp9kyqq2w7ws8enucqpw094n" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "20704262527696272.300865134187811381aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "207042625276962723.008651341878113807aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eunmpgl2rspj38x26h9t8gr8226s2xd9szn3a8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "10342853352392183.557413982282978458aarch" + }, + { + "key": "validator", + "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "206857067047843671.148279645659569157aarch" + }, + { + "key": "validator", + "value": "archwayvaloper140l6y2gp3gxvay6qtn70re7z2s0gn57zekxzpl" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "10058784660575979.450497583500532425aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "201175693211519589.009951670010648493aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14sp0yjvxkrsj7qjltga65g9ctz5c2nrw8cgs72" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "10057608129204031.057693831734466791aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "201152162584080621.153876634689335819aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jzz2uw3nz446s4936afz9408vmk84lytdnkpkf" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "38747471286483611.048097493622208845aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "193737356432418055.240487468111044227aarch" + }, + { + "key": "validator", + "value": "archwayvaloper17wysu3cvfyd9xpxwmym7kw57grufsgkpfc0yrv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "19210593730598865.380000256101014502aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "192105937305988653.800002561010145023aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166zw6w83rksfrqsft3vn2fm546tcpqy64r4hpa" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9489278427943515.403961143343086722aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "189785568558870308.079222866861734448aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1x20lytyf6zkcrv5edpkfkn8sz578qg5sqjl9gf" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8968937631296504.628589616361239585aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "179378752625930092.571792327224791701aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1tunvmmw4v6nedchg3w355k9swt00ld0k0cp3zh" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8455378859240676.386090820451955527aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "169107577184813527.721816409039110538aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1esg4kluvdkfcxl0atcf2us2p9m9y9sjjsu04ex" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "16404526813696481.066932507601551531aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "164045268136964810.669325076015515314aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pnu3tpydg7264ncfv0vy763p56e7drf3pge9qx" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8168428231203281.128240608348785573aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "163368564624065622.564812166975711460aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3mhyp9fvcmuu8l0q8qvjy07x0rql8q42jcedm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "14178063936182338.931016367721810950aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "157534043735359321.455737419131232774aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18wdwndqaaukkgwn4s0ynw7mdddty6h6vtm2g8p" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7854703029852823.032975439319402992aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "157094060597056460.659508786388059831aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kw5n4hk62kqjumc8p900df7ug5e3j8rt6uzlcw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7743600004815286.397101974248501803aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "154872000096305727.942039484970036053aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1a7fng4tw3dxzaxt0c698qgu8v3m9pjvea9k0dy" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "1482294057855007.314932552000893032aarch" + }, + { + "key": "validator", + "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "148229405785500731.493255200089303224aarch" + }, + { + "key": "validator", + "value": "archwayvaloper15qa2dx667akjq7kf4lpfqquedlydsv720uwdhv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "13359505243871239.618113378023869059aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "133595052438712396.181133780238690588aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j84hef7m9jrh36aanr0p4rd5ff2lsjstss5hq6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6580656721752905.788086466423767856aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "131613134435058115.761729328475357112aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1feuxzwn0d498v38799x06n6hqlc5d04ydpczaq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6466157028018950.853027144130551369aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "129323140560379017.060542882611027389aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18tjtnapg85exzkqzt7l8l7hfmka4ann9gqruk5" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6438135218323605.726233885971765429aarch" + }, + { + "key": "validator", + "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "128762704366472114.524677719435308588aarch" + }, + { + "key": "validator", + "value": "archwayvaloper180798qlvh6jmxd9x74t4paweecgenk7j685kxz" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "12794017884026127.345265914463309077aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "127940178840261273.452659144633090770aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eze2npmnmu4mu5gklw02rnp6sa6cqysn8kxjsh" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6389225734475559.818206816817578790aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "127784514689511196.364136336351575792aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1qe8uuf5x69c526h4nzxwv4ltftr73v7q463llj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6216158252482012.324063372662922421aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "124323165049640246.481267453258448429aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1v8er9uqsx0hd6tav2pltqplu2zgj0a3reaaamt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11905578318982044.760484415612078161aarch" + }, + { + "key": "validator", + "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "119055783189820447.604844156120781606aarch" + }, + { + "key": "validator", + "value": "archwayvaloper143y40ycafxs5tqmujx4wrp337ufj93eczp0f3u" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "11891683370351319.802062026190881109aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "118916833703513198.020620261908811086aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1judfxhsvzckqzhd4l3wdwrtn3prggjdq28yc6j" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5755442991049182.108829660463534238aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "115108859820983642.176593209270684757aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lyj3ywvl4cj68sl2ac5rp5y06hdfxx3el7nkzm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9077722380455229.380506937455209582aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "113471529755690367.256336718190119771aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1uvkmmjtvzxtn9cjhd2c9kdncjfslnql8mz786s" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5668877432797758.035339498460660975aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "113377548655955160.706789969213219496aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1j7fgj7v9nqjg6wfda9paldcxezd8yv4qtvgc05" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5512832889092086.888778222282819987aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "110256657781841737.775564445656399745aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1846wx4dzcrm5guey0l5gp4kf6dp2zmqrj6rpcn" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5185781207393984.511267708798404371aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "103715624147879690.225354175968087422aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cz6unq70w0sdm2gwghv8m4uqmhwxz5x4adam88" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5087656794053251.896313112504530285aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "101753135881065037.926262250090605705aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lmpway2t6ltvpvv2rlgp0kk8g7vzkayxe5da3h" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5054011107835986.049813148707928098aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "101080222156719720.996262974158561966aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xajq58h5x2quul39xr0a7lw7zdcsu9wy09v7gm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4983324480805243.727813395134124660aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "99666489616104874.556267902682493205aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1968axqhgdcmyc8xypw53v0092gld8pmqawdapr" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4807932218071933.152612052565173343aarch" + }, + { + "key": "validator", + "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "96158644361438663.052241051303466866aarch" + }, + { + "key": "validator", + "value": "archwayvaloper199r99ywklced4uxav5mgyf5ykc72l74hw4hwp7" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4687805819615643.616671815463040614aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "93756116392312872.333436309260812278aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hvhyunq7qvykzvrcnhjj4xnkcla58xus26rg5n" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "9351170331259227.661311346615131068aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "93511703312592276.613113466151310681aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1k8wmx9texf0velkysk69wkse0gxv7ahtdayy2s" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4644023863116977.859737134376397646aarch" + }, + { + "key": "validator", + "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "92880477262339557.194742687527952914aarch" + }, + { + "key": "validator", + "value": "archwayvaloper132cmdmha0tehev0jhw7r8rcx6ecge45wlfc8vt" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "912388200504138.758207225526939014aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "91238820050413875.820722552693901405aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n3fjzmr2kd9jy8rd2k9c9j30w5zrf3w4s3clvd" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8978481393591310.980058997323930025aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "89784813935913109.800589973239300249aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1pc03t9pxw235pwv29qd0lx3c6zp23q7ccduy07" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8824565070696675.382493341633412224aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "88245650706966753.824933416334122245aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mttfqlpxsehxhevs0c52enktagrwn50edfxxgw" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4333416752722224.028719865116115876aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "86668335054444480.574397302322317512aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1g976ww27dfqcjrzxr3vemcwu7e360yx2u4d5gc" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6933328788175387.893890877583023027aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "86666609852192348.673635969787787835aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1s0lankh33kprer2l22nank5rvsuh9ksatu7zp3" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4243733103515096.420580730000308036aarch" + }, + { + "key": "validator", + "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "84874662070301928.411614600006160723aarch" + }, + { + "key": "validator", + "value": "archwayvaloper134f0zte66y0p6xenkdvsxyrm2pcvn5vmrl7y60" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4202893889546507.856643606258212915aarch" + }, + { + "key": "validator", + "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "84057877790930157.132872125164258306aarch" + }, + { + "key": "validator", + "value": "archwayvaloper19f0w9svr905fhefusyx4z8sf83j6et0g4y4huj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "825314980278520.926122474569125142aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "82531498027852092.612247456912514226aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1emv3genha0hmd058r0g0pttexwg4xeljuw3pdq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4106692652486843.803896504979888971aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "82133853049736876.077930099597779417aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ej2es5fjztqjcd4pwa0zyvaevtjd2y5wkaqkrq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "8165713158806477.593831289907813332aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "81657131588064775.938312899078133322aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jrgjvtv0p5yu3fulz24wfhav577p68fcxgxnw7" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4067085119798264.101275238653982123aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "81341702395965282.025504773079642452aarch" + }, + { + "key": "validator", + "value": "archwayvaloper16vh6jdzrvda47stsjlxap6yukh5pq4q06sgcm6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4038428379110125.223491699819174481aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "80768567582202504.469833996383489616aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1728wq7c67e6xkgkjy546l7996dn8xgtlvv2n3m" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4011530779079081.902164296947431532aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "80230615581581638.043285938948630637aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1gjtvly9lel6zskvwtvlg5vhwpu9c9wawwt839t" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7858482919705247.812176120296811825aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "78584829197052478.121761202968118250aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jdm7fprjl8p94fygap772jpqhq4fekppc6upv4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3914031398029696.642887029199227865aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "78280627960593932.857740583984557309aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1wcynzzk7fj2fsgz2dmk3qr0hk0msezxs48jhcd" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7427074885055624.383377598080804260aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "74270748850556243.833775980808042598aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vnet33snv6xtklyw2ad9dewu3m0z4wh57e4ym4" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3669727204025012.730204512835922843aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "73394544080500254.604090256718456863aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18xqqw8nfrc7zm9286fcl0w64semwxlzgr93gjp" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "7075549371080707.907523881410952171aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "70755493710807079.075238814109521709aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1hccgnft2asahy7hxrk4fx2y6nndk3rwre387zm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3524928999262976.812068470004330586aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "70498579985259536.241369400086611723aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120xprf3m7u6gwsvsggzr4tz4tw2ugxq8vf5a97" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3369963414014993.397773895593761233aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "67399268280299867.955477911875224661aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18zma4gfcnp9pcr5x56qcnedj333vfvp35nq5df" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3271604260039953.880493390780894020aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "65432085200799077.609867815617880394aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1mj2muyc2el7z9l243thhj3crhzzn2ds4tsr7ar" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6513300300708867.960860407706255796aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "65133003007088679.608604077062557955aarch" + }, + { + "key": "validator", + "value": "archwayvaloper166a4vy3609c0wgmrs4kdww79apwceu7nslcp4k" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6372501171331290.296188510554680460aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "63725011713312902.961885105546804595aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1dht6wr376rw07nh60s6qqalatpen8htwk9g499" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3112694749315571.951647849684264150aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "62253894986311439.032956993685282991aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1xn03xz6495xmdkz3pxy8xluvyxuz3r4u7k7m3l" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "6045549890747861.001191402927826369aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "60455498907478610.011914029278263690aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1ep3mayvcxyr26mc3nmk7gkk7krnssuml87y2td" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2896088536058905.787220407162925460aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "57921770721178115.744408143258509194aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1jy9kqql29lefyddmha9xla39qwqv8zxdzep27p" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "5776644595447763.143689776989237028aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "57766445954477631.436897769892370280aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1n7ucxt0afdd2cny94p7syu22chvfttx6le2k80" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2866556467342839.223371187447069231aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "57331129346856784.467423748941384621aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1eufkxcmzzs44d5fzvmy7l4kygdym0vt9pr383f" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2793116587209713.267099558184105951aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "55862331744194265.341991163682119029aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c2f4nd85gcntlleqtx84vcnedqejlhu2r3yhkv" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2666933597568262.366076251068808323aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "53338671951365247.321525021376166458aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kjrhhn2tg6wuvqjjrhr7l65yqhfvmax8mg73u2" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4970468895826418.731609118990295409aarch" + }, + { + "key": "validator", + "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "49704688958264187.316091189902954088aarch" + }, + { + "key": "validator", + "value": "archwayvaloper173zlk665f6f4hl8rnmelhql9qkttc2e79z5xn6" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2363240023083911.006570006371421238aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "47264800461678220.131400127428424751aarch" + }, + { + "key": "validator", + "value": "archwayvaloper10j0jzlpuqkjujrpd5k2qr9j53p3d3w3xlldvk5" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4493096948059239.739356367479582812aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "44930969480592397.393563674795828125aarch" + }, + { + "key": "validator", + "value": "archwayvaloper18qs78duhvkdchrrz9nr4y6t857dwhxqenae350" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4432372656984477.926727020012983425aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "44323726569844779.267270200129834248aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1fzzxu5296sqkye9ccujc9x43h32j5dn8n64wsg" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4356571229506215.000523113016921359aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43565712295062150.005231130169213588aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1zpr0n5mf6ktfdlr2l80pf0a0d0ddzcnfspzgfj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2170089489955256.520683882635905078aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43401789799105130.413677652718101553aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lnjm5he7kd4peahyz874p53xva8rps32r8jlnj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4339276783978658.591339583858475248aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43392767839786585.913395838584752481aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vj2xdt654d7el6eghz63qf8ls8watvkatu6ku8" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4319745231924152.636723327498010671aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "43197452319241526.367233274980106706aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1kv2c4q3d2q396fgfd9mc9g0sfynuf59p7qam9x" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4298086873158816.614500701923440434aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42980868731588166.145007019234404342aarch" + }, + { + "key": "validator", + "value": "archwayvaloper120gntmczryywurtkp6tw8rwjtdxazlscr0tdpm" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4247671372590667.172783278344168560aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42476713725906671.727832783441685605aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1vdmhn49edkx42pk8tzrtuwrvyxahv20jpw0v2k" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "4244848828578158.041721811086383508aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "42448488285781580.417218110863835081aarch" + }, + { + "key": "validator", + "value": "archwayvaloper14q6gk2fdhym8q58x2at9lqke4chuk46emtyvvn" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "" + }, + { + "key": "validator", + "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "37380890503159912.415474413392650975aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1c37x9qfka8ms3pmqkxl39vd8gks6d0dal94vzp" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "2577041792810712.064098004399317701aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "36814882754438743.772828634275967154aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1cuu7t30msk68netlmrqgpumfgwgdfz8c5w4hqj" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "3595358260056104.830343274971172101aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "35953582600561048.303432749711721009aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1rjrcd7826hfghldgpcwtvnxe9e5ku9q5exhlfq" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "897625842806642.500370590272808166aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "29920861426888083.345686342426938867aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1lz9p2lggvnz69dm3gutl3jd9z0gxrhh65j4lrs" + } + ] + }, + { + "type": "commission", + "attributes": [ + { + "key": "amount", + "value": "167630266698905.722389284344961896aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1f66gz07x3qs6ad429845etd5vvhg8p7spc75ln" + } + ] + }, + { + "type": "rewards", + "attributes": [ + { + "key": "amount", + "value": "1676302666989057.223892843449618958aarch" + }, + { + "key": "validator", + "value": "archwayvaloper1f66gz07x3qs6ad429845etd5vvhg8p7spc75ln" + } + ] + } + ], + "end_block_events": [ + { + "type": "archway.rewards.v1.ContractRewardCalculationEvent", + "attributes": [ + { + "key": "contract_address", + "value": "\"archway153l9pc7acv7qw43lyx3f0d3tt02gu80zdlllr4lvwtj9gpk7nu0q7qdagg\"" + }, + { + "key": "fee_rebate_rewards", + "value": "[{\"denom\":\"aarch\",\"amount\":\"44712326671015226\"}]" + }, + { + "key": "gas_consumed", + "value": "\"73689\"" + }, + { + "key": "inflation_rewards", + "value": "{\"denom\":\"aarch\",\"amount\":\"1267441195508077\"}" + }, + { + "key": "metadata", + "value": "null" + } + ] + }, + { + "type": "archway.rewards.v1.ContractRewardCalculationEvent", + "attributes": [ + { + "key": "contract_address", + "value": "\"archway1paztmpff88sjjcrwwej8qlyfz7dlletq640wuxgg4lrpvhvqucqs92wwnj\"" + }, + { + "key": "fee_rebate_rewards", + "value": "[{\"denom\":\"aarch\",\"amount\":\"17612733328984773\"}]" + }, + { + "key": "gas_consumed", + "value": "\"29027\"" + }, + { + "key": "inflation_rewards", + "value": "{\"denom\":\"aarch\",\"amount\":\"499260616672951\"}" + }, + { + "key": "metadata", + "value": "null" + } + ] + }, + { + "type": "archway.rewards.v1.ContractRewardCalculationEvent", + "attributes": [ + { + "key": "contract_address", + "value": "\"archway1zlc00gjw4ecan3tkk5g0lfd78gyfldh4hvkv2g8z5qnwlkz9vqmsdfvs7q\"" + }, + { + "key": "fee_rebate_rewards", + "value": "[{\"denom\":\"aarch\",\"amount\":\"31500000000000000\"}]" + }, + { + "key": "gas_consumed", + "value": "\"118180\"" + }, + { + "key": "inflation_rewards", + "value": "{\"denom\":\"aarch\",\"amount\":\"2032680596631036\"}" + }, + { + "key": "metadata", + "value": "{\"contract_address\":\"archway1zlc00gjw4ecan3tkk5g0lfd78gyfldh4hvkv2g8z5qnwlkz9vqmsdfvs7q\",\"owner_address\":\"archway1d78gwz77n2yywvqyyekrhajzly66skuq06j3j6ptcctl5xh2e4gqa994k3\",\"rewards_address\":\"archway1d78gwz77n2yywvqyyekrhajzly66skuq06j3j6ptcctl5xh2e4gqa994k3\",\"withdraw_to_wallet\":false}" + } + ] + }, + { + "type": "coin_spent", + "attributes": [ + { + "key": "amount", + "value": "5220253277942136587aarch" + }, + { + "key": "spender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "coin_received", + "attributes": [ + { + "key": "amount", + "value": "5220253277942136587aarch" + }, + { + "key": "receiver", + "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" + } + ] + }, + { + "type": "transfer", + "attributes": [ + { + "key": "amount", + "value": "5220253277942136587aarch" + }, + { + "key": "recipient", + "value": "archway1vmafl8f3s6uuzwnxkqz0eza47v6ecn0tutlu4f" + }, + { + "key": "sender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + }, + { + "type": "message", + "attributes": [ + { + "key": "sender", + "value": "archway1245yut9zht8q4hz39sd0lzqtzkuw5us50e94ya" + } + ] + } + ], + "validator_updates": null, + "consensus_param_updates": { + "block": { + "max_bytes": "22020096", + "max_gas": "300000000" + }, + "evidence": { + "max_age_num_blocks": "100000", + "max_age_duration": "172800000000000", + "max_bytes": "1048576" + }, + "validator": { + "pub_key_types": ["ed25519"] + } + } + } + } + } +] From a000f6d3d303d9650c189ad7bb69b08ea8ce4364 Mon Sep 17 00:00:00 2001 From: bz888 Date: Fri, 26 Apr 2024 19:02:48 +0800 Subject: [PATCH 75/81] fix up tests --- packages/node/src/indexer/api.service.test.ts | 6 +----- packages/node/src/utils/kyve/kyve.spec.ts | 5 ++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 069bf9ccb..9674131c6 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -1,7 +1,6 @@ // Copyright 2020-2024 SubQuery Pte Ltd authors & contributors // SPDX-License-Identifier: GPL-3.0 -import fs from 'fs'; import path from 'path'; import { toHex } from '@cosmjs/encoding'; import { Uint53 } from '@cosmjs/math'; @@ -13,13 +12,10 @@ import { loadFromJsonOrYaml, makeTempDir } from '@subql/common'; import { ConnectionPoolService, ConnectionPoolStateManager, - delay, NodeConfig, } from '@subql/node-core'; import { GraphQLSchema } from 'graphql'; -import Pino from 'pino'; import { SubqueryProject } from '../configure/SubqueryProject'; -import { LazyBlockContent } from '../utils/cosmos'; import { ApiService } from './api.service'; const TEST_BLOCKNUMBER = 3266772; @@ -107,7 +103,7 @@ describe('ApiService', () => { const rpcFetchSpy = jest.spyOn(apiService as any, 'retryFetch'); - await apiService.fetchBlocks([1]); + await apiService.fetchBlocks([4282099]); expect(rpcFetchSpy).toHaveBeenCalledTimes(1); }); diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 29583a259..4cf0b9e22 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -358,7 +358,6 @@ describe('KyveApi', () => { const blockRes = (kyveApi as any).decodeBlockResult( blockData.value.block_results, ); - const rpcBlockResult = await tendermint.blockResults(height); const reconstructedKyveBlock = (kyveApi as any).injectLogs(blockRes); expect(JSON.parse(reconstructedKyveBlock.results[0].log).length).toBe(1); @@ -457,8 +456,8 @@ describe('KyveApi', () => { const pollSpy = jest.spyOn(workerKyveApi as any, 'pollUntilReadable'); await Promise.all([ - kyveApi.fetchBlocksBatches(registry, [3856726], 1), - workerKyveApi.fetchBlocksBatches(registry, [3856726], 1), + kyveApi.fetchBlocksBatches(registry, [4326863], 1), + workerKyveApi.fetchBlocksBatches(registry, [4326863], 1), ]); expect(pollSpy).toHaveBeenCalledTimes(1); From 4c8f2305cc107d7361efcfd2266fd12889066852 Mon Sep 17 00:00:00 2001 From: Scott Twiname Date: Tue, 30 Apr 2024 13:12:00 +1200 Subject: [PATCH 76/81] Fix timeout, move buffer arg to constructor --- packages/node/src/indexer/api.service.ts | 32 ++++++++++------------- packages/node/src/utils/kyve/kyve.spec.ts | 10 ++++--- packages/node/src/utils/kyve/kyve.ts | 21 ++++++++++++--- 3 files changed, 37 insertions(+), 26 deletions(-) diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 4cda25ed0..01e65748f 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -115,6 +115,7 @@ export class ApiService this.nodeConfig.kyveStorageUrl, this.nodeConfig.kyveChainId, this.project.fileCacheDir, + KYVE_BUFFER_RANGE * this.nodeConfig.batchSize, ); } catch (e) { logger.warn(`Kyve Api is not connected. ${e}`); @@ -131,25 +132,20 @@ export class ApiService heights: number[], numAttempts = MAX_RECONNECT_ATTEMPTS, ): Promise[]> { - if (this.kyveApi) { - const bufferSize = KYVE_BUFFER_RANGE * this.nodeConfig.batchSize; - try { - return await this.kyveApi.fetchBlocksBatches( - this.registry, - heights, - bufferSize, - ); - } catch (e) { - logger.warn( - e, - `Failed to fetch blocks: ${JSON.stringify( - heights, - )} via Kyve, switching to rpc`, - ); - } - } - return this.retryFetch(async () => { + if (this.kyveApi) { + try { + return await this.kyveApi.fetchBlocksBatches(this.registry, heights); + } catch (e) { + console.log('Kyve error', e, e.stack); + logger.warn( + e, + `Failed to fetch blocks: ${JSON.stringify( + heights, + )} via Kyve, trying with RPC`, + ); + } + } // Get the latest fetch function from the provider const apiInstance = this.connectionPoolService.api; return apiInstance.fetchBlocks(heights); diff --git a/packages/node/src/utils/kyve/kyve.spec.ts b/packages/node/src/utils/kyve/kyve.spec.ts index 4cf0b9e22..9e44c1ce8 100644 --- a/packages/node/src/utils/kyve/kyve.spec.ts +++ b/packages/node/src/utils/kyve/kyve.spec.ts @@ -79,6 +79,7 @@ describe('KyveApi', () => { KYVE_STORAGE_URL, KYVE_CHAINID, tmpPath, + 300, ); const client = new HttpClient('https://rpc.mainnet.archway.io:443'); tendermint = await Tendermint37Client.create(client); @@ -310,8 +311,8 @@ describe('KyveApi', () => { const heights_1 = [150, 300, 1, 301, 450, 550]; const heights_2 = [498, 600, 801, 1100]; const blockArr = await Promise.all([ - kyveApi.fetchBlocksBatches(registry, heights_1, 300), - kyveApi.fetchBlocksBatches(registry, heights_2, 300), + kyveApi.fetchBlocksBatches(registry, heights_1), + kyveApi.fetchBlocksBatches(registry, heights_2), ]); blockArr.forEach((blockContent) => { @@ -433,6 +434,7 @@ describe('KyveApi', () => { KYVE_STORAGE_URL, KYVE_CHAINID, tmpPath, + 1, ); (workerKyveApi as any).cachedBundleDetails = mockCacheDetails; @@ -456,8 +458,8 @@ describe('KyveApi', () => { const pollSpy = jest.spyOn(workerKyveApi as any, 'pollUntilReadable'); await Promise.all([ - kyveApi.fetchBlocksBatches(registry, [4326863], 1), - workerKyveApi.fetchBlocksBatches(registry, [4326863], 1), + kyveApi.fetchBlocksBatches(registry, [4326863]), + workerKyveApi.fetchBlocksBatches(registry, [4326863]), ]); expect(pollSpy).toHaveBeenCalledTimes(1); diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 65b2cabd5..15da12974 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -29,6 +29,7 @@ import { isTmpDir } from '../project'; import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms +const WRITER_TIMEOUT = 3; //sec const POLL_TIMER = 3; // sec const POLL_LIMIT = 10; const MAX_COMPRESSION_BYTE_SIZE = 2 * 10 ** 9; @@ -55,6 +56,7 @@ export class KyveApi { private readonly tmpCacheDir: string, private readonly poolId: string, private readonly lcdClient: KyveLCDClientType, + private readonly removeBuffer: number, ) {} static async create( @@ -63,6 +65,7 @@ export class KyveApi { storageUrl: string, kyveChainId: SupportedChains, tmpCacheDir: string, + removeBuffer: number, // The buffer before a bundle file is removed from disc ): Promise { if (!isTmpDir(tmpCacheDir)) { throw new Error('File cache directory must be a tmp directory'); @@ -77,7 +80,13 @@ export class KyveApi { await KyveApi.clearStaleFiles(tmpCacheDir, poolId); logger.info(`Kyve API connected`); - return new KyveApi(storageUrl, tmpCacheDir, poolId, lcdClient); + return new KyveApi( + storageUrl, + tmpCacheDir, + poolId, + lcdClient, + removeBuffer, + ); } private static async fetchPoolId( @@ -317,7 +326,8 @@ export class KyveApi { writeStream.on('open', resolve); writeStream.on('error', reject); }), - BUNDLE_TIMEOUT, + WRITER_TIMEOUT, + `Timeout waiting for write stream on file ${bundleFilePath}`, ); const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); @@ -527,12 +537,15 @@ export class KyveApi { async fetchBlocksBatches( registry: Registry, blockArray: number[], - bufferSize: number, ): Promise[]> { const blocks = await this.fetchBlocksArray(blockArray); const minHeight = Math.min(...blockArray); - await this.clearFileCache(this.cachedBundleDetails, minHeight, bufferSize); + await this.clearFileCache( + this.cachedBundleDetails, + minHeight, + this.removeBuffer, + ); return blocks.map(([blockInfo, blockResults]) => { try { From 8e1e1e6b95885be0629887b74ca927b4a858e654 Mon Sep 17 00:00:00 2001 From: Scott Twiname Date: Wed, 1 May 2024 13:13:12 +1200 Subject: [PATCH 77/81] Fix up types, improve kyve error handling, fix kyve temp dir --- packages/node/package.json | 2 +- .../node/src/configure/SubqueryProject.ts | 49 +++--- packages/node/src/indexer/api.service.test.ts | 2 +- packages/node/src/indexer/api.service.ts | 13 +- .../block-dispatcher.service.ts | 11 +- .../worker-block-dispatcher.service.ts | 16 +- .../node/src/indexer/dynamic-ds.service.ts | 9 +- packages/node/src/indexer/indexer.manager.ts | 21 ++- packages/node/src/indexer/project.service.ts | 5 +- .../node/src/indexer/worker/worker.service.ts | 3 +- .../node/src/subcommands/testing.service.ts | 7 +- packages/node/src/utils/kyve/kyve.ts | 145 +++++++++--------- yarn.lock | 10 +- 13 files changed, 151 insertions(+), 142 deletions(-) diff --git a/packages/node/package.json b/packages/node/package.json index 3eecab19b..e4a23e6ec 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -31,7 +31,7 @@ "@nestjs/schedule": "^3.0.1", "@subql/common": "^3.5.1", "@subql/common-cosmos": "workspace:*", - "@subql/node-core": "^10.0.0", + "@subql/node-core": "10.0.1-0", "@subql/types-cosmos": "workspace:*", "cron-converter": "^1.0.2", "eventemitter2": "^6.4.5", diff --git a/packages/node/src/configure/SubqueryProject.ts b/packages/node/src/configure/SubqueryProject.ts index de8a535cc..248ce7b3d 100644 --- a/packages/node/src/configure/SubqueryProject.ts +++ b/packages/node/src/configure/SubqueryProject.ts @@ -2,12 +2,15 @@ // SPDX-License-Identifier: GPL-3.0 import assert from 'assert'; +import fs from 'fs'; +import os from 'os'; +import { sep } from 'path'; +import { isMainThread } from 'worker_threads'; import { Injectable } from '@nestjs/common'; import { validateSemver } from '@subql/common'; import { CosmosProjectNetworkConfig, parseCosmosProjectManifest, - CosmosDataSource, ProjectManifestV1_0_0Impl, isRuntimeCosmosDs, isCustomCosmosDs, @@ -16,28 +19,25 @@ import { insertBlockFiltersCronSchedules, ISubqueryProject, loadProjectTemplates, - SubqlProjectDs, updateDataSourcesV1_0_0, + WorkerHost, } from '@subql/node-core'; import { ParentProject, Reader, RunnerSpecs } from '@subql/types-core'; import { + CosmosDatasource, CustomDatasourceTemplate, RuntimeDatasourceTemplate, CosmosHandlerKind, } from '@subql/types-cosmos'; import { buildSchemaFromString } from '@subql/utils'; -import Cron from 'cron-converter'; import { GraphQLSchema } from 'graphql'; -import { KyveApi } from '../utils/kyve/kyve'; import { processNetworkConfig } from '../utils/project'; const { version: packageVersion } = require('../../package.json'); -export type CosmosProjectDs = SubqlProjectDs; - export type CosmosProjectDsTemplate = - | SubqlProjectDs - | SubqlProjectDs; + | RuntimeDatasourceTemplate + | CustomDatasourceTemplate; const NOT_SUPPORT = (name: string) => { throw new Error(`Manifest specVersion ${name} is not supported`); @@ -48,23 +48,23 @@ type NetworkConfig = CosmosProjectNetworkConfig & { chainId: string }; @Injectable() export class SubqueryProject implements ISubqueryProject { - #dataSources: CosmosProjectDs[]; + #dataSources: CosmosDatasource[]; constructor( readonly id: string, readonly root: string, readonly network: NetworkConfig, - dataSources: CosmosProjectDs[], + dataSources: CosmosDatasource[], readonly schema: GraphQLSchema, readonly templates: CosmosProjectDsTemplate[], readonly runner?: RunnerSpecs, readonly parent?: ParentProject, - readonly fileCacheDir?: string, + readonly tempDir?: string, ) { this.#dataSources = dataSources; } - get dataSources(): CosmosProjectDs[] { + get dataSources(): CosmosDatasource[] { return this.#dataSources; } @@ -114,6 +114,23 @@ export class SubqueryProject implements ISubqueryProject { type SUPPORT_MANIFEST = ProjectManifestV1_0_0Impl; +/** + * Gets a temp dir shared between main thread and workers + * */ +function getTempDir(): string { + if (isMainThread) return fs.mkdtempSync(`${os.tmpdir()}${sep}`); + const workerTempDir = ( + (global as any).host as WorkerHost | undefined + )?.getWorkerData()?.tempDir; + + if (!workerTempDir) { + throw new Error( + 'Worker expected tempDir to be provided through workerData', + ); + } + return workerTempDir; +} + async function loadProjectFromManifestBase( projectManifest: SUPPORT_MANIFEST, reader: Reader, @@ -170,12 +187,6 @@ async function loadProjectFromManifestBase( ), ); - const fileCacheDir = await KyveApi.getFileCacheDir( - reader, - root, - network.chainId, - ); - return new SubqueryProject( reader.root ? reader.root : path, //TODO, need to method to get project_id root, @@ -185,6 +196,6 @@ async function loadProjectFromManifestBase( templates, runner, projectManifest.parent, - fileCacheDir, + getTempDir(), ); } diff --git a/packages/node/src/indexer/api.service.test.ts b/packages/node/src/indexer/api.service.test.ts index 9674131c6..844cf2175 100644 --- a/packages/node/src/indexer/api.service.test.ts +++ b/packages/node/src/indexer/api.service.test.ts @@ -37,7 +37,7 @@ function testCosmosProject( root: './', schema: new GraphQLSchema({}), templates: [], - fileCacheDir, + tempDir: fileCacheDir, } as SubqueryProject; } diff --git a/packages/node/src/indexer/api.service.ts b/packages/node/src/indexer/api.service.ts index 01e65748f..6b1e18421 100644 --- a/packages/node/src/indexer/api.service.ts +++ b/packages/node/src/indexer/api.service.ts @@ -114,7 +114,7 @@ export class ApiService this.nodeConfig.kyveEndpoint, this.nodeConfig.kyveStorageUrl, this.nodeConfig.kyveChainId, - this.project.fileCacheDir, + this.project.tempDir, KYVE_BUFFER_RANGE * this.nodeConfig.batchSize, ); } catch (e) { @@ -137,7 +137,6 @@ export class ApiService try { return await this.kyveApi.fetchBlocksBatches(this.registry, heights); } catch (e) { - console.log('Kyve error', e, e.stack); logger.warn( e, `Failed to fetch blocks: ${JSON.stringify( @@ -195,16 +194,6 @@ export class CosmosClient extends CosmWasmClient { super(tendermintClient); } - /* - async chainId(): Promise { - return this.getChainId(); - } - - async finalisedHeight(): Promise { - return this.getHeight(); - } - */ - // eslint-disable-next-line @typescript-eslint/require-await async blockInfo(height?: number): Promise { return this.tendermintClient.block(height); diff --git a/packages/node/src/indexer/blockDispatcher/block-dispatcher.service.ts b/packages/node/src/indexer/blockDispatcher/block-dispatcher.service.ts index 6bfac056c..00086c52b 100644 --- a/packages/node/src/indexer/blockDispatcher/block-dispatcher.service.ts +++ b/packages/node/src/indexer/blockDispatcher/block-dispatcher.service.ts @@ -14,10 +14,8 @@ import { IProjectUpgradeService, IBlock, } from '@subql/node-core'; -import { - CosmosProjectDs, - SubqueryProject, -} from '../../configure/SubqueryProject'; +import { CosmosDatasource } from '@subql/types-cosmos'; +import { SubqueryProject } from '../../configure/SubqueryProject'; import { ApiService } from '../api.service'; import { IndexerManager } from '../indexer.manager'; import { BlockContent } from '../types'; @@ -27,7 +25,7 @@ import { BlockContent } from '../types'; */ @Injectable() export class BlockDispatcherService - extends BlockDispatcher + extends BlockDispatcher implements OnApplicationShutdown { constructor( @@ -35,7 +33,8 @@ export class BlockDispatcherService nodeConfig: NodeConfig, private indexerManager: IndexerManager, eventEmitter: EventEmitter2, - @Inject('IProjectService') projectService: IProjectService, + @Inject('IProjectService') + projectService: IProjectService, @Inject('IProjectUpgradeService') projectUpgradeService: IProjectUpgradeService, storeService: StoreService, diff --git a/packages/node/src/indexer/blockDispatcher/worker-block-dispatcher.service.ts b/packages/node/src/indexer/blockDispatcher/worker-block-dispatcher.service.ts index 15013abc1..bde8fdc4b 100644 --- a/packages/node/src/indexer/blockDispatcher/worker-block-dispatcher.service.ts +++ b/packages/node/src/indexer/blockDispatcher/worker-block-dispatcher.service.ts @@ -4,6 +4,7 @@ import path from 'path'; import { Inject, Injectable, OnApplicationShutdown } from '@nestjs/common'; import { EventEmitter2 } from '@nestjs/event-emitter'; +import { CosmosDataSource } from '@subql/common-cosmos'; import { NodeConfig, StoreService, @@ -16,10 +17,7 @@ import { InMemoryCacheService, createIndexerWorker, } from '@subql/node-core'; -import { - CosmosProjectDs, - SubqueryProject, -} from '../../configure/SubqueryProject'; +import { SubqueryProject } from '../../configure/SubqueryProject'; import { CosmosClientConnection } from '../cosmosClient.connection'; import { DynamicDsService } from '../dynamic-ds.service'; import { BlockContent } from '../types'; @@ -32,13 +30,14 @@ type IndexerWorker = IIndexerWorker & { @Injectable() export class WorkerBlockDispatcherService - extends WorkerBlockDispatcher + extends WorkerBlockDispatcher implements OnApplicationShutdown { constructor( nodeConfig: NodeConfig, eventEmitter: EventEmitter2, - @Inject('IProjectService') projectService: IProjectService, + @Inject('IProjectService') + projectService: IProjectService, @Inject('IProjectUpgradeService') projectUpgadeService: IProjectUpgradeService, cacheService: InMemoryCacheService, @@ -64,7 +63,7 @@ export class WorkerBlockDispatcherService IIndexerWorker, CosmosClientConnection, BlockContent, - CosmosProjectDs + CosmosDataSource >( path.resolve(__dirname, '../../../dist/indexer/worker/worker.js'), [], @@ -75,6 +74,9 @@ export class WorkerBlockDispatcherService connectionPoolState, project.root, projectService.startHeight, + { + tempDir: project.tempDir, + }, ), ); } diff --git a/packages/node/src/indexer/dynamic-ds.service.ts b/packages/node/src/indexer/dynamic-ds.service.ts index 6b65ebc4f..5ce2c326d 100644 --- a/packages/node/src/indexer/dynamic-ds.service.ts +++ b/packages/node/src/indexer/dynamic-ds.service.ts @@ -7,12 +7,13 @@ import { DatasourceParams, DynamicDsService as BaseDynamicDsService, } from '@subql/node-core'; -import { CosmosProjectDs, SubqueryProject } from '../configure/SubqueryProject'; +import { CosmosDatasource } from '@subql/types-cosmos'; +import { SubqueryProject } from '../configure/SubqueryProject'; import { DsProcessorService } from './ds-processor.service'; @Injectable() export class DynamicDsService extends BaseDynamicDsService< - CosmosProjectDs, + CosmosDatasource, SubqueryProject > { constructor( @@ -24,8 +25,8 @@ export class DynamicDsService extends BaseDynamicDsService< protected async getDatasource( params: DatasourceParams, - ): Promise { - const dsObj = this.getTemplate( + ): Promise { + const dsObj = this.getTemplate( params.templateName, params.startBlock, ); diff --git a/packages/node/src/indexer/indexer.manager.ts b/packages/node/src/indexer/indexer.manager.ts index 198ff6e47..fc8060200 100644 --- a/packages/node/src/indexer/indexer.manager.ts +++ b/packages/node/src/indexer/indexer.manager.ts @@ -29,7 +29,6 @@ import { CosmosCustomDatasource, CosmosDatasource, } from '@subql/types-cosmos'; -import { CosmosProjectDs } from '../configure/SubqueryProject'; import * as CosmosUtil from '../utils/cosmos'; import { ApiService as CosmosApiService, @@ -107,8 +106,8 @@ export class IndexerManager extends BaseIndexerManager< protected async indexBlockData( blockContent: BlockContent, - dataSources: CosmosProjectDs[], - getVM: (d: CosmosProjectDs) => Promise, + dataSources: CosmosDatasource[], + getVM: (d: CosmosDatasource) => Promise, ): Promise { await this.indexBlockContent(blockContent, dataSources, getVM); @@ -140,8 +139,8 @@ export class IndexerManager extends BaseIndexerManager< private async indexBlockContent( block: BlockContent, - dataSources: CosmosProjectDs[], - getVM: (d: CosmosProjectDs) => Promise, + dataSources: CosmosDatasource[], + getVM: (d: CosmosDatasource) => Promise, ): Promise { for (const ds of dataSources) { await this.indexData(CosmosHandlerKind.Block, block.block, ds, getVM); @@ -150,8 +149,8 @@ export class IndexerManager extends BaseIndexerManager< private async indexTransaction( tx: CosmosTransaction, - dataSources: CosmosProjectDs[], - getVM: (d: CosmosProjectDs) => Promise, + dataSources: CosmosDatasource[], + getVM: (d: CosmosDatasource) => Promise, ): Promise { for (const ds of dataSources) { await this.indexData(CosmosHandlerKind.Transaction, tx, ds, getVM); @@ -160,8 +159,8 @@ export class IndexerManager extends BaseIndexerManager< private async indexMessage( message: CosmosMessage, - dataSources: CosmosProjectDs[], - getVM: (d: CosmosProjectDs) => Promise, + dataSources: CosmosDatasource[], + getVM: (d: CosmosDatasource) => Promise, ): Promise { for (const ds of dataSources) { await this.indexData(CosmosHandlerKind.Message, message, ds, getVM); @@ -170,8 +169,8 @@ export class IndexerManager extends BaseIndexerManager< private async indexEvent( event: CosmosEvent, - dataSources: CosmosProjectDs[], - getVM: (d: CosmosProjectDs) => Promise, + dataSources: CosmosDatasource[], + getVM: (d: CosmosDatasource) => Promise, ): Promise { for (const ds of dataSources) { await this.indexData(CosmosHandlerKind.Event, event, ds, getVM); diff --git a/packages/node/src/indexer/project.service.ts b/packages/node/src/indexer/project.service.ts index 6ef3eeaff..d91849b15 100644 --- a/packages/node/src/indexer/project.service.ts +++ b/packages/node/src/indexer/project.service.ts @@ -14,8 +14,9 @@ import { IProjectUpgradeService, profiler, } from '@subql/node-core'; +import { CosmosDatasource } from '@subql/types-cosmos'; import { Sequelize } from '@subql/x-sequelize'; -import { SubqueryProject, CosmosProjectDs } from '../configure/SubqueryProject'; +import { SubqueryProject } from '../configure/SubqueryProject'; import { ApiService } from './api.service'; import { DsProcessorService } from './ds-processor.service'; import { DynamicDsService } from './dynamic-ds.service'; @@ -27,7 +28,7 @@ const { version: packageVersion } = require('../../package.json'); @Injectable() export class ProjectService extends BaseProjectService< ApiService, - CosmosProjectDs + CosmosDatasource > { protected packageVersion = packageVersion; diff --git a/packages/node/src/indexer/worker/worker.service.ts b/packages/node/src/indexer/worker/worker.service.ts index f911b5a55..02e10144f 100644 --- a/packages/node/src/indexer/worker/worker.service.ts +++ b/packages/node/src/indexer/worker/worker.service.ts @@ -13,7 +13,6 @@ import { IBlock, } from '@subql/node-core'; import { CosmosDatasource } from '@subql/types-cosmos'; -import { CosmosProjectDs } from '../../configure/SubqueryProject'; import { ApiService } from '../api.service'; import { IndexerManager } from '../indexer.manager'; import { BlockContent } from '../types'; @@ -41,7 +40,7 @@ export class WorkerService extends BaseWorkerService< private apiService: ApiService, private indexerManager: IndexerManager, @Inject('IProjectService') - projectService: IProjectService, + projectService: IProjectService, @Inject('IProjectUpgradeService') projectUpgradeService: IProjectUpgradeService, nodeConfig: NodeConfig, diff --git a/packages/node/src/subcommands/testing.service.ts b/packages/node/src/subcommands/testing.service.ts index 894184676..96aac766a 100644 --- a/packages/node/src/subcommands/testing.service.ts +++ b/packages/node/src/subcommands/testing.service.ts @@ -10,7 +10,8 @@ import { TestingService as BaseTestingService, TestRunner, } from '@subql/node-core'; -import { CosmosProjectDs, SubqueryProject } from '../configure/SubqueryProject'; +import { CosmosDatasource } from '@subql/types-cosmos'; +import { SubqueryProject } from '../configure/SubqueryProject'; import { CosmosClient, CosmosSafeClient } from '../indexer/api.service'; import { IndexerManager } from '../indexer/indexer.manager'; import { ProjectService } from '../indexer/project.service'; @@ -22,7 +23,7 @@ export class TestingService extends BaseTestingService< CosmosClient, CosmosSafeClient, BlockContent, - CosmosProjectDs + CosmosDatasource > { constructor( nodeConfig: NodeConfig, @@ -38,7 +39,7 @@ export class TestingService extends BaseTestingService< CosmosClient, CosmosSafeClient, BlockContent, - CosmosProjectDs + CosmosDatasource >, ] > { diff --git a/packages/node/src/utils/kyve/kyve.ts b/packages/node/src/utils/kyve/kyve.ts index 15da12974..c1d501b06 100644 --- a/packages/node/src/utils/kyve/kyve.ts +++ b/packages/node/src/utils/kyve/kyve.ts @@ -4,7 +4,6 @@ import assert from 'assert'; import fs from 'fs'; import { isMainThread } from 'node:worker_threads'; -import os from 'os'; import path from 'path'; import * as zlib from 'zlib'; import { JsonRpcSuccessResponse } from '@cosmjs/json-rpc'; @@ -19,9 +18,7 @@ import { Responses } from '@cosmjs/tendermint-rpc/build/tendermint37/adaptor'; / import KyveSDK, { KyveLCDClientType } from '@kyvejs/sdk'; import { SupportedChains } from '@kyvejs/sdk/src/constants'; // Currently these types are not exported import { QueryPoolsResponse } from '@kyvejs/types/lcd/kyve/query/v1beta1/pools'; -import { LocalReader } from '@subql/common'; import { delay, getLogger, IBlock, timeout } from '@subql/node-core'; -import { Reader } from '@subql/types-core'; import axios, { AxiosResponse } from 'axios'; import { BlockContent } from '../../indexer/types'; import { formatBlockUtil, LazyBlockContent } from '../cosmos'; @@ -30,6 +27,7 @@ import { BundleDetails } from './kyveTypes'; const BUNDLE_TIMEOUT = 10000; //ms const WRITER_TIMEOUT = 3; //sec +const PROCESS_BUNDLE_TIMEOUT = 20; //sec const POLL_TIMER = 3; // sec const POLL_LIMIT = 10; const MAX_COMPRESSION_BYTE_SIZE = 2 * 10 ** 9; @@ -40,6 +38,10 @@ const parseDecimal = (value: string) => parseInt(value, 10); const logger = getLogger('kyve'); +class ExistsError extends Error { + readonly code = 'EEXIST'; +} + // eslint-disable-next-line @typescript-eslint/no-var-requires const { version: packageVersion } = require('../../../package.json'); @@ -77,7 +79,7 @@ export class KyveApi { const poolId = await KyveApi.fetchPoolId(chainId, lcdClient); - await KyveApi.clearStaleFiles(tmpCacheDir, poolId); + await this.clearStaleFiles(tmpCacheDir, poolId); logger.info(`Kyve API connected`); return new KyveApi( @@ -116,33 +118,32 @@ export class KyveApi { fileCacheDir: string, poolId: string, ): Promise { - if (isMainThread) { - const files = await fs.promises.readdir(fileCacheDir); - - const isStaleBundle = async (file: string) => { - try { - const bundlePath = path.join(fileCacheDir, file); - - const isStale = - ((await fs.promises.stat(bundlePath)).mode & 0o777).toString(8) === - '200'; - - if (isStale) { - await KyveApi.unlinkFile( - bundlePath, - `Removed stale bundle: ${file}`, - ); - } - } catch (e) { - if (e.code !== 'ENOENT') throw e; - } - }; - await Promise.all( - files - .filter((f) => KyveApi.isBundleFile(f, poolId)) - .map((bundleFile) => isStaleBundle(bundleFile)), - ); + if (!isMainThread) { + return; } + const files = await fs.promises.readdir(fileCacheDir); + + const isStaleBundle = async (file: string) => { + try { + const bundlePath = path.join(fileCacheDir, file); + + const isStale = + ((await fs.promises.stat(bundlePath)).mode & 0o777).toString(8) === + '200'; + + if (isStale) { + await KyveApi.unlinkFile(bundlePath, `Removed stale bundle: ${file}`); + } + } catch (e) { + logger.error(e, 'Error clearing stale files'); + if (e.code !== 'ENOENT') throw e; + } + }; + await Promise.all( + files + .filter((f) => KyveApi.isBundleFile(f, poolId)) + .map((bundleFile) => isStaleBundle(bundleFile)), + ); } private static isBundleFile(filename: string, poolId: string): boolean { @@ -173,7 +174,7 @@ export class KyveApi { private async getBundleById(bundleId: number): Promise { return (this.cachedBundleDetails[bundleId] ??= (() => { - logger.debug(`getBundleId ${bundleId}`); + // logger.debug(`getBundleId ${bundleId}`); return this.lcdClient.kyve.query.v1beta1.finalizedBundle({ pool_id: this.poolId, id: bundleId.toString(), @@ -292,7 +293,7 @@ export class KyveApi { bundle = await this.cachedBundleDetails[bundleId]; } - return JSON.parse(await this.getBundleData(bundle)); + return this.getBundleData(bundle); } private async pollUntilReadable(bundleFilePath: string): Promise { @@ -309,12 +310,14 @@ export class KyveApi { } } } - throw new Error('Timeout waiting for bundle'); + throw new Error(`Timeout waiting for bundle ${bundleFilePath}`); } async downloadAndProcessBundle(bundle: BundleDetails): Promise { const bundleFilePath = this.getBundleFilePath(bundle.id); + // We use mode to control permissions amongst workers. + // The mode is updated once the file is finished downloading const writeStream = fs.createWriteStream(bundleFilePath, { flags: 'wx', mode: 0o200, // Ensure that only writer has access to file @@ -322,13 +325,24 @@ export class KyveApi { try { await timeout( - new Promise((resolve, reject) => { + new Promise((resolve, reject) => { writeStream.on('open', resolve); writeStream.on('error', reject); }), WRITER_TIMEOUT, `Timeout waiting for write stream on file ${bundleFilePath}`, - ); + ).catch(async (e) => { + // Timeout might be becaus of a race condition creating a write stream + // So check the file exists and allow continuing + if (e.code === undefined) { + await fs.promises.stat(bundleFilePath).catch((e2) => { + // Throw the original error if we get an error seeing if the file exists + throw e; + }); + throw new ExistsError('File exists when rechecking'); + } + throw e; + }); const zippedBundleData = await this.retrieveBundleData(bundle.storage_id); @@ -337,15 +351,18 @@ export class KyveApi { }); logger.debug(`Retrieving bundle ${bundle.id}`); - logger.info(`Fetching blocks ${bundle.from_key} to ${bundle.to_key}`); - - await new Promise((resolve, reject) => { - zippedBundleData.data - .pipe(gunzip) - .pipe(writeStream) - .on('error', reject) - .on('finish', resolve); - }); + + await timeout( + new Promise((resolve, reject) => { + zippedBundleData.data + .pipe(gunzip) + .pipe(writeStream) + .on('error', reject) + .on('finish', resolve); + }), + PROCESS_BUNDLE_TIMEOUT, + `Timeout processing bundle from download bundleId=${bundle.id}`, + ); await fs.promises.chmod(bundleFilePath, 0o444); @@ -373,16 +390,27 @@ export class KyveApi { } } - private async getBundleData(bundle: BundleDetails): Promise { + private async getBundleData( + bundle: BundleDetails, + ): Promise { const bundleFilePath = this.getBundleFilePath(bundle.id); + let bundleData: string; + try { await this.downloadAndProcessBundle(bundle); - return await this.readFromFile(bundleFilePath); + bundleData = await this.readFromFile(bundleFilePath); } catch (e: any) { if (['EEXIST', 'EACCES'].includes(e.code)) { - const res = await this.pollUntilReadable(bundleFilePath); - return res; + bundleData = await this.pollUntilReadable(bundleFilePath); + } else { + throw e; } + } + + try { + return JSON.parse(bundleData); + } catch (e) { + logger.debug(`Bundle data is invalid ${bundleFilePath}`); await KyveApi.unlinkFile(bundleFilePath); throw e; } @@ -566,25 +594,4 @@ export class KyveApi { } }); } - - static async getFileCacheDir( - reader: Reader, - projectRoot: string, - chainId: string, - ): Promise { - if (isTmpDir(projectRoot)) return projectRoot; - if (reader instanceof LocalReader) { - const tmpDir = path.join(os.tmpdir(), `kyveTmpFileCache_${chainId}`); - try { - await fs.promises.mkdir(tmpDir); - return tmpDir; - } catch (e) { - if (e.code === 'EEXIST') { - return tmpDir; - } - throw e; - } - } - return projectRoot; - } } diff --git a/yarn.lock b/yarn.lock index 4b17e15fb..f110d6423 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6300,9 +6300,9 @@ __metadata: languageName: node linkType: hard -"@subql/node-core@npm:^10.0.0": - version: 10.0.0 - resolution: "@subql/node-core@npm:10.0.0" +"@subql/node-core@npm:10.0.1-0": + version: 10.0.1-0 + resolution: "@subql/node-core@npm:10.0.1-0" dependencies: "@apollo/client": ^3.8.8 "@nestjs/common": ^9.4.0 @@ -6327,7 +6327,7 @@ __metadata: toposort-class: ^1.0.1 vm2: ^3.9.19 yargs: ^16.2.0 - checksum: c52c304ea23c10a171ef411b877032c88733eb6a2262b4a167de9484f7e1fed567bdc36ad1bcb7f9a610d1774a348bd203dc82dd1f7c52f693ff7756c4097d4f + checksum: 6fe1f5eeac265c05f5d0a37c120bd95c459d1fff62899f95545019b657f184d5789511074d8f39fb58dc744c0e18bca7603f34a52f46af2b0533491eb90a6dab languageName: node linkType: hard @@ -6349,7 +6349,7 @@ __metadata: "@nestjs/testing": ^9.4.0 "@subql/common": ^3.5.1 "@subql/common-cosmos": "workspace:*" - "@subql/node-core": ^10.0.0 + "@subql/node-core": 10.0.1-0 "@subql/types-cosmos": "workspace:*" "@types/express": ^4.17.13 "@types/jest": ^27.4.0 From 6cdccf220da7a513e7a83d6cdf3ac02861170a82 Mon Sep 17 00:00:00 2001 From: Scott Twiname Date: Wed, 1 May 2024 13:29:12 +1200 Subject: [PATCH 78/81] Clean up deps --- packages/node/package.json | 5 -- yarn.lock | 159 ++----------------------------------- 2 files changed, 5 insertions(+), 159 deletions(-) diff --git a/packages/node/package.json b/packages/node/package.json index e4a23e6ec..3ff91cd70 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -33,15 +33,10 @@ "@subql/common-cosmos": "workspace:*", "@subql/node-core": "10.0.1-0", "@subql/types-cosmos": "workspace:*", - "cron-converter": "^1.0.2", - "eventemitter2": "^6.4.5", "lodash": "^4.17.21", - "pg": "^8.7.1", "protobufjs": "^6.11.4", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", - "rxjs": "^7.5.2", - "vm2": "^3.9.9", "yargs": "^16.2.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index f110d6423..2ba75dd70 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6357,17 +6357,12 @@ __metadata: "@types/pino": ^6.3.12 "@types/tar": ^6.1.1 "@types/yargs": ^16.0.4 - cron-converter: ^1.0.2 dotenv: ^15.0.1 - eventemitter2: ^6.4.5 lodash: ^4.17.21 nodemon: ^2.0.15 - pg: ^8.7.1 protobufjs: ^6.11.4 reflect-metadata: ^0.1.13 rimraf: ^3.0.2 - rxjs: ^7.5.2 - vm2: ^3.9.9 yargs: ^16.2.0 peerDependencies: "@subql/utils": "*" @@ -8640,13 +8635,6 @@ __metadata: languageName: node linkType: hard -"buffer-writer@npm:2.0.0": - version: 2.0.0 - resolution: "buffer-writer@npm:2.0.0" - checksum: 11736b48bb75106c52ca8ec9f025e7c1b3b25ce31875f469d7210eabd5c576c329e34f6b805d4a8d605ff3f0db1e16342328802c4c963e9c826b0e43a4e631c2 - languageName: node - linkType: hard - "buffer@npm:6.0.3, buffer@npm:^6.0.1, buffer@npm:^6.0.2, buffer@npm:^6.0.3, buffer@npm:~6.0.3": version: 6.0.3 resolution: "buffer@npm:6.0.3" @@ -9494,16 +9482,6 @@ __metadata: languageName: node linkType: hard -"cron-converter@npm:^1.0.2": - version: 1.0.2 - resolution: "cron-converter@npm:1.0.2" - dependencies: - moment-timezone: ~0.5 - sprintf-js: ~1 - checksum: 7bbd01f29a6fc5a8a8c8dabda3a6468b7040acd374beadbf103d6c86f9e85c961a0937cfa2a997e4bfcdcd6bd07cde658a3009b899130e69e6c9ceb5f0a82ac3 - languageName: node - linkType: hard - "cron@npm:2.4.1": version: 2.4.1 resolution: "cron@npm:2.4.1" @@ -10688,7 +10666,7 @@ __metadata: languageName: node linkType: hard -"eventemitter2@npm:6.4.9, eventemitter2@npm:^6.4.5": +"eventemitter2@npm:6.4.9": version: 6.4.9 resolution: "eventemitter2@npm:6.4.9" checksum: be59577c1e1c35509c7ba0e2624335c35bbcfd9485b8a977384c6cc6759341ea1a98d3cb9dbaa5cea4fff9b687e504504e3f9c2cc1674cf3bd8a43a7c74ea3eb @@ -14445,7 +14423,7 @@ __metadata: languageName: node linkType: hard -"moment-timezone@npm:^0.5.35, moment-timezone@npm:~0.5": +"moment-timezone@npm:^0.5.35": version: 0.5.43 resolution: "moment-timezone@npm:0.5.43" dependencies: @@ -15245,13 +15223,6 @@ __metadata: languageName: node linkType: hard -"packet-reader@npm:1.0.0": - version: 1.0.0 - resolution: "packet-reader@npm:1.0.0" - checksum: 0b7516f0cbf3e322aad591bed29ba544220088c53943145c0d9121a6f59182ad811f7fd6785a8979a34356aca69d97653689029964c5998dc02645633d88ffd7 - languageName: node - linkType: hard - "pako@npm:^2.0.2": version: 2.1.0 resolution: "pako@npm:2.1.0" @@ -15453,89 +15424,13 @@ __metadata: languageName: node linkType: hard -"pg-cloudflare@npm:^1.1.1": - version: 1.1.1 - resolution: "pg-cloudflare@npm:1.1.1" - checksum: 32aac06b5dc4588bbf78801b6267781bc7e13be672009df949d08e9627ba9fdc26924916665d4de99d47f9b0495301930547488dad889d826856976c7b3f3731 - languageName: node - linkType: hard - -"pg-connection-string@npm:^2.5.0, pg-connection-string@npm:^2.6.2": +"pg-connection-string@npm:^2.5.0": version: 2.6.2 resolution: "pg-connection-string@npm:2.6.2" checksum: 22265882c3b6f2320785378d0760b051294a684989163d5a1cde4009e64e84448d7bf67d9a7b9e7f69440c3ee9e2212f9aa10dd17ad6773f6143c6020cebbcb5 languageName: node linkType: hard -"pg-int8@npm:1.0.1": - version: 1.0.1 - resolution: "pg-int8@npm:1.0.1" - checksum: a1e3a05a69005ddb73e5f324b6b4e689868a447c5fa280b44cd4d04e6916a344ac289e0b8d2695d66e8e89a7fba023affb9e0e94778770ada5df43f003d664c9 - languageName: node - linkType: hard - -"pg-pool@npm:^3.6.1": - version: 3.6.1 - resolution: "pg-pool@npm:3.6.1" - peerDependencies: - pg: ">=8.0" - checksum: 8a6513e6f74a794708c9dd16d2ccda0debadc56435ec2582de2b2e35b01315550c5dab8a0a9a2a16f4adce45523228f5739940fb7687ec7e9c300f284eb08fd1 - languageName: node - linkType: hard - -"pg-protocol@npm:^1.6.0": - version: 1.6.0 - resolution: "pg-protocol@npm:1.6.0" - checksum: e12662d2de2011e0c3a03f6a09f435beb1025acdc860f181f18a600a5495dc38a69d753bbde1ace279c8c442536af9c1a7c11e1d0fe3fad3aa1348b28d9d2683 - languageName: node - linkType: hard - -"pg-types@npm:^2.1.0": - version: 2.2.0 - resolution: "pg-types@npm:2.2.0" - dependencies: - pg-int8: 1.0.1 - postgres-array: ~2.0.0 - postgres-bytea: ~1.0.0 - postgres-date: ~1.0.4 - postgres-interval: ^1.1.0 - checksum: bf4ec3f594743442857fb3a8dfe5d2478a04c98f96a0a47365014557cbc0b4b0cee01462c79adca863b93befbf88f876299b75b72c665b5fb84a2c94fbd10316 - languageName: node - linkType: hard - -"pg@npm:^8.7.1": - version: 8.11.3 - resolution: "pg@npm:8.11.3" - dependencies: - buffer-writer: 2.0.0 - packet-reader: 1.0.0 - pg-cloudflare: ^1.1.1 - pg-connection-string: ^2.6.2 - pg-pool: ^3.6.1 - pg-protocol: ^1.6.0 - pg-types: ^2.1.0 - pgpass: 1.x - peerDependencies: - pg-native: ">=3.0.1" - dependenciesMeta: - pg-cloudflare: - optional: true - peerDependenciesMeta: - pg-native: - optional: true - checksum: 8af9468b8969fa0d73a6b349216c8cbc953d938fcae5594f2d24043060e9226a072c8085fc4230172b5576fcab4c39c8563c655f271dc2a9209b6ad5370cafe5 - languageName: node - linkType: hard - -"pgpass@npm:1.x": - version: 1.0.5 - resolution: "pgpass@npm:1.0.5" - dependencies: - split2: ^4.1.0 - checksum: 947ac096c031eebdf08d989de2e9f6f156b8133d6858c7c2c06c041e1e71dda6f5f3bad3c0ec1e96a09497bbc6ef89e762eefe703b5ef9cb2804392ec52ec400 - languageName: node - linkType: hard - "picocolors@npm:^1.0.0": version: 1.0.0 resolution: "picocolors@npm:1.0.0" @@ -15623,36 +15518,6 @@ __metadata: languageName: node linkType: hard -"postgres-array@npm:~2.0.0": - version: 2.0.0 - resolution: "postgres-array@npm:2.0.0" - checksum: 0e1e659888147c5de579d229a2d95c0d83ebdbffc2b9396d890a123557708c3b758a0a97ed305ce7f58edfa961fa9f0bbcd1ea9f08b6e5df73322e683883c464 - languageName: node - linkType: hard - -"postgres-bytea@npm:~1.0.0": - version: 1.0.0 - resolution: "postgres-bytea@npm:1.0.0" - checksum: d844ae4ca7a941b70e45cac1261a73ee8ed39d72d3d74ab1d645248185a1b7f0ac91a3c63d6159441020f4e1f7fe64689ac56536a307b31cef361e5187335090 - languageName: node - linkType: hard - -"postgres-date@npm:~1.0.4": - version: 1.0.7 - resolution: "postgres-date@npm:1.0.7" - checksum: 5745001d47e51cd767e46bcb1710649cd705d91a24d42fa661c454b6dcbb7353c066a5047983c90a626cd3bbfea9e626cc6fa84a35ec57e5bbb28b49f78e13ed - languageName: node - linkType: hard - -"postgres-interval@npm:^1.1.0": - version: 1.2.0 - resolution: "postgres-interval@npm:1.2.0" - dependencies: - xtend: ^4.0.0 - checksum: 746b71f93805ae33b03528e429dc624706d1f9b20ee81bf743263efb6a0cd79ae02a642a8a480dbc0f09547b4315ab7df6ce5ec0be77ed700bac42730f5c76b2 - languageName: node - linkType: hard - "prando@npm:^6.0.1": version: 6.0.1 resolution: "prando@npm:6.0.1" @@ -16512,7 +16377,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:7.8.1, rxjs@npm:^7.5.2, rxjs@npm:^7.5.5": +"rxjs@npm:7.8.1, rxjs@npm:^7.5.5": version: 7.8.1 resolution: "rxjs@npm:7.8.1" dependencies: @@ -17000,20 +16865,6 @@ __metadata: languageName: node linkType: hard -"split2@npm:^4.1.0": - version: 4.2.0 - resolution: "split2@npm:4.2.0" - checksum: 05d54102546549fe4d2455900699056580cca006c0275c334611420f854da30ac999230857a85fdd9914dc2109ae50f80fda43d2a445f2aa86eccdc1dfce779d - languageName: node - linkType: hard - -"sprintf-js@npm:~1": - version: 1.1.3 - resolution: "sprintf-js@npm:1.1.3" - checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 - languageName: node - linkType: hard - "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -18461,7 +18312,7 @@ __metadata: languageName: node linkType: hard -"vm2@npm:^3.9.19, vm2@npm:^3.9.9": +"vm2@npm:^3.9.19": version: 3.9.19 resolution: "vm2@npm:3.9.19" dependencies: From 125a2ac7012fdb6c3064ec9e88ee436e25ce7452 Mon Sep 17 00:00:00 2001 From: Scott Twiname Date: Wed, 1 May 2024 16:03:05 +1200 Subject: [PATCH 79/81] Fix not applying timestamp block filers --- packages/node/package.json | 1 + .../node/src/configure/SubqueryProject.ts | 9 +++++ packages/node/src/utils/cosmos.ts | 38 ++++++++++++++++++- yarn.lock | 27 +++++++++++++ 4 files changed, 74 insertions(+), 1 deletion(-) diff --git a/packages/node/package.json b/packages/node/package.json index 3ff91cd70..3fd73811d 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -33,6 +33,7 @@ "@subql/common-cosmos": "workspace:*", "@subql/node-core": "10.0.1-0", "@subql/types-cosmos": "workspace:*", + "cron-converter": "^1.0.2", "lodash": "^4.17.21", "protobufjs": "^6.11.4", "reflect-metadata": "^0.1.13", diff --git a/packages/node/src/configure/SubqueryProject.ts b/packages/node/src/configure/SubqueryProject.ts index 248ce7b3d..707174fa5 100644 --- a/packages/node/src/configure/SubqueryProject.ts +++ b/packages/node/src/configure/SubqueryProject.ts @@ -28,8 +28,10 @@ import { CustomDatasourceTemplate, RuntimeDatasourceTemplate, CosmosHandlerKind, + CosmosBlockFilter, } from '@subql/types-cosmos'; import { buildSchemaFromString } from '@subql/utils'; +import Cron from 'cron-converter'; import { GraphQLSchema } from 'graphql'; import { processNetworkConfig } from '../utils/project'; @@ -39,6 +41,13 @@ export type CosmosProjectDsTemplate = | RuntimeDatasourceTemplate | CustomDatasourceTemplate; +export type SubqlProjectBlockFilter = CosmosBlockFilter & { + cronSchedule?: { + schedule: Cron.Seeker; + next: number; + }; +}; + const NOT_SUPPORT = (name: string) => { throw new Error(`Manifest specVersion ${name} is not supported`); }; diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index f0b6a55c9..06a817b9c 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -6,13 +6,15 @@ import { TextDecoder } from 'util'; import { sha256 } from '@cosmjs/crypto'; import { toHex } from '@cosmjs/encoding'; import { DecodeObject, decodeTxRaw, Registry } from '@cosmjs/proto-signing'; -import { fromTendermintEvent } from '@cosmjs/stargate'; +import { Block, fromTendermintEvent } from '@cosmjs/stargate'; import { Log, parseRawLog } from '@cosmjs/stargate/build/logs'; +import { toRfc3339WithNanoseconds } from '@cosmjs/tendermint-rpc'; import { BlockResponse, BlockResultsResponse, TxData, Event, + Header as CosmosHeader, } from '@cosmjs/tendermint-rpc/build/tendermint37'; import { IBlock, getLogger, Header } from '@subql/node-core'; import { @@ -26,6 +28,7 @@ import { CosmosTxFilter, } from '@subql/types-cosmos'; import { isObjectLike } from 'lodash'; +import { SubqlProjectBlockFilter } from '../configure/SubqueryProject'; import { CosmosClient } from '../indexer/api.service'; import { BlockContent } from '../indexer/types'; @@ -60,12 +63,45 @@ export function filterBlock( if (!filter) { return true; } + if (filter.timestamp) { + if (!filterBlockTimestamp(data, filter as SubqlProjectBlockFilter)) { + return; + } + } if (filter.modulo && data.block.header.height % filter.modulo !== 0) { return false; } return true; } +export function getBlockTimestamp(blockHeader: CosmosHeader): Date { + return new Date(toRfc3339WithNanoseconds(blockHeader.time)); +} + +export function filterBlockTimestamp( + block: CosmosBlock, + filter: SubqlProjectBlockFilter, +): boolean { + const unixTimestamp = getBlockTimestamp(block.header).getTime(); + if (unixTimestamp > filter.cronSchedule.next) { + logger.info( + `Block with timestamp ${new Date( + unixTimestamp, + ).toString()} is about to be indexed`, + ); + logger.info( + `Next block will be indexed at ${new Date( + filter.cronSchedule.next, + ).toString()}`, + ); + filter.cronSchedule.schedule.prev(); + return true; + } else { + filter.cronSchedule.schedule.prev(); + return false; + } +} + export function filterTx( data: CosmosTransaction, filter?: CosmosTxFilter, diff --git a/yarn.lock b/yarn.lock index 2ba75dd70..73008d028 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6357,6 +6357,7 @@ __metadata: "@types/pino": ^6.3.12 "@types/tar": ^6.1.1 "@types/yargs": ^16.0.4 + cron-converter: ^1.0.2 dotenv: ^15.0.1 lodash: ^4.17.21 nodemon: ^2.0.15 @@ -9482,6 +9483,16 @@ __metadata: languageName: node linkType: hard +"cron-converter@npm:^1.0.2": + version: 1.0.2 + resolution: "cron-converter@npm:1.0.2" + dependencies: + moment-timezone: ~0.5 + sprintf-js: ~1 + checksum: 7bbd01f29a6fc5a8a8c8dabda3a6468b7040acd374beadbf103d6c86f9e85c961a0937cfa2a997e4bfcdcd6bd07cde658a3009b899130e69e6c9ceb5f0a82ac3 + languageName: node + linkType: hard + "cron@npm:2.4.1": version: 2.4.1 resolution: "cron@npm:2.4.1" @@ -14432,6 +14443,15 @@ __metadata: languageName: node linkType: hard +"moment-timezone@npm:~0.5": + version: 0.5.45 + resolution: "moment-timezone@npm:0.5.45" + dependencies: + moment: ^2.29.4 + checksum: a22e9f983fbe1a01757ce30685bce92e3f6efa692eb682afd47b82da3ff960b3c8c2c3883ec6715c124bc985a342b57cba1f6ba25a1c8b4c7ad766db3cd5e1d0 + languageName: node + linkType: hard + "moment@npm:>=2.14.0, moment@npm:^2.29.1, moment@npm:^2.29.4": version: 2.29.4 resolution: "moment@npm:2.29.4" @@ -16865,6 +16885,13 @@ __metadata: languageName: node linkType: hard +"sprintf-js@npm:~1": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 + languageName: node + linkType: hard + "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" From 997c94de98b766968238161385d9786c79226fd1 Mon Sep 17 00:00:00 2001 From: Scott Twiname Date: Thu, 2 May 2024 10:55:19 +1200 Subject: [PATCH 80/81] Update deps and use code from node-core --- package.json | 1 - packages/node/package.json | 3 +- .../node/src/configure/SubqueryProject.ts | 9 +-- packages/node/src/utils/cosmos.ts | 44 ++++-------- yarn.lock | 68 +++++++------------ 5 files changed, 41 insertions(+), 84 deletions(-) diff --git a/package.json b/package.json index d9b093e8c..9be824799 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,6 @@ "@actions/core": "^1.10.0", "@babel/preset-env": "^7.16.11", "@octokit/request": "^5.6.3", - "@types/cron-converter": "^1", "@types/node": "^18.16.10", "@types/node-fetch": "2.6.2", "@typescript-eslint/eslint-plugin": "^5.10.2", diff --git a/packages/node/package.json b/packages/node/package.json index 3fd73811d..fa81538a0 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -31,9 +31,8 @@ "@nestjs/schedule": "^3.0.1", "@subql/common": "^3.5.1", "@subql/common-cosmos": "workspace:*", - "@subql/node-core": "10.0.1-0", + "@subql/node-core": "^10.1.0", "@subql/types-cosmos": "workspace:*", - "cron-converter": "^1.0.2", "lodash": "^4.17.21", "protobufjs": "^6.11.4", "reflect-metadata": "^0.1.13", diff --git a/packages/node/src/configure/SubqueryProject.ts b/packages/node/src/configure/SubqueryProject.ts index 707174fa5..926ae3949 100644 --- a/packages/node/src/configure/SubqueryProject.ts +++ b/packages/node/src/configure/SubqueryProject.ts @@ -16,6 +16,7 @@ import { isCustomCosmosDs, } from '@subql/common-cosmos'; import { + CronFilter, insertBlockFiltersCronSchedules, ISubqueryProject, loadProjectTemplates, @@ -31,7 +32,6 @@ import { CosmosBlockFilter, } from '@subql/types-cosmos'; import { buildSchemaFromString } from '@subql/utils'; -import Cron from 'cron-converter'; import { GraphQLSchema } from 'graphql'; import { processNetworkConfig } from '../utils/project'; @@ -41,12 +41,7 @@ export type CosmosProjectDsTemplate = | RuntimeDatasourceTemplate | CustomDatasourceTemplate; -export type SubqlProjectBlockFilter = CosmosBlockFilter & { - cronSchedule?: { - schedule: Cron.Seeker; - next: number; - }; -}; +export type SubqlProjectBlockFilter = CosmosBlockFilter & CronFilter; const NOT_SUPPORT = (name: string) => { throw new Error(`Manifest specVersion ${name} is not supported`); diff --git a/packages/node/src/utils/cosmos.ts b/packages/node/src/utils/cosmos.ts index 06a817b9c..b44686e2a 100644 --- a/packages/node/src/utils/cosmos.ts +++ b/packages/node/src/utils/cosmos.ts @@ -6,7 +6,7 @@ import { TextDecoder } from 'util'; import { sha256 } from '@cosmjs/crypto'; import { toHex } from '@cosmjs/encoding'; import { DecodeObject, decodeTxRaw, Registry } from '@cosmjs/proto-signing'; -import { Block, fromTendermintEvent } from '@cosmjs/stargate'; +import { fromTendermintEvent } from '@cosmjs/stargate'; import { Log, parseRawLog } from '@cosmjs/stargate/build/logs'; import { toRfc3339WithNanoseconds } from '@cosmjs/tendermint-rpc'; import { @@ -16,7 +16,12 @@ import { Event, Header as CosmosHeader, } from '@cosmjs/tendermint-rpc/build/tendermint37'; -import { IBlock, getLogger, Header } from '@subql/node-core'; +import { + IBlock, + getLogger, + Header, + filterBlockTimestamp, +} from '@subql/node-core'; import { CosmosEventFilter, CosmosMessageFilter, @@ -63,10 +68,13 @@ export function filterBlock( if (!filter) { return true; } - if (filter.timestamp) { - if (!filterBlockTimestamp(data, filter as SubqlProjectBlockFilter)) { - return; - } + if ( + !filterBlockTimestamp( + getBlockTimestamp(data.header).getTime(), + filter as SubqlProjectBlockFilter, + ) + ) { + return false; } if (filter.modulo && data.block.header.height % filter.modulo !== 0) { return false; @@ -78,30 +86,6 @@ export function getBlockTimestamp(blockHeader: CosmosHeader): Date { return new Date(toRfc3339WithNanoseconds(blockHeader.time)); } -export function filterBlockTimestamp( - block: CosmosBlock, - filter: SubqlProjectBlockFilter, -): boolean { - const unixTimestamp = getBlockTimestamp(block.header).getTime(); - if (unixTimestamp > filter.cronSchedule.next) { - logger.info( - `Block with timestamp ${new Date( - unixTimestamp, - ).toString()} is about to be indexed`, - ); - logger.info( - `Next block will be indexed at ${new Date( - filter.cronSchedule.next, - ).toString()}`, - ); - filter.cronSchedule.schedule.prev(); - return true; - } else { - filter.cronSchedule.schedule.prev(); - return false; - } -} - export function filterTx( data: CosmosTransaction, filter?: CosmosTxFilter, diff --git a/yarn.lock b/yarn.lock index 73008d028..877e384c7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6300,9 +6300,9 @@ __metadata: languageName: node linkType: hard -"@subql/node-core@npm:10.0.1-0": - version: 10.0.1-0 - resolution: "@subql/node-core@npm:10.0.1-0" +"@subql/node-core@npm:^10.1.0": + version: 10.1.0 + resolution: "@subql/node-core@npm:10.1.0" dependencies: "@apollo/client": ^3.8.8 "@nestjs/common": ^9.4.0 @@ -6311,10 +6311,11 @@ __metadata: "@subql/common": 3.5.1 "@subql/testing": 2.1.1 "@subql/types": 3.5.0 - "@subql/utils": 2.9.1 + "@subql/utils": 2.9.2 "@willsoto/nestjs-prometheus": ^5.4.0 async-lock: ^1.4.0 async-mutex: ^0.4.0 + cron-converter: ^2.0.1 cross-fetch: ^3.1.6 csv-stringify: ^6.4.5 dayjs: ^1.10.7 @@ -6327,7 +6328,7 @@ __metadata: toposort-class: ^1.0.1 vm2: ^3.9.19 yargs: ^16.2.0 - checksum: 6fe1f5eeac265c05f5d0a37c120bd95c459d1fff62899f95545019b657f184d5789511074d8f39fb58dc744c0e18bca7603f34a52f46af2b0533491eb90a6dab + checksum: b7df8c672e93bc6339d47c4a8c806dd8fca7c1a24e0ce0ac065925928151bc476b8cf9f6149e85c472085f81800d601a79ea6fd8e1e0ca09636b09fdc3371dd0 languageName: node linkType: hard @@ -6349,7 +6350,7 @@ __metadata: "@nestjs/testing": ^9.4.0 "@subql/common": ^3.5.1 "@subql/common-cosmos": "workspace:*" - "@subql/node-core": 10.0.1-0 + "@subql/node-core": ^10.1.0 "@subql/types-cosmos": "workspace:*" "@types/express": ^4.17.13 "@types/jest": ^27.4.0 @@ -6357,7 +6358,6 @@ __metadata: "@types/pino": ^6.3.12 "@types/tar": ^6.1.1 "@types/yargs": ^16.0.4 - cron-converter: ^1.0.2 dotenv: ^15.0.1 lodash: ^4.17.21 nodemon: ^2.0.15 @@ -6412,9 +6412,9 @@ __metadata: languageName: node linkType: hard -"@subql/utils@npm:2.9.1": - version: 2.9.1 - resolution: "@subql/utils@npm:2.9.1" +"@subql/utils@npm:2.9.2": + version: 2.9.2 + resolution: "@subql/utils@npm:2.9.2" dependencies: "@polkadot/util": ^12.5.1 "@polkadot/util-crypto": ^12.5.1 @@ -6430,7 +6430,7 @@ __metadata: rotating-file-stream: ^3.0.2 semver: ^7.5.2 tar: ^6.2.1 - checksum: 555c215f44ac6f6828ade30c3643e260bf99ef3c14381d14a9e9ba3c9fa5cfd0a4e938b3a2fbd907379ad2b832bb79a5071f96966b32d751824affb9cea266c8 + checksum: fd2f32136d0324e3b19e826e4760e90db36e66b580ee244e77fa96124389d3253923c74ab98a07799803ba2421c285b68bc42b295e8a3b48376db34405adb872 languageName: node linkType: hard @@ -6713,15 +6713,6 @@ __metadata: languageName: node linkType: hard -"@types/cron-converter@npm:^1": - version: 1.0.1 - resolution: "@types/cron-converter@npm:1.0.1" - dependencies: - moment: ">=2.14.0" - checksum: 93a0a81d44a12d7cc748e124e459037349863ecf10c47316c7693e96367c735fe463afb2bd22f82c5bdb2679e67f247dfca71403d3e4df0bee2d24b63698004a - languageName: node - linkType: hard - "@types/debug@npm:^4.1.7": version: 4.1.8 resolution: "@types/debug@npm:4.1.8" @@ -9483,13 +9474,12 @@ __metadata: languageName: node linkType: hard -"cron-converter@npm:^1.0.2": - version: 1.0.2 - resolution: "cron-converter@npm:1.0.2" +"cron-converter@npm:^2.0.1": + version: 2.0.1 + resolution: "cron-converter@npm:2.0.1" dependencies: - moment-timezone: ~0.5 - sprintf-js: ~1 - checksum: 7bbd01f29a6fc5a8a8c8dabda3a6468b7040acd374beadbf103d6c86f9e85c961a0937cfa2a997e4bfcdcd6bd07cde658a3009b899130e69e6c9ceb5f0a82ac3 + luxon: ^3.1.0 + checksum: 74ef69ec7e9020183cfa8f117fe687c654ba32f863ae8cf86a834b5baafd1321ee0d9caa62cc8e6e4cfe02b255f237ed0a0f91f0da78d01eb49317d06bf76f3d languageName: node linkType: hard @@ -13974,6 +13964,13 @@ __metadata: languageName: node linkType: hard +"luxon@npm:^3.1.0": + version: 3.4.4 + resolution: "luxon@npm:3.4.4" + checksum: 36c1f99c4796ee4bfddf7dc94fa87815add43ebc44c8934c924946260a58512f0fd2743a629302885df7f35ccbd2d13f178c15df046d0e3b6eb71db178f1c60c + languageName: node + linkType: hard + "luxon@npm:^3.2.1": version: 3.4.3 resolution: "luxon@npm:3.4.3" @@ -14443,16 +14440,7 @@ __metadata: languageName: node linkType: hard -"moment-timezone@npm:~0.5": - version: 0.5.45 - resolution: "moment-timezone@npm:0.5.45" - dependencies: - moment: ^2.29.4 - checksum: a22e9f983fbe1a01757ce30685bce92e3f6efa692eb682afd47b82da3ff960b3c8c2c3883ec6715c124bc985a342b57cba1f6ba25a1c8b4c7ad766db3cd5e1d0 - languageName: node - linkType: hard - -"moment@npm:>=2.14.0, moment@npm:^2.29.1, moment@npm:^2.29.4": +"moment@npm:^2.29.1, moment@npm:^2.29.4": version: 2.29.4 resolution: "moment@npm:2.29.4" checksum: 0ec3f9c2bcba38dc2451b1daed5daded747f17610b92427bebe1d08d48d8b7bdd8d9197500b072d14e326dd0ccf3e326b9e3d07c5895d3d49e39b6803b76e80e @@ -16885,13 +16873,6 @@ __metadata: languageName: node linkType: hard -"sprintf-js@npm:~1": - version: 1.1.3 - resolution: "sprintf-js@npm:1.1.3" - checksum: a3fdac7b49643875b70864a9d9b469d87a40dfeaf5d34d9d0c5b1cda5fd7d065531fcb43c76357d62254c57184a7b151954156563a4d6a747015cfb41021cad0 - languageName: node - linkType: hard - "sprintf-js@npm:~1.0.2": version: 1.0.3 resolution: "sprintf-js@npm:1.0.3" @@ -17169,7 +17150,6 @@ __metadata: "@babel/preset-env": ^7.16.11 "@geut/chan": ^3.2.9 "@octokit/request": ^5.6.3 - "@types/cron-converter": ^1 "@types/node": ^18.16.10 "@types/node-fetch": 2.6.2 "@typescript-eslint/eslint-plugin": ^5.10.2 From e138dc5175d936cb4af28c287f0874d8c2557bfd Mon Sep 17 00:00:00 2001 From: Scott Twiname Date: Thu, 2 May 2024 10:56:01 +1200 Subject: [PATCH 81/81] Add script for updating versions: --- scripts/update_versions.sh | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100755 scripts/update_versions.sh diff --git a/scripts/update_versions.sh b/scripts/update_versions.sh new file mode 100755 index 000000000..f8fba526c --- /dev/null +++ b/scripts/update_versions.sh @@ -0,0 +1,78 @@ +#!/bin/sh +set -e + +LIGHT_BLUE='\033[1;34m' +YELLOW='\033[1;33m' +NC='\033[0m' + +# Function to echo unreleased changes from CHANGELOG.md +echo_unreleased_changes() { + local changelog_file="$1" + + # Check if the provided argument is a valid file + if [ ! -f "$changelog_file" ]; then + echo "Changelog doesn't exist" + return 1 + fi + + # Use sed to extract the line number of the start and end of the unreleased changes + local start_line=$(sed -n '/## \[Unreleased\]/=' "$changelog_file") + local end_line=$(sed -n '/## \[/=' "$changelog_file" | sed -n 2p) + + # Use awk to extract the unreleased changes + local changes=$(awk "NR > $start_line && NR < $end_line" "$changelog_file") + + # Check if there are any changes + if [ -z "$changes" ]; then + echo "No unreleased changes found. Please include some changes and try again" + exit 1 + else + echo "Unreleased Changes:\n${LIGHT_BLUE}$changes${NC}\n" + fi +} + +prepare_package_release() { + local dir="$1" + + # Check if the provided argument is a valid file + if [ ! -d "$dir" ]; then + echo "Expected $dir to be a directory" + exit 1 + fi + + # Movde into the directory in the path + cd "$dir" + + # Get the version from package.json + VERSION=$(jq -r '.version' package.json) + NAME=$(jq -r '.name' package.json) + + # Check if the version is a prerelease (ends with a hyphen and one or more digits) + if [[ $VERSION =~ -[0-9]+$ ]]; then + # Prompt the user for the version bump + echo "Please select the version bump for ${YELLOW}$NAME${NC}" + echo_unreleased_changes "./CHANGELOG.md" + read -p "Version bump (major, minor or patch): " BUMP + + # Update the package.json version + yarn version $BUMP + + # Run the changelog:release command + yarn changelog:release + fi + + # Back to previous dir + cd - +} + +## Warning this will not automatically update packages that just have dependency changes +## E.g. when @subql/common is updated, @subql/common-substrate should also be updated +## It also doesn't do things in order of dependencies +for dir in packages/*; do + # Check the path is a directory and is tracked by git + if [ -d "$dir" ] && [[ $(git ls-files "$dir") ]]; then + prepare_package_release "$dir" + fi +done + +# prepare_package_release "$1"