-
Notifications
You must be signed in to change notification settings - Fork 378
Extrinsic v2 #1150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Extrinsic v2 #1150
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
8736fc9
Extrinsic v2
jacogr 118402b
Save after last move of files
jacogr 924cb1a
Signature V2
jacogr 3422329
Rework signature decoding
jacogr c3f6a60
Simplify V1 and V2 underlying impl.
jacogr 8798656
Detect chain extrinsic version
jacogr 7b8baae
SignaturePayload
jacogr e6ee306
remove Raw payload variant link (Payload is now raw)
jacogr c2cf69c
Remove v2 comments referring to v1 data
jacogr 9b50084
Merge branch 'master' into kg-extrinsic-v2
jacogr 8e95203
Pass isSigned to Extrinsic{V1, V2}
jacogr 419663b
Cleanup era injection
jacogr 8e8c5f9
It flows :)
jacogr 64193d0
Add SignerPayload and signPayload for Signer (#1152)
jacogr ed8227a
Update packages/api/src/types.ts
jacogr 7d8ad6d
Update packages/types/src/primitive/BalanceCompact.ts
jacogr 73e0e40
Backwards compatibility for current in-store signers
jacogr 236b7c7
Merge branch 'kg-extrinsic-v2' of github.com:polkadot-js/api into kg-…
jacogr 680a38b
Apply options suggestions
jacogr 4fb312c
Marge master
jacogr c4f0789
Add missing Compact params (linting)
jacogr File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 hidden or 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 |
|---|---|---|
|
|
@@ -22,8 +22,9 @@ import { Storage } from '@polkadot/api-metadata/storage/types'; | |
| import storageFromMeta from '@polkadot/api-metadata/storage/fromMetadata'; | ||
| import RpcCore from '@polkadot/rpc-core'; | ||
| import { WsProvider } from '@polkadot/rpc-provider'; | ||
| import { Event, getTypeRegistry, Hash, Metadata, Method, RuntimeVersion, Null, U64 } from '@polkadot/types'; | ||
| import { Event, getTypeRegistry, Hash, Metadata, Method, RuntimeVersion, SignedBlock, Null, U64 } from '@polkadot/types'; | ||
| import Linkage, { LinkageResult } from '@polkadot/types/codec/Linkage'; | ||
| import { DEFAULT_VERSION as EXTRINSIC_DEFAULT_VERSION } from '@polkadot/types/primitive/Extrinsic/constants'; | ||
| import { MethodFunction, ModulesWithMethods } from '@polkadot/types/primitive/Method'; | ||
| import * as srmlTypes from '@polkadot/types/srml/definitions'; | ||
| import { StorageEntry } from '@polkadot/types/primitive/StorageKey'; | ||
|
|
@@ -72,6 +73,8 @@ export default abstract class ApiBase<ApiType> { | |
|
|
||
| private _extrinsics?: SubmittableExtrinsics<ApiType>; | ||
|
|
||
| private _extrinsicType: number = EXTRINSIC_DEFAULT_VERSION; | ||
|
|
||
| private _genesisHash?: Hash; | ||
|
|
||
| protected _isConnected: BehaviorSubject<boolean>; | ||
|
|
@@ -150,6 +153,13 @@ export default abstract class ApiBase<ApiType> { | |
| this.init(); | ||
| } | ||
|
|
||
| /** | ||
| * @description Returns th version of extrinsics in-use on this chain | ||
| */ | ||
| public get extrinsicVersion (): number { | ||
| return this._extrinsicType; | ||
| } | ||
|
|
||
| /** | ||
| * @description Contains the genesis Hash of the attached chain. Apart from being useful to determine the actual chain, it can also be used to sign immortal transactions. | ||
| */ | ||
|
|
@@ -498,7 +508,9 @@ export default abstract class ApiBase<ApiType> { | |
| this._rpcCore.chain.getBlockHash(0).toPromise(), | ||
| this._rpcCore.chain.getRuntimeVersion().toPromise() | ||
| ]); | ||
|
|
||
| const metadataKey = `${this._genesisHash}-${(this._runtimeVersion as RuntimeVersion).specVersion}`; | ||
|
|
||
| if (metadataKey in metadata) { | ||
| this._runtimeMetadata = new Metadata(metadata[metadataKey]); | ||
| } else { | ||
|
|
@@ -508,6 +520,7 @@ export default abstract class ApiBase<ApiType> { | |
| // get unique types & validate | ||
| this.runtimeMetadata.getUniqTypes(false); | ||
| } else { | ||
| this._extrinsicType = this._options.source.extrinsicVersion; | ||
| this._runtimeMetadata = this._options.source.runtimeMetadata; | ||
| this._runtimeVersion = this._options.source.runtimeVersion; | ||
| this._genesisHash = this._options.source.genesisHash; | ||
|
|
@@ -517,22 +530,29 @@ export default abstract class ApiBase<ApiType> { | |
| const storage = storageFromMeta(this.runtimeMetadata); | ||
| const constants = constantsFromMeta(this.runtimeMetadata); | ||
|
|
||
| // only inject if we are not a clone (global init) | ||
| if (!this._options.source) { | ||
| Event.injectMetadata(this.runtimeMetadata); | ||
| Method.injectMethods(extrinsics); | ||
|
|
||
| // detect the extrinsic version in-use based on the last block | ||
| const lastBlock: SignedBlock = await this._rpcCore.chain.getBlock().toPromise(); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We now determine the extrinsic version from the chain - basically, based on the last block, we pull out the version from contained extrinsics and then use this in any future construction of this type. |
||
|
|
||
| this._extrinsicType = lastBlock.block.extrinsics[0].type; | ||
| } | ||
|
|
||
| this._extrinsics = this.decorateExtrinsics(extrinsics, this.decorateMethod); | ||
| this._query = this.decorateStorage(storage, this.decorateMethod); | ||
| this._consts = constants; | ||
|
|
||
| this._rx.extrinsicType = this._extrinsicType; | ||
| this._rx.genesisHash = this._genesisHash; | ||
| this._rx.runtimeVersion = this._runtimeVersion; | ||
| this._rx.tx = this.decorateExtrinsics(extrinsics, rxDecorateMethod); | ||
| this._rx.query = this.decorateStorage(storage, rxDecorateMethod); | ||
| this._rx.consts = constants; | ||
| this._derive = this.decorateDerive(this._rx as ApiInterfaceRx, this.decorateMethod); | ||
|
|
||
| // only inject if we are not a clone (global init) | ||
| if (!this._options.source) { | ||
| Event.injectMetadata(this.runtimeMetadata); | ||
| Method.injectMethods(extrinsics); | ||
| } | ||
| this._derive = this.decorateDerive(this._rx as ApiInterfaceRx, this.decorateMethod); | ||
|
|
||
| return true; | ||
| } | ||
|
|
||
This file contains hidden or 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,77 @@ | ||
| // Copyright 2017-2019 @polkadot/api 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 extrinsics from '@polkadot/api-metadata/extrinsics/static'; | ||
| import { Method, ExtrinsicEra, SignaturePayload } from '@polkadot/types'; | ||
|
|
||
| import SignerPayload from './SignerPayload'; | ||
|
|
||
| describe('SignerPayload', (): void => { | ||
| const TEST = { | ||
| address: '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE', | ||
| blockHash: '0xde8f69eeb5e065e18c6950ff708d7e551f68dc9bf59a07c52367c0280f805ec7', | ||
| blockNumber: '0x0000000000231d30', | ||
| era: '0x0703', | ||
| genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b', | ||
| method: '0x0500ffd7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9e56c', | ||
| nonce: '0x0000000000001234', | ||
| tip: '0x00000000000000000000000000005678', | ||
| version: 2 | ||
| }; | ||
|
|
||
| beforeEach((): void => { | ||
| Method.injectMethods(extrinsics); | ||
| }); | ||
|
|
||
| it('creates a valid JSON output', (): void => { | ||
| expect( | ||
| new SignerPayload({ | ||
| address: '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE', | ||
| blockHash: '0xde8f69eeb5e065e18c6950ff708d7e551f68dc9bf59a07c52367c0280f805ec7', | ||
| blockNumber: '0x231d30', | ||
| era: new ExtrinsicEra({ current: 2301232, period: 200 }), | ||
| genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b', | ||
| method: new Method('0x0500ffd7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9e56c'), | ||
| nonce: 0x1234, | ||
| tip: 0x5678, | ||
| version: 2 | ||
| }).toPayload() | ||
| ).toEqual({ | ||
| address: '5DTestUPts3kjeXSTMyerHihn1uwMfLj8vU8sqF7qYrFabHE', | ||
| blockHash: '0xde8f69eeb5e065e18c6950ff708d7e551f68dc9bf59a07c52367c0280f805ec7', | ||
| blockNumber: '0x0000000000231d30', | ||
| era: '0x0703', | ||
| genesisHash: '0xdcd1346701ca8396496e52aa2785b1748deb6db09551b72159dcb3e08991025b', | ||
| method: '0x0500ffd7568e5f0a7eda67a82691ff379ac4bba4f9c9b859fe779b5d46363b61ad2db9e56c', | ||
| nonce: '0x0000000000001234', | ||
| tip: '0x00000000000000000000000000005678', | ||
| version: 2 | ||
| }); | ||
| }); | ||
|
|
||
| it('re-constructs from JSON', (): void => { | ||
| expect( | ||
| new SignerPayload(TEST).toPayload() | ||
| ).toEqual(TEST); | ||
| }); | ||
|
|
||
| it('re-constructs from itself', (): void => { | ||
| expect( | ||
| new SignerPayload( | ||
| new SignerPayload(TEST) | ||
| ).toPayload() | ||
| ).toEqual(TEST); | ||
| }); | ||
|
|
||
| it('can be used as a feed to SignaturePayload', (): void => { | ||
| const signer = new SignerPayload(TEST).toPayload(); | ||
| const payload = new SignaturePayload(signer, { version: signer.version }); | ||
|
|
||
| expect(payload.era.toHex()).toEqual(TEST.era); | ||
| expect(payload.method.toHex()).toEqual(TEST.method); | ||
| expect(payload.blockHash.toHex()).toEqual(TEST.blockHash); | ||
| expect(payload.nonce.eq(TEST.nonce)).toBe(true); | ||
| expect(payload.tip.eq(TEST.tip)).toBe(true); | ||
| }); | ||
| }); |
This file contains hidden or 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,57 @@ | ||
| // Copyright 2017-2019 @polkadot/api 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 { SignerPayload as ISignerPayload } from './types'; | ||
|
|
||
| import { Address, Balance, BlockNumber, Compact, ExtrinsicEra, Hash, Nonce, Struct, U8, Method } from '@polkadot/types'; | ||
|
|
||
| export interface SignerPayloadType { | ||
| address: Address; | ||
| blockHash: Hash; | ||
| blockNumber: BlockNumber; | ||
| era: ExtrinsicEra; | ||
| genesisHash: Hash; | ||
| method: Method; | ||
| nonce: Compact<Nonce>; | ||
| tip: Compact<Balance>; | ||
| version: U8; | ||
| } | ||
|
|
||
| export default class SignerPayload extends Struct.with({ | ||
| address: Address, | ||
| blockHash: Hash, | ||
| blockNumber: BlockNumber, | ||
| era: ExtrinsicEra, | ||
| genesisHash: Hash, | ||
| method: Method, | ||
| nonce: Compact.with(Nonce), | ||
| tip: Compact.with(Balance), | ||
| version: U8 | ||
| }) { | ||
| /** | ||
| * @description Returns this as a SignerPayloadType. This works since the Struct.with injects all the getters automatically (just ensure the 2 definitiona are matching) | ||
| */ | ||
| public get self (): SignerPayloadType { | ||
| return this as any as SignerPayloadType; | ||
| } | ||
|
|
||
| /** | ||
| * @description Creates an representation of the structure as an ISignerPayload JSON | ||
| */ | ||
| public toPayload (): ISignerPayload { | ||
| const { address, blockHash, blockNumber, era, genesisHash, method, nonce, tip, version } = this.self; | ||
|
|
||
| return { | ||
| address: address.toString(), | ||
| blockHash: blockHash.toHex(), | ||
| blockNumber: blockNumber.toHex(), | ||
| era: era.toHex(), | ||
| genesisHash: genesisHash.toHex(), | ||
| method: method.toHex(), | ||
| nonce: nonce.toHex(), | ||
| tip: tip.toHex(), | ||
| version: version.toNumber() | ||
| }; | ||
| } | ||
| } |
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I whacked this, technically a backwards incompatible change, however we have not had the
nobodyaccount in the system since poc-2 - so actually the test is bullsh*t. (inherents are now just unsigned, not with a nobody sig)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just remove it, then? Are we still supporting POC-2?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which is why the test was removed. (It relied on an unsupported all-0 sig)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sorry, right, monday morning comment...