-
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.
* add rpc types and docs * refactor and add types
- Loading branch information
Showing
10 changed files
with
503 additions
and
309 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 |
---|---|---|
@@ -1,71 +1,98 @@ | ||
import { APPLY_EXTRINSIC_ERROR, Block } from '@acala-network/chopsticks-core' | ||
import { Handlers, ResponseError } from '../shared' | ||
import { HexString } from '@polkadot/util/types' | ||
import { TransactionValidityError } from '@polkadot/types/interfaces' | ||
|
||
import { Handler, ResponseError, SubscriptionManager } from '../shared' | ||
import { defaultLogger } from '../../logger' | ||
|
||
const logger = defaultLogger.child({ name: 'rpc-author' }) | ||
|
||
const handlers: Handlers = { | ||
author_submitExtrinsic: async (context, [extrinsic]) => { | ||
return context.chain.submitExtrinsic(extrinsic).catch((error: TransactionValidityError) => { | ||
const code = error.isInvalid ? 1010 : 1011 | ||
throw new ResponseError(code, error.toString()) | ||
}) | ||
}, | ||
author_submitAndWatchExtrinsic: async (context, [extrinsic], { subscribe, unsubscribe }) => { | ||
let update = (_block: Block) => {} | ||
/** | ||
* @param context | ||
* @param params - [`extrinsic`] | ||
* | ||
* @return Hash | ||
*/ | ||
export const author_submitExtrinsic: Handler<[HexString], HexString> = async (context, [extrinsic]) => { | ||
return context.chain.submitExtrinsic(extrinsic).catch((error: TransactionValidityError) => { | ||
const code = error.isInvalid ? 1010 : 1011 | ||
throw new ResponseError(code, error.toString()) | ||
}) | ||
} | ||
|
||
/** | ||
* @param context | ||
* @param params - [`extrinsic`] | ||
* @param subscriptionManager | ||
* | ||
* @return subscription id | ||
*/ | ||
export const author_submitAndWatchExtrinsic: Handler<[HexString], string> = async ( | ||
context, | ||
[extrinsic], | ||
{ subscribe, unsubscribe }: SubscriptionManager, | ||
) => { | ||
let update = (_block: Block) => {} | ||
|
||
const id = context.chain.headState.subscribeHead((block) => update(block)) | ||
const callback = subscribe('author_extrinsicUpdate', id, () => context.chain.headState.unsubscribeHead(id)) | ||
const id = context.chain.headState.subscribeHead((block) => update(block)) | ||
const callback = subscribe('author_extrinsicUpdate', id, () => context.chain.headState.unsubscribeHead(id)) | ||
|
||
const onExtrinsicFail = ([failedExtrinsic, error]: [string, TransactionValidityError]) => { | ||
if (failedExtrinsic === extrinsic) { | ||
callback(error.toJSON()) | ||
done(id) | ||
} | ||
const onExtrinsicFail = ([failedExtrinsic, error]: [string, TransactionValidityError]) => { | ||
if (failedExtrinsic === extrinsic) { | ||
callback(error.toJSON()) | ||
done(id) | ||
} | ||
} | ||
|
||
context.chain.txPool.event.on(APPLY_EXTRINSIC_ERROR, onExtrinsicFail) | ||
context.chain.txPool.event.on(APPLY_EXTRINSIC_ERROR, onExtrinsicFail) | ||
|
||
const done = (id: string) => { | ||
context.chain.txPool.event.removeListener(APPLY_EXTRINSIC_ERROR, onExtrinsicFail) | ||
unsubscribe(id) | ||
} | ||
const done = (id: string) => { | ||
context.chain.txPool.event.removeListener(APPLY_EXTRINSIC_ERROR, onExtrinsicFail) | ||
unsubscribe(id) | ||
} | ||
|
||
update = async (block) => { | ||
const extrisnics = await block.extrinsics | ||
if (!extrisnics.includes(extrinsic)) return | ||
update = async (block) => { | ||
const extrisnics = await block.extrinsics | ||
if (!extrisnics.includes(extrinsic)) return | ||
|
||
logger.debug({ block: block.hash }, 'author_extrinsicUpdate') | ||
logger.debug({ block: block.hash }, 'author_extrinsicUpdate') | ||
|
||
callback({ | ||
InBlock: block.hash, | ||
}) | ||
callback({ | ||
Finalized: block.hash, | ||
}) | ||
done(id) | ||
} | ||
callback({ | ||
InBlock: block.hash, | ||
}) | ||
callback({ | ||
Finalized: block.hash, | ||
}) | ||
done(id) | ||
} | ||
|
||
try { | ||
await context.chain.submitExtrinsic(extrinsic) | ||
callback({ | ||
Ready: null, | ||
}) | ||
} catch (error) { | ||
logger.error({ error }, 'ExtrinsicFailed') | ||
const code = (error as TransactionValidityError).isInvalid ? 1010 : 1011 | ||
done(id) | ||
throw new ResponseError(code, (error as TransactionValidityError).toString()) | ||
} | ||
return id | ||
}, | ||
author_unwatchExtrinsic: async (_context, [subid], { unsubscribe }) => { | ||
unsubscribe(subid) | ||
}, | ||
author_pendingExtrinsics: async (context) => { | ||
return context.chain.txPool.pendingExtrinsics | ||
}, | ||
try { | ||
await context.chain.submitExtrinsic(extrinsic) | ||
callback({ | ||
Ready: null, | ||
}) | ||
} catch (error) { | ||
logger.error({ error }, 'ExtrinsicFailed') | ||
const code = (error as TransactionValidityError).isInvalid ? 1010 : 1011 | ||
done(id) | ||
throw new ResponseError(code, (error as TransactionValidityError).toString()) | ||
} | ||
return id | ||
} | ||
|
||
/** | ||
* @param _context | ||
* @param params - [`subid`] | ||
*/ | ||
export const author_unwatchExtrinsic: Handler<[string], void> = async (_context, [subid], { unsubscribe }) => { | ||
unsubscribe(subid) | ||
} | ||
|
||
export default handlers | ||
/** | ||
* Get pending extrinsics | ||
* | ||
* @return Array of pending extrinsics | ||
*/ | ||
export const author_pendingExtrinsics: Handler<void, HexString[]> = async (context) => { | ||
return context.chain.txPool.pendingExtrinsics | ||
} |
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 |
---|---|---|
@@ -1,83 +1,108 @@ | ||
import { Handlers, ResponseError } from '../shared' | ||
import { Header } from '@polkadot/types/interfaces' | ||
import { HexString } from '@polkadot/util/types' | ||
|
||
import { Handler, ResponseError } from '../shared' | ||
|
||
const processHeader = (header: Header) => { | ||
const res = header.toJSON() as any | ||
res.number = '0x' + res.number.toString(16) // number is hex format | ||
return res | ||
} | ||
|
||
const handlers: Handlers = { | ||
chain_getBlockHash: async (context, [blockNumber]) => { | ||
const block = await context.chain.getBlockAt(blockNumber) | ||
if (!block) { | ||
throw new ResponseError(1, `Block #${blockNumber} not found`) | ||
} | ||
return block.hash | ||
}, | ||
chain_getHeader: async (context, [hash]) => { | ||
const block = await context.chain.getBlock(hash) | ||
if (!block) { | ||
throw new ResponseError(1, `Block ${hash} not found`) | ||
} | ||
return processHeader(await block.header) | ||
}, | ||
chain_getBlock: async (context, [hash]) => { | ||
const block = await context.chain.getBlock(hash) | ||
if (!block) { | ||
throw new ResponseError(1, `Block ${hash} not found`) | ||
} | ||
return { | ||
block: { | ||
header: await block.header, | ||
extrinsics: await block.extrinsics, | ||
}, | ||
justifications: null, | ||
} | ||
}, | ||
chain_getFinalizedHead: async (context) => { | ||
return context.chain.head.hash | ||
}, | ||
chain_subscribeNewHead: async (context, _params, { subscribe }) => { | ||
let update = () => {} | ||
|
||
const id = context.chain.headState.subscribeHead(() => update()) | ||
const callback = subscribe('chain_newHead', id, () => context.chain.headState.unsubscribeHead(id)) | ||
|
||
update = async () => { | ||
callback(processHeader(await context.chain.head.header)) | ||
} | ||
|
||
update() | ||
|
||
return id | ||
}, | ||
chain_subscribeFinalizedHeads: async (context, _params, { subscribe }) => { | ||
let update = () => {} | ||
|
||
const id = context.chain.headState.subscribeHead(() => update()) | ||
const callback = subscribe('chain_finalizedHead', id, () => context.chain.headState.unsubscribeHead(id)) | ||
|
||
update = async () => { | ||
callback(processHeader(await context.chain.head.header)) | ||
} | ||
|
||
update() | ||
|
||
return id | ||
}, | ||
chain_unsubscribeNewHead: async (_context, [subid], { unsubscribe }) => { | ||
unsubscribe(subid) | ||
}, | ||
/** | ||
* @param context | ||
* @param params - [`blockNumber`] | ||
* | ||
* @return Block hash | ||
*/ | ||
export const chain_getBlockHash: Handler<[number], HexString> = async (context, [blockNumber]) => { | ||
const block = await context.chain.getBlockAt(blockNumber) | ||
if (!block) { | ||
throw new ResponseError(1, `Block #${blockNumber} not found`) | ||
} | ||
return block.hash | ||
} | ||
|
||
/** | ||
* @param context | ||
* @param params - [`blockhash`] | ||
* | ||
* @return Header - see `@polkadot/types/interfaces` | ||
*/ | ||
export const chain_getHeader: Handler<[HexString], Header> = async (context, [hash]) => { | ||
const block = await context.chain.getBlock(hash) | ||
if (!block) { | ||
throw new ResponseError(1, `Block ${hash} not found`) | ||
} | ||
return processHeader(await block.header) | ||
} | ||
|
||
/** | ||
* @param context | ||
* @param params - [`blockhash`] | ||
* | ||
* @return Block header and extrinsics | ||
*/ | ||
export const chain_getBlock: Handler< | ||
[HexString], | ||
{ block: { header: Header; extrinsics: HexString[] }; justifications: null } | ||
> = async (context, [hash]) => { | ||
const block = await context.chain.getBlock(hash) | ||
if (!block) { | ||
throw new ResponseError(1, `Block ${hash} not found`) | ||
} | ||
return { | ||
block: { | ||
header: await block.header, | ||
extrinsics: await block.extrinsics, | ||
}, | ||
justifications: null, | ||
} | ||
} | ||
|
||
/** | ||
* @param context | ||
* | ||
* @return head hash | ||
*/ | ||
export const chain_getFinalizedHead: Handler<void, HexString> = async (context) => { | ||
return context.chain.head.hash | ||
} | ||
|
||
export const chain_subscribeNewHead: Handler<void, string> = async (context, _params, { subscribe }) => { | ||
let update = () => {} | ||
|
||
const id = context.chain.headState.subscribeHead(() => update()) | ||
const callback = subscribe('chain_newHead', id, () => context.chain.headState.unsubscribeHead(id)) | ||
|
||
update = async () => { | ||
callback(processHeader(await context.chain.head.header)) | ||
} | ||
|
||
update() | ||
|
||
return id | ||
} | ||
|
||
const alias = { | ||
chain_subscribeNewHeads: handlers.chain_subscribeNewHead, | ||
chain_unsubscribeNewHeads: handlers.chain_unsubscribeNewHead, | ||
chain_unsubscribeFinalizedHeads: handlers.chain_unsubscribeNewHead, | ||
export const chain_subscribeFinalizedHeads: Handler<void, string> = async (context, _params, { subscribe }) => { | ||
let update = () => {} | ||
|
||
const id = context.chain.headState.subscribeHead(() => update()) | ||
const callback = subscribe('chain_finalizedHead', id, () => context.chain.headState.unsubscribeHead(id)) | ||
|
||
update = async () => { | ||
callback(processHeader(await context.chain.head.header)) | ||
} | ||
|
||
update() | ||
|
||
return id | ||
} | ||
|
||
export default { | ||
...handlers, | ||
...alias, | ||
export const chain_unsubscribeNewHead: Handler<[string], void> = async (_context, [subid], { unsubscribe }) => { | ||
unsubscribe(subid) | ||
} | ||
|
||
export const chain_subscribeNewHeads = chain_subscribeNewHead | ||
export const chain_unsubscribeNewHeads = chain_unsubscribeNewHead | ||
export const chain_unsubscribeFinalizedHeads = chain_unsubscribeNewHead |
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 |
---|---|---|
@@ -1,17 +1,21 @@ | ||
import author from './author' | ||
import chain from './chain' | ||
import payment from './payment' | ||
import state from './state' | ||
import system from './system' | ||
import * as AuthorRPC from './author' | ||
import * as ChainRPC from './chain' | ||
import * as PaymentRPC from './payment' | ||
import * as StateRPC from './state' | ||
import * as SystemRPC from './system' | ||
|
||
import { Handlers } from '../shared' | ||
export { AuthorRPC } | ||
export { ChainRPC } | ||
export { PaymentRPC } | ||
export { StateRPC } | ||
export { SystemRPC } | ||
|
||
const handlers: Handlers = { | ||
...author, | ||
...chain, | ||
...state, | ||
...system, | ||
...payment, | ||
const handlers = { | ||
...AuthorRPC, | ||
...ChainRPC, | ||
...PaymentRPC, | ||
...StateRPC, | ||
...SystemRPC, | ||
} | ||
|
||
export default handlers |
Oops, something went wrong.