Multisig calls with weight (#2957)

* Multisig calls with weight

* approveAsMulti args check
This commit is contained in:
Jaco Greeff 2020-06-17 12:49:56 +02:00 committed by GitHub
parent 8eccba3197
commit 2e427e90e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 34 additions and 21 deletions

View File

@ -9,7 +9,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react';
import styled from 'styled-components';
import { registry } from '@polkadot/react-api';
import { Dropdown, InputAddress, Modal, Toggle, TxButton, Input } from '@polkadot/react-components';
import { useAccounts, useApi } from '@polkadot/react-hooks';
import { useAccounts, useApi, useWeight } from '@polkadot/react-hooks';
import { assert, isHex } from '@polkadot/util';
import { useTranslation } from '../../translate';
@ -38,6 +38,7 @@ function MultisigApprove ({ className = '', onClose, ongoing, threshold, who }:
const { api } = useApi();
const { allAccounts } = useAccounts();
const [callData, setCallData] = useState<Call | null>(null);
const [callWeight] = useWeight(callData);
const [hash, setHash] = useState<string | null>(ongoing[0][0].toHex());
const [{ isMultiCall, multisig }, setMultisig] = useState<MultiInfo>({ isMultiCall: false, multisig: null });
const [isCallOverride, setCallOverride] = useState(true);
@ -104,17 +105,21 @@ function MultisigApprove ({ className = '', onClose, ongoing, threshold, who }:
? type === 'aye'
? isMultiCall && isCallOverride
? callData
? multiMod.asMulti.meta.args.length === 5
? multiMod.asMulti.meta.args.length === 6
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
? multiMod.asMulti(threshold, others, multisig.when, callData, false)
// @ts-ignore (We are doing toHex here since we have a Vec<u8> input)
? multiMod.asMulti(threshold, others, multisig.when, callData.toHex(), false, callWeight)
: multiMod.asMulti(threshold, others, multisig.when, callData)
: null
: multiMod.approveAsMulti(threshold, others, multisig.when, hash)
: multiMod.approveAsMulti.meta.args.length === 5
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
? multiMod.approveAsMulti(threshold, others, multisig.when, hash, callWeight)
: multiMod.approveAsMulti(threshold, others, multisig.when, hash)
: multiMod.cancelAsMulti(threshold, others, multisig.when, hash)
: null
);
}, [api, callData, hash, isCallOverride, isMultiCall, others, multisig, threshold, type]);
}, [api, callData, callWeight, hash, isCallOverride, isMultiCall, others, multisig, threshold, type]);
// when the actual call input changes, create a call and set it
const _setCallData = useCallback(

View File

@ -24,8 +24,7 @@ function Close ({ hasFailed, hash, idNumber, isDisabled, members, proposal }: Pr
const { api } = useApi();
const [isOpen, toggleOpen] = useToggle();
const [accountId, setAccountId] = useState<string | null>(null);
const [proposalLength] = useState(proposal.encodedLength);
const proposalWeight = useWeight(proposal);
const [proposalWeight, proposalLength] = useWeight(proposal);
return (
<>

View File

@ -24,8 +24,7 @@ function Close ({ hasFailed, hash, idNumber, isDisabled, members, proposal }: Pr
const { api } = useApi();
const [isOpen, toggleOpen] = useToggle();
const [accountId, setAccountId] = useState<string | null>(null);
const [proposalLength] = useState(proposal.encodedLength);
const proposalWeight = useWeight(proposal);
const [proposalWeight, proposalLength] = useWeight(proposal);
return (
<>

View File

@ -13,19 +13,24 @@ import useIsMountedRef from './useIsMountedRef';
// a random address that we are using for our queries
const ZERO_ACCOUNT = '5CAUdnwecHGxxyr5vABevAfZ34Fi4AaraDRMwfDQXQ52PXqg';
const EMPTY_STATE: [BN, number] = [BN_ZERO, 0];
// for a given call, calculate the weight
export default function useWeight (call: Call): BN {
export default function useWeight (call?: Call | null): [BN, number] {
const { api } = useApi();
const mountedRef = useIsMountedRef();
const [weight, setWeight] = useState<BN>(BN_ZERO);
const [state, setState] = useState(EMPTY_STATE);
useEffect((): void => {
api.tx(call)
.paymentInfo(ZERO_ACCOUNT)
.then(({ weight }) => mountedRef.current && setWeight(weight))
.catch(console.error);
if (call) {
api.tx(call)
.paymentInfo(ZERO_ACCOUNT)
.then(({ weight }) => mountedRef.current && setState([weight, call.encodedLength]))
.catch(console.error);
} else {
setState(EMPTY_STATE);
}
}, [api, call, mountedRef]);
return weight;
return state;
}

View File

@ -108,6 +108,7 @@ async function wrapTx (api: ApiPromise, currentItem: QueueTx, { isMultiCall, mul
if (multiRoot) {
const multiModule = api.tx.multisig ? 'multisig' : 'utility';
const info = await api.query[multiModule].multisigs<Option<Multisig>>(multiRoot, tx.method.hash);
const { weight } = await tx.paymentInfo(multiRoot);
const { threshold, who } = extractExternal(multiRoot);
const others = who.filter((w) => w !== signAddress);
let timepoint: Timepoint | null = null;
@ -117,12 +118,16 @@ async function wrapTx (api: ApiPromise, currentItem: QueueTx, { isMultiCall, mul
}
tx = isMultiCall
? api.tx[multiModule].asMulti.meta.args.length === 5
? api.tx[multiModule].asMulti.meta.args.length === 6
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore (We are doing toHex here since we have a Vec<u8> input)
? api.tx[multiModule].asMulti(threshold, others, timepoint, tx.method.toHex(), false, weight)
: api.tx[multiModule].asMulti(threshold, others, timepoint, tx.method)
: api.tx[multiModule].approveAsMulti.meta.args.length === 5
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
? api.tx[multiModule].asMulti(threshold, others, timepoint, tx.method, false)
: api.tx[multiModule].asMulti(threshold, others, timepoint, tx.method)
: api.tx[multiModule].approveAsMulti(threshold, others, timepoint, tx.method.hash);
? api.tx[multiModule].approveAsMulti(threshold, others, timepoint, tx.method.hash, weight)
: api.tx[multiModule].approveAsMulti(threshold, others, timepoint, tx.method.hash);
}
return tx;