Additional types for latest substrate master (#1016)

* Additional types for latest substrate master

* Method tests updated for new structure

* Adjust extrinsic test indexes

* Adjust type-extrinsics tests

* Adapt for new session/era calc

* Small comment update

* Update with patch for system

* Adjust tests with system calls in metadata
This commit is contained in:
Jaco Greeff
2019-06-15 19:06:02 +02:00
committed by GitHub
parent 364b442eb7
commit ea991e4ccc
19 changed files with 3723 additions and 2561 deletions
+1
View File
@@ -1,6 +1,7 @@
# 0.82.0-beta.x
- **Breaking change** The `ContractsAbi` type has been moved from `@polkadot/types` to `import { Abi } from '@polkadot/api-contract`. This paves the way for an enhanced contracts interface, instead of dealing with low-level API calls.
- Update with latest substrate 2.x types
# 0.81.1
+46 -14
View File
@@ -5,7 +5,7 @@
import { DerivedSessionInfo } from '../types';
import BN from 'bn.js';
import { Observable, combineLatest } from 'rxjs';
import { Observable, combineLatest, of } from 'rxjs';
import { map } from 'rxjs/operators';
import { ApiInterface$Rx } from '@polkadot/api/types';
import { BlockNumber, Option, StructAny } from '@polkadot/types';
@@ -13,12 +13,13 @@ import { BlockNumber, Option, StructAny } from '@polkadot/types';
import { drr } from '../util/drr';
import { bestNumber } from '../chain';
type Result = [BN, [BlockNumber, Option<BlockNumber>, BlockNumber, BlockNumber, BlockNumber]];
type Result0_94 = [BN, [BN, Option<BlockNumber>, BN, BN, BN]];
type Result = [BN, [BN, BN]];
const ZERO = new BN(0);
// internal helper to just split the logic - take all inputs, do the calculations and combine
function createDerived ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: Result): DerivedSessionInfo {
function createDerived0_94 ([bestNumber, [currentIndex, _lastLengthChange, sessionLength, lastEraLengthChange, sessionsPerEra]]: Result0_94): DerivedSessionInfo {
const eraLength = sessionLength.mul(sessionsPerEra);
const lastLengthChange = _lastLengthChange
? _lastLengthChange.unwrapOr(ZERO)
@@ -27,13 +28,15 @@ function createDerived ([bestNumber, [currentIndex, _lastLengthChange, sessionLe
.sub(lastLengthChange)
.add(sessionLength)
.mod(sessionLength);
const eraProgress = (currentIndex)
const currentEra = (currentIndex)
.sub(lastEraLengthChange)
.mod(sessionsPerEra)
.mod(sessionsPerEra);
const eraProgress = currentEra
.mul(sessionLength)
.add(sessionProgress);
return new StructAny({
currentEra,
currentIndex,
eraLength,
eraProgress,
@@ -45,24 +48,53 @@ function createDerived ([bestNumber, [currentIndex, _lastLengthChange, sessionLe
}) as DerivedSessionInfo;
}
function createDerived ([sessionsPerEra, [currentIndex, currentEra]]: Result): DerivedSessionInfo {
const eraProgress = (currentIndex).mod(sessionsPerEra);
return new StructAny({
currentEra,
currentIndex,
eraLength: ZERO,
eraProgress,
lastEraLengthChange: ZERO,
lastLengthChange: ZERO,
sessionLength: ZERO,
sessionsPerEra,
sessionProgress: ZERO
}) as DerivedSessionInfo;
}
/**
* @description Retrieves all the session and era info and calculates specific valus on it sunh as the length of the session and eras
*/
export function info (api: ApiInterface$Rx) {
return (): Observable<DerivedSessionInfo> =>
// This is a much more optimal way to calculate since we only make a single call to the RPC backend
// instead of making a subscription for each of the params (this means all others in session use)
(combineLatest([
bestNumber(api)(),
return (): Observable<DerivedSessionInfo> => {
// with 94, the era and session has been explicitly exposed, pre-94
// we had more info and needed to calculate (handle old/Alex first)
return api.query.session.lastLengthChange
? (combineLatest([
bestNumber(api)(),
api.queryMulti([
api.query.session.currentIndex,
api.query.session.lastLengthChange,
api.query.session.sessionLength,
api.query.staking.lastEraLengthChange,
api.query.staking.sessionsPerEra
])
]) as any as Observable<Result0_94>).pipe(
map(createDerived0_94),
drr()
)
: (combineLatest([
// sessionsPerEra, hardcoded, due to https://github.com/paritytech/substrate/pull/2802/files#diff-5e5e1c3aec9ddfde0a9054d062ab3db9R156
of(new BN(6)),
api.queryMulti([
api.query.session.currentIndex,
api.query.session.lastLengthChange,
api.query.session.sessionLength,
api.query.staking.lastEraLengthChange,
api.query.staking.sessionsPerEra
api.query.staking.currentEra
])
]) as any as Observable<Result>).pipe(
map(createDerived),
drr()
);
};
}
+6 -5
View File
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import BN from 'bn.js';
import { AccountId, Balance, BlockNumber, Exposure, Index, RewardDestination, StakingLedger, StructAny, ValidatorPrefs, Vote } from '@polkadot/types';
import { AccountId, Balance, Exposure, Index, RewardDestination, StakingLedger, StructAny, ValidatorPrefs, Vote } from '@polkadot/types';
export interface DerivedBalances extends StructAny {
accountId: AccountId;
@@ -48,13 +48,14 @@ export interface DerivedReferendumVote extends StructAny {
}
export interface DerivedSessionInfo extends StructAny {
currentIndex: BlockNumber;
currentEra: BN;
currentIndex: BN;
eraLength: BN;
eraProgress: BN;
lastEraLengthChange: BlockNumber;
lastEraLengthChange: BN;
lastLengthChange: BN;
sessionLength: BlockNumber;
sessionsPerEra: BlockNumber;
sessionLength: BN;
sessionsPerEra: BN;
sessionProgress: BN;
}
@@ -30,7 +30,7 @@ describe('fromMetadata', () => {
// version, no signature
1,
// index
0, 0,
1, 0,
// values, Compact<Moment>
116
])
+14 -5
View File
@@ -22,7 +22,7 @@ describe('extrinsics', () => {
}
).toU8a(true)
).toEqual(new Uint8Array([
129, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 19, 0, 0, 0, 213, 157
129, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, 19, 0, 1, 0, 213, 157
]));
});
@@ -33,9 +33,18 @@ describe('extrinsics', () => {
).sign(keyring.alice, {
blockHash: '0xec7afaf1cca720ce88c1d1b689d81f0583cc15a97d621cf046dd9abf605ef22f',
nonce: 0
}).toU8a()
).toEqual(new Uint8Array([
37, 2, 129, 255, 209, 114, 167, 76, 218, 76, 134, 89, 18, 195, 43, 160, 168, 10, 87, 174, 105, 171, 174, 65, 14, 92, 203, 89, 222, 232, 78, 47, 68, 50, 219, 79, 245, 228, 136, 9, 232, 31, 206, 95, 236, 20, 206, 189, 109, 251, 83, 198, 37, 79, 144, 90, 72, 33, 101, 250, 52, 0, 66, 80, 222, 78, 34, 124, 6, 101, 244, 44, 168, 225, 239, 153, 185, 58, 113, 221, 221, 136, 43, 237, 9, 6, 201, 17, 56, 110, 105, 78, 173, 109, 176, 100, 24, 78, 164, 15, 0, 0, 3, 0, 255, 215, 86, 142, 95, 10, 126, 218, 103, 168, 38, 145, 255, 55, 154, 196, 187, 164, 249, 201, 184, 89, 254, 119, 155, 93, 70, 54, 59, 97, 173, 45, 185, 229, 108
]));
}).toHex()
).toEqual(
'0x' +
'2502' + // length
'81' + // signed flag
'ffd172a74cda4c865912c32ba0a80a57ae69abae410e5ccb59dee84e2f4432db4f' + // who
'f5e48809e81fce5fec14cebd6dfb53c6254f905a482165fa34004250de4e227c' + // sig1
'0665f42ca8e1ef99b93a71dddd882bed0906c911386e694ead6db064184ea40f' + // sig2
'0000' + // nonce
'0300' + // balances.transfer
'ffd7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9' + // to
'e56c' // value
);
});
});
+7
View File
@@ -81,6 +81,7 @@ These custom types implement specific types that are found as part of the Substr
| [[AttestedCandidate]] | An attested candidate |
| [[AuthorityId]] | Wrapper for a AuthorityId. Same as an normal AccountId |
| [[AuthoritiesChange]] | Log for Authories changed |
| [[AuthorityWeight]] | The weight of an authority |
| [[Balance]] | The Substrate Balance representation as a [[U128]] |
| [[BalanceLock]] | The Substrate BalanceLock for staking |
| [[BalanceOf]] | The Substrate BalanceOf representation as a [[Balance]] |
@@ -94,6 +95,7 @@ These custom types implement specific types that are found as part of the Substr
| [[Consensus]] | Log item indicating consensus |
| [[ContractInfo]] | The contract information for a given contract |
| [[ContractStorageKey]] | A representation of a storage key for contracts |
| [[EraIndex]] | A representation for the era count |
| [[Exposure]] | A snapshot of the stake backing a single validator in the system |
| [[Extrinsic]] | Representation of an Extrinsic in the system |
| [[ExtrinsicEra]] | The era for an extrinsic, indicating either a mortal or immortal extrinsic |
@@ -104,6 +106,7 @@ These custom types implement specific types that are found as part of the Substr
| [[InherentOfflineReport]] | Describes the offline-reporting extrinsic |
| [[Justification]] | A generic justification as a stream of [[Bytes]], this is specific per consensus implementation |
| [[Key]] | The Substrate Key representation as a [[Bytes]] (`vec<u8>`) |
| [[Keys]] | The session keys |
| [[KeyValue]] | KeyValue structure. Since most of the keys and resultant values in Subtrate are hashed and/or encoded, keys and values are reprsented as [[Bytes]] |
| [[KeyValueOption]] | A key/value change. Similar to the [[KeyValue]] structure, but the value can be optional |
| [[LockIdentifier]] | The Substrate LockIdentifier for staking |
@@ -116,6 +119,7 @@ These custom types implement specific types that are found as part of the Substr
| [[Nonce]] | The Nonce or number of transactions sent by a specific account |
| [[NonceCompact]] | The Compact<Nonce> or number of transactions sent by a specific account |
| [[ParaId]] | Identifier for a deployed parachain implemented as a [[U32]] |
| [[OpaqueKey]] | A key represented as a [[Bytes]] |
| [[Perbill]] | Parts per billion (see also [[Permill]]) |
| [[Permill]] | Parts per million (See also [[Perbill]]) |
| [[PrefabWasmModule]] | Struct to encode the vesting schedule of an individual account |
@@ -128,7 +132,9 @@ These custom types implement specific types that are found as part of the Substr
| [[Schedule]] | Definition of the cost schedule and other parameterizations for wasm vm |
| [[Seal]] | Log item indicating a sealing event |
| [[SeedOf]] | The Substrate SeedOf representation as a [[Hash]] |
| [[SessionIndex]] | Simple index type with which we can count sessions as [[U32]] |
| [[SessionKey]] | Wrapper for a SessionKey. Same as an normal [[AuthorityId]], i.e. a wrapper around publicKey |
| [[SessionKeys]] | Wrapper for the session and authority ids |
| [[SetIndex]] | Set index, implemented as a [[U32]] |
| [[Signature]] | The default signature that is used accross the system |
| [[SignaturePayload]] | A signing payload for an [[Extrinsic]]. For the final encoding, it is variable length based on the contents included |
@@ -156,6 +162,7 @@ These types are not used in the runtime, but are rather used in RPC results:
| [[Block]] | A block encoded with header and extrinsics |
| [[ChainProperties]] | Wraps the properties retrieved from the chain via the `system.properties` RPC call |
| [[Digest]] | A [[Header]] Digest |
| [[DigestOf]] | A [[Header]] Digest |
| [[DigestItem]] | A [[EnumType]] the specifies the specific item in the logs of a [[Digest]] |
| [[ExtrinsicStatus]] | An EnumType that indicates the status of the Extrinsic as been submitted |
| [[Header]] | A [[Block]] header |
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
+7 -5
View File
@@ -11,25 +11,27 @@ describe('Method', () => {
Method.injectMethods(extrinsics);
});
// FIXME susbtrate master does not currently expose the new system module calls in meta,
// once it does the index here will change, so a different method would be refrerred to
it('handles decoding correctly (bare)', () => {
expect(
new Method({
args: [],
callIndex: [1, 2]
callIndex: [3, 1] // balances.setBalance
}).toU8a()
).toEqual(new Uint8Array([1, 2, 0])); // array of 0
).toEqual(new Uint8Array([3, 1, 0, 0, 0]));
});
it('handles creation from a hex value properly', () => {
expect(
new Method('0x0102').toU8a()
).toEqual(new Uint8Array([1, 2, 0])); // array of 0 for consensus.noteOffline
new Method('0x0301').toU8a()
).toEqual(new Uint8Array([3, 1, 0, 0, 0])); // balances.setBalance
});
describe('hasOrigin', () => {
const test = {
args: [],
callIndex: [1, 2]
callIndex: [2, 2] // timestamp
};
it('is false with no arguments', () => {
+7
View File
@@ -417,3 +417,10 @@ export default class Digest extends Struct {
return this.logs.filter(({ type }) => !exclude.includes(type)) as Vector<DigestItem>;
}
}
/**
* @name DigestOf
* @description
* A [[Header]] Digest
*/
export class DigestOf extends Digest {}
+1 -1
View File
@@ -10,7 +10,7 @@
*/
export { default as Block } from './Block';
export { default as ChainProperties } from './ChainProperties';
export { default as Digest, DigestItem } from './Digest';
export { default as Digest, DigestItem, DigestOf } from './Digest';
export { default as ExtrinsicStatus } from './ExtrinsicStatus';
export { default as Header } from './Header';
export { default as Health } from './Health';
@@ -0,0 +1,13 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import U64 from '../primitive/U64';
/**
* @name AuthorityWeight
* @description
* The weight of an authority
*/
export default class AuthorityWeight extends U64 {
}
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import U32 from '../primitive/U32';
/**
* @name EraIndex
* @description
* Index type of eras
*/
export default class EraIndex extends U32 {
}
+8 -2
View File
@@ -21,7 +21,9 @@ describe('Extrinsic', () => {
});
it('decodes an actual transaction (new format)', () => {
const extrinsic = new Extrinsic('0x250281ffbfc823aa75c30058eeec21abe2c2d6b7247418a4af89d67a2084c2ac864da080c0aa4df3b4926c3cd78bbdced31d8bdccb8604b779b71b90e58b2848df4a9ad6b0aa1aae6be7a05c9413a172b0325e4d214e5ff2b25098028b30f1a50be9c90e0c000300ff4a83f1c09be797bc3d9adce29818368b276a84e6b545ced492c25c948978d7f8e5c0');
const extrinsic = new Extrinsic('0x250281ffbfc823aa75c30058eeec21abe2c2d6b7247418a4af89d67a2084c2ac864da080c0aa4df3b4926c3cd78bbdced31d8bdccb8604b779b71b90e58b2848df4a9ad6b0aa1aae6be7a05c9413a172b0325e4d214e5ff2b25098028b30f1a50be9c90e0c00' +
'0300' + // balances.transfer
'ff4a83f1c09be797bc3d9adce29818368b276a84e6b545ced492c25c948978d7f8e5c0');
expect(extrinsic.isSigned).toEqual(true);
expect(extrinsic.signature.signer.toU8a()).toEqual(new Uint8Array([255, 191, 200, 35, 170, 117, 195, 0, 88, 238, 236, 33, 171, 226, 194, 214, 183, 36, 116, 24, 164, 175, 137, 214, 122, 32, 132, 194, 172, 134, 77, 160, 128]));
@@ -29,12 +31,15 @@ describe('Extrinsic', () => {
expect(extrinsic.signature.nonce.toNumber()).toEqual(3);
expect(extrinsic.signature.era.toU8a()).toEqual(new Uint8Array([0]));
expect(extrinsic.callIndex).toEqual(new Uint8Array([3, 0]));
expect(`${extrinsic.method.sectionName}.${extrinsic.method.methodName}`).toEqual('balances.transfer');
expect(extrinsic.args[0].toString()).toEqual('5DkQbYAExs3M2sZgT1Ec3mKfZnAQCL4Dt9beTCknkCUn5jzo');
});
it('decodes an actual transaction (old format)', () => {
const extrinsic = new Extrinsic(
'0x81ffbfc823aa75c30058eeec21abe2c2d6b7247418a4af89d67a2084c2ac864da080c0aa4df3b4926c3cd78bbdced31d8bdccb8604b779b71b90e58b2848df4a9ad6b0aa1aae6be7a05c9413a172b0325e4d214e5ff2b25098028b30f1a50be9c90e0c000300ff4a83f1c09be797bc3d9adce29818368b276a84e6b545ced492c25c948978d7f8e5c0'
'0x81ffbfc823aa75c30058eeec21abe2c2d6b7247418a4af89d67a2084c2ac864da080c0aa4df3b4926c3cd78bbdced31d8bdccb8604b779b71b90e58b2848df4a9ad6b0aa1aae6be7a05c9413a172b0325e4d214e5ff2b25098028b30f1a50be9c90e0c00' +
'0300' + // balances.transfer
'ff4a83f1c09be797bc3d9adce29818368b276a84e6b545ced492c25c948978d7f8e5c0'
);
expect(extrinsic.isSigned).toEqual(true);
@@ -43,6 +48,7 @@ describe('Extrinsic', () => {
expect(extrinsic.signature.nonce.toNumber()).toEqual(3);
expect(extrinsic.signature.era.toU8a()).toEqual(new Uint8Array([0]));
expect(extrinsic.callIndex).toEqual(new Uint8Array([3, 0]));
expect(`${extrinsic.method.sectionName}.${extrinsic.method.methodName}`).toEqual('balances.transfer');
expect(extrinsic.args[0].toString()).toEqual('5DkQbYAExs3M2sZgT1Ec3mKfZnAQCL4Dt9beTCknkCUn5jzo');
});
});
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import SessionKeys from './SessionKeys';
/**
* @name Keys
* @description
* The session keys
*/
export default class Keys extends SessionKeys {
}
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Bytes from '../primitive/Bytes';
/**
* @name OpaqueKey
* @description
* The Substrate OpaqueKey representation as a [[Bytes]] (`vec<u8>`).
*/
export default class OpaqueKey extends Bytes {
}
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import U32 from '../primitive/U32';
/**
* @name SessionIndex
* @description
* Simple index type with which we can count sessions
*/
export default class SessionIndex extends U32 {
}
+35
View File
@@ -0,0 +1,35 @@
// Copyright 2017-2019 @polkadot/types authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import Struct from '../codec/Struct';
import AuthorityId from './AuthorityId';
import SessionKey from './SessionKey';
/**
* @name SessionKeys
* @description
* Wrapper for the session and authority ids
*/
export default class SessionKeys extends Struct {
constructor (value?: any) {
super({
authorityId: AuthorityId,
sessionKey: SessionKey
}, value);
}
/**
* @description The Grandpa Authority
*/
get authorityId (): AuthorityId {
return this.get('authorityId') as AuthorityId;
}
/**
* @description The Aura session
*/
get sessionKey (): SessionKey {
return this.get('sessionKey') as SessionKey;
}
}
+6
View File
@@ -13,6 +13,7 @@ export { default as ApprovalFlag } from './ApprovalFlag';
export { default as AssetOf } from './AssetOf';
export { default as AttestedCandidate } from './AttestedCandidate';
export { default as AuthorityId } from './AuthorityId';
export { default as AuthorityWeight } from './AuthorityWeight';
export { default as Balance, BalanceOf } from './Balance';
export { default as BalanceLock } from './BalanceLock';
// NOTE Bft items are only used in internal structures
@@ -22,6 +23,7 @@ export { default as CodeHash } from './CodeHash';
export { default as Conviction } from './Conviction';
export { default as ContractInfo } from './ContractInfo';
export { default as ContractStorageKey } from './ContractStorageKey';
export { default as EraIndex } from './EraIndex';
export { default as Exposure } from './Exposure';
export { default as Extrinsic } from './Extrinsic';
export { default as ExtrinsicEra } from './ExtrinsicEra';
@@ -32,6 +34,7 @@ export { default as Gas } from './Gas';
export { default as IndividualExposure } from './IndividualExposure';
export { default as InherentOfflineReport } from './InherentOfflineReport';
export { default as Key } from './Key';
export { default as Keys } from './Keys';
export { default as KeyValue } from './KeyValue';
export { default as LockIdentifier } from './LockIdentifier';
export { default as LockPeriods } from './LockPeriods';
@@ -42,6 +45,7 @@ export { default as Justification } from './Justification';
export { default as MemberCount } from './MemberCount';
export { default as MisbehaviorReport } from './MisbehaviorReport';
export { default as NewAccountOutcome } from './NewAccountOutcome';
export { default as OpaqueKey } from './OpaqueKey';
export { default as ParaId } from './ParaId';
export { default as Permill } from './Permill';
export { default as Perbill } from './Perbill';
@@ -54,7 +58,9 @@ export { default as ReferendumInfo } from './ReferendumInfo';
export { default as RewardDestination } from './RewardDestination';
export { default as Schedule } from './Schedule';
export { default as SeedOf } from './SeedOf';
export { default as SessionIndex } from './SessionIndex';
export { default as SessionKey } from './SessionKey';
export { default as SessionKeys } from './SessionKeys';
export { default as SetIndex } from './SetIndex';
export { default as Signature, Ed25519Signature, Sr25519Signature } from './Signature';
export { default as SignaturePayload, SignaturePayloadRaw } from './SignaturePayload';