-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* wip: fetch-storage * wip: fetch storages * fix cli * refactor * refactor and fix * worker * fix
- Loading branch information
Showing
14 changed files
with
482 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { z } from 'zod' | ||
import _ from 'lodash' | ||
import type { Argv } from 'yargs' | ||
|
||
import { configSchema, getYargsOptions } from '../../schema/index.js' | ||
import { fetchStorages } from '../../utils/fetch-storages.js' | ||
|
||
const schema = z.object(_.pick(configSchema.shape, ['endpoint', 'block', 'db'])) | ||
|
||
export const cli = (y: Argv) => { | ||
y.command({ | ||
command: 'fetch-storages [items..]', | ||
aliases: ['fetch-storage'], | ||
describe: 'Fetch and save storages', | ||
builder: (yargs) => yargs.options(getYargsOptions(schema.shape)), | ||
handler: async (argv) => { | ||
const config = schema.parse(argv) | ||
if (!argv.items) throw new Error('fetch-storages items are required') | ||
|
||
try { | ||
await fetchStorages({ | ||
block: config.block, | ||
endpoint: config.endpoint, | ||
dbPath: config.db, | ||
config: argv.items as any, | ||
}) | ||
process.exit(0) | ||
} catch (e) { | ||
process.exit(1) | ||
} | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './cli.js' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import * as Comlink from 'comlink' | ||
import { parentPort } from 'node:worker_threads' | ||
import nodeEndpoint from 'comlink/dist/umd/node-adapter.js' | ||
|
||
import { fetchStorages } from './fetch-storages.js' | ||
|
||
const api = { | ||
startFetch: async ({ ...options }) => { | ||
await fetchStorages({ ...options }) | ||
}, | ||
} | ||
|
||
Comlink.expose(api, nodeEndpoint(parentPort)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import { ApiPromise } from '@polkadot/api' | ||
import { HexString } from '@polkadot/util/types' | ||
import { Like } from 'typeorm' | ||
import { ProviderInterface } from '@polkadot/rpc-provider/types' | ||
import { SqliteDatabase } from '@acala-network/chopsticks-db' | ||
import { WsProvider } from '@polkadot/rpc-provider' | ||
import { afterAll, beforeAll, describe, expect, it } from 'vitest' | ||
import { resolve } from 'node:path' | ||
import { tmpdir } from 'node:os' | ||
import { xxhashAsHex } from '@polkadot/util-crypto' | ||
|
||
import { FetchStorageConfig, fetchStorages, getPrefixesFromConfig } from './fetch-storages.js' | ||
|
||
describe('fetch-storages', () => { | ||
let api: ApiPromise | ||
let provider: ProviderInterface | ||
const endpoint = 'wss://acala-rpc.aca-api.network' | ||
|
||
beforeAll(async () => { | ||
provider = new WsProvider(endpoint, 30_000) | ||
api = new ApiPromise({ provider }) | ||
await api.isReady | ||
}) | ||
|
||
afterAll(async () => { | ||
await api.disconnect() | ||
}) | ||
|
||
it('get prefixes from config works', async () => { | ||
const config: FetchStorageConfig = [ | ||
'0x123456', | ||
'Balances', | ||
'Tokens.Accounts', | ||
{ | ||
System: 'Account', | ||
}, | ||
{ | ||
Tokens: { | ||
Accounts: ['5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'], | ||
}, | ||
}, | ||
{ | ||
Tokens: { | ||
Accounts: [ | ||
'5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', | ||
{ | ||
token: 'DOT', | ||
}, | ||
], | ||
}, | ||
}, | ||
{ | ||
'Tokens.Accounts': ['5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY'], | ||
}, | ||
{ | ||
'Tokens.Accounts': [ | ||
'5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY', | ||
{ | ||
token: 'DOT', | ||
}, | ||
], | ||
}, | ||
] | ||
|
||
const prefixes = await getPrefixesFromConfig(config, api) | ||
|
||
expect(prefixes).toEqual([ | ||
'0x123456', | ||
'0xc2261276cc9d1f8598ea4b6a74b15c2f', | ||
'0x99971b5749ac43e0235e41b0d37869188ee7418a6531173d60d1f6a82d8f4d51', | ||
'0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9', | ||
'0x99971b5749ac43e0235e41b0d37869188ee7418a6531173d60d1f6a82d8f4d51de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d', | ||
'0x99971b5749ac43e0235e41b0d37869188ee7418a6531173d60d1f6a82d8f4d51de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dc483de2de1246ea70002', | ||
'0x99971b5749ac43e0235e41b0d37869188ee7418a6531173d60d1f6a82d8f4d51de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d', | ||
'0x99971b5749ac43e0235e41b0d37869188ee7418a6531173d60d1f6a82d8f4d51de1e86a9a8c739864cf3cc5ec2bea59fd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27dc483de2de1246ea70002', | ||
]) | ||
}) | ||
|
||
it('get prefixes from config throws', async () => { | ||
expect(() => getPrefixesFromConfig(['Balancess'], api)).rejects.toThrow(/Cannot find pallet Balancess/) | ||
|
||
expect(() => getPrefixesFromConfig(['System.Acount'], api)).rejects.toThrow( | ||
/Cannot find storage Acount in pallet System/, | ||
) | ||
|
||
expect(() => | ||
getPrefixesFromConfig( | ||
[ | ||
{ | ||
System: ['Account', 'BlockHash'], | ||
}, | ||
], | ||
api, | ||
), | ||
).rejects.toThrow(/Unsupported fetch-storage config: System.Account,BlockHash/) | ||
}) | ||
|
||
it('fetch prefixes works', async () => { | ||
const blockHash = '0x3a9a2d71537ceedff1a3895d68456f4a870bb89ab649fd47c6cf9c4f9731d580' // 4,500,000 | ||
const dbPath = resolve(tmpdir(), 'fetch.db.sqlite') | ||
|
||
await fetchStorages({ | ||
block: blockHash, | ||
endpoint, | ||
dbPath, | ||
config: [ | ||
'System.Number', | ||
'Tips', | ||
{ | ||
Rewards: { | ||
PoolInfos: [{ Loans: { Token: 'ACA' } }], | ||
}, | ||
}, | ||
], | ||
}) | ||
|
||
const db = new SqliteDatabase(dbPath) | ||
|
||
const systemNumberStorage = await db.queryStorage( | ||
blockHash, | ||
(xxhashAsHex('System', 128) + xxhashAsHex('Number', 128).slice(2)) as HexString, | ||
) | ||
expect(systemNumberStorage?.value).toEqual('0x20aa4400') | ||
|
||
const datasource = await db.datasource | ||
const keyValueTable = datasource.getRepository('KeyValuePair') | ||
|
||
expect(await keyValueTable.count()).toEqual(5) | ||
|
||
expect(await keyValueTable.countBy({ key: Like(`${xxhashAsHex('Tips', 128)}%`) })).toEqual(3) | ||
|
||
const rewards = await keyValueTable.findBy({ key: Like(`${xxhashAsHex('Rewards', 128)}%`) }) | ||
expect(rewards.length).toEqual(1) | ||
expect(rewards[0].value).toEqual( | ||
'0xf45ce8eb6fcaa12109000000000000000800002333cc48e197963c000000000000000014e1339c9e79e7380000000000000000010000000195319d9b71330d010000000000000000bb59ad064bb0bd000000000000000000', | ||
) | ||
|
||
db.close() | ||
}) | ||
}) |
Oops, something went wrong.