ParaId reservation (#5257)

* ParaId reservation

* Show reservation fees
This commit is contained in:
Jaco 2021-05-11 22:14:55 +03:00 committed by GitHub
parent c35a24db2d
commit b84adb8bdf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 135 additions and 46 deletions

View File

@ -4,9 +4,10 @@
import React from 'react';
import { Button } from '@polkadot/react-components';
import { useToggle } from '@polkadot/react-hooks';
import { useApi, useToggle } from '@polkadot/react-hooks';
import { useTranslation } from '../translate';
import RegisterId from './RegisterId';
import RegisterThread from './RegisterThread';
interface Props {
@ -15,13 +16,24 @@ interface Props {
function Actions ({ className }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [isRegisterOpen, toggleRegisterOpen] = useToggle();
const [isReserveOpen, toggleReserveOpen] = useToggle();
return (
<Button.Group className={className}>
<Button
icon='plus'
label={t<string>('Register')}
isDisabled={!api.tx.registrar.reserve}
label={t<string>('ParaId')}
onClick={toggleReserveOpen}
/>
{isReserveOpen && (
<RegisterId onClose={toggleReserveOpen} />
)}
<Button
icon='plus'
label={t<string>('ParaThread')}
onClick={toggleRegisterOpen}
/>
{isRegisterOpen && (

View File

@ -0,0 +1,77 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type BN from 'bn.js';
import type { ParaId } from '@polkadot/types/interfaces';
import React, { useState } from 'react';
import { InputAddress, InputBalance, InputNumber, Modal, TxButton } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';
import { useTranslation } from '../translate';
import { LOWEST_PUBLIC_ID } from './constants';
interface Props {
className?: string;
onClose: () => void;
}
const transformId = {
transform: (nextId: ParaId) =>
nextId.isZero()
? LOWEST_PUBLIC_ID
: nextId
};
function RegisterId ({ className, onClose }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [accountId, setAccountId] = useState<string | null>(null);
const nextParaId = useCall<ParaId | BN>(api.query.registrar?.nextFreeParaId, [], transformId);
return (
<Modal
className={className}
header={t<string>('Reserve ParaId')}
size='large'
>
<Modal.Content>
<Modal.Columns hint={t<string>('This account will be used to the Id reservation and for the future parathread.')}>
<InputAddress
label={t<string>('reserve from')}
onChange={setAccountId}
type='account'
value={accountId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The Id of this parachain as known on the network')}>
<InputNumber
defaultValue={nextParaId}
isDsiabled
label={t<string>('parachain id')}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The reservation fee for this Id')}>
<InputBalance
defaultValue={api.consts.registrar.paraDeposit}
isDisabled
label={t<string>('reserved deposit')}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>
<TxButton
accountId={accountId}
icon='plus'
isDisabled={!nextParaId}
onStart={onClose}
params={[]}
tx={api.tx.registrar.reserve}
/>
</Modal.Actions>
</Modal>
);
}
export default React.memo(RegisterId);

View File

@ -1,37 +1,28 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { ParaId } from '@polkadot/types/interfaces';
import type BN from 'bn.js';
import type { BalanceOf } from '@polkadot/types/interfaces';
import BN from 'bn.js';
import React, { useCallback, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { InputAddress, InputFile, InputNumber, Modal, TxButton } from '@polkadot/react-components';
import { useApi, useCall } from '@polkadot/react-hooks';
import { InputAddress, InputBalance, InputFile, InputNumber, Modal, TxButton } from '@polkadot/react-components';
import { useApi } from '@polkadot/react-hooks';
import { compactAddLength } from '@polkadot/util';
import { useTranslation } from '../translate';
import { LOWEST_INVALID_ID } from './constants';
interface Props {
className?: string;
onClose: () => void;
}
const LOWEST_PUBLIC_ID = new BN(2_000);
const transformId = {
transform: (nextId: ParaId) =>
nextId.isZero()
? LOWEST_PUBLIC_ID
: nextId
};
function RegisterThread ({ className, onClose }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const { api } = useApi();
const [accountId, setAccountId] = useState<string | null>(null);
const [paraId, setParaId] = useState<BN | undefined>();
const nextParaId = useCall<ParaId | BN>(api.query.registrar?.nextFreeParaId, [], transformId);
const [wasm, setWasm] = useState<Uint8Array | null>(null);
const [genesisState, setGenesisState] = useState<Uint8Array | null>(null);
@ -45,9 +36,14 @@ function RegisterThread ({ className, onClose }: Props): React.ReactElement<Prop
[]
);
const isIdValid = api.tx.registrar.registerNext
? !!nextParaId
: !!(paraId && paraId.gte(LOWEST_PUBLIC_ID));
const reservedDeposit = useMemo(
() => (api.consts.registrar.paraDeposit as BalanceOf)
.add((api.consts.registrar.dataDepositPerByte as BalanceOf).muln(wasm ? wasm.length : 0))
.iadd((api.consts.registrar.dataDepositPerByte as BalanceOf).muln(genesisState ? genesisState.length : 0)),
[api, wasm, genesisState]
);
const isIdError = !paraId || !paraId.gt(LOWEST_INVALID_ID);
return (
<Modal
@ -65,28 +61,17 @@ function RegisterThread ({ className, onClose }: Props): React.ReactElement<Prop
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The id of this parachain as known on the network')}>
{api.tx.registrar.registerNext
? (
<InputNumber
defaultValue={nextParaId || LOWEST_PUBLIC_ID}
isDisabled
isZeroable={false}
label={t<string>('parachain id')}
/>
)
: (
<InputNumber
autoFocus
isZeroable={false}
label={t<string>('parachain id')}
onChange={setParaId}
/>
)
}
<InputNumber
autoFocus
defaultValue={LOWEST_INVALID_ID}
isError={isIdError}
isZeroable={false}
label={t<string>('parachain id')}
onChange={setParaId}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The WASM validation function for this parachain.')}>
<InputFile
autoFocus={!!api.tx.registrar.registerNext}
help={t<string>('The compiled runtime WASM for the parachain you wish to register.')}
isError={!wasm}
label={t<string>('code')}
@ -101,19 +86,22 @@ function RegisterThread ({ className, onClose }: Props): React.ReactElement<Prop
onChange={_setGenesisState}
/>
</Modal.Columns>
<Modal.Columns hint={t<string>('The reservation fee for this parachain, including base fee and per-byte fees')}>
<InputBalance
defaultValue={reservedDeposit}
isDisabled
label={t<string>('reserved deposit')}
/>
</Modal.Columns>
</Modal.Content>
<Modal.Actions onCancel={onClose}>
<TxButton
accountId={accountId}
icon='plus'
isDisabled={!wasm || !genesisState || !isIdValid}
isDisabled={!wasm || !genesisState || isIdError}
onStart={onClose}
params={
api.tx.registrar.registerNext
? [genesisState, wasm]
: [paraId, genesisState, wasm]
}
tx={api.tx.registrar.registerNext || api.tx.registrar.register}
params={[paraId, genesisState, wasm]}
tx={api.tx.registrar.register}
/>
</Modal.Actions>
</Modal>

View File

@ -0,0 +1,12 @@
// Copyright 2017-2021 @polkadot/app-parachains authors & contributors
// SPDX-License-Identifier: Apache-2.0
import BN from 'bn.js';
import { BN_ONE, BN_THOUSAND } from '@polkadot/util';
export const LOWEST_PUBLIC_ID = new BN(2_000);
export const LOWEST_INVALID_ID = LOWEST_PUBLIC_ID.sub(BN_ONE);
export const LOWEST_USER_ID = BN_THOUSAND;