Skip to content

Commit

Permalink
TransactionExtension, ExtrinsicV5 (#5976)
Browse files Browse the repository at this point in the history
* TransactionExtension Start

* Add V5_VERSION logic to necessary classes

* Fix latest version to 5

* Add v5 dir

* Add v5 types to interfaces

* Cleanup paths

* Update ExtrinsicSignature V5

* Cleanup v5 folders

* nits

* signed works

* general works?

* Clean linter, and imports

* fix typing

* Change sign in v5 to hash all payloads

* remove SignV5Options

* Remove SignatureV5Options

* Change versioning

* added bitmasks

* cleanup

* change version to constant

* Add tests

* Decouple payload v5 from v4

* Add helper fn to get signed extension version from the registry

* Add version to encoding

* Cleanup tests

* renamed getSignedExtensionVersion to getTransactionExtensionVersion

* removed this.type for v5

* undo this.type removal

* replaced signedExtensionVersion by transactionExtensionVersion for v5 in ExtrinsicSignature

* unfinished Preamble Class

* Revert "unfinished Preamble Class"

This reverts commit 0b1c350.

* Added test for decoding

* Fix test

* preamble typo

* updated GeneralExtrinsic [WIP]

* added generalExtrinsic

* General Extrinsic

* linting and renaming

* renaming

* Extend the v5 signed extrinsic test

* Unmask preamble

* Set payload to GeneralExtrinsicPayload

* Add test for GeneralExtrinsicPayload

* Start GeneralExtrinsicEncoded tests

* Add GeneralExt as a replacement class

* Export GeneralExt

* Fix nits

* Start decodeu8a

* GeneralExt tests

* GeneralExt fix

* updated decodeu8a

* Fix decoding

* Add error handling for invalid version

* remove fluff

* Fix version in GeneralExtrinsic

* fixes

* add parent class methods as errors

* Reorg some types

* Add test for GeneralExtrinsic

* Fix compatibility with GeneralExtrinsic

* fix structure of GeneralExtrinsic

* Add another test

* cleanup

* Fix decoding bug for bare

* fix change from bare to signed

* linting

* Fix encodinglength

* Set default to preamble to bre

* Fix tests

* fixed version setting

* Add test

---------

Co-authored-by: bee344 <[email protected]>
  • Loading branch information
TarikGul and bee344 authored Oct 2, 2024
1 parent 096da21 commit c146727
Show file tree
Hide file tree
Showing 22 changed files with 1,302 additions and 47 deletions.
5 changes: 4 additions & 1 deletion packages/types-augment/src/registry/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import type { ApprovalFlag, DefunctVoter, Renouncing, SetIndex, Vote, VoteIndex,
import type { CreatedBlock, ImportedAux } from '@polkadot/types/interfaces/engine';
import type { BlockV0, BlockV1, BlockV2, EIP1559Transaction, EIP2930Transaction, EthAccessList, EthAccessListItem, EthAccount, EthAddress, EthBlock, EthBloom, EthCallRequest, EthFeeHistory, EthFilter, EthFilterAddress, EthFilterChanges, EthFilterTopic, EthFilterTopicEntry, EthFilterTopicInner, EthHeader, EthLog, EthReceipt, EthReceiptV0, EthReceiptV3, EthRichBlock, EthRichHeader, EthStorageProof, EthSubKind, EthSubParams, EthSubResult, EthSyncInfo, EthSyncStatus, EthTransaction, EthTransactionAction, EthTransactionCondition, EthTransactionRequest, EthTransactionSignature, EthTransactionStatus, EthWork, EthereumAccountId, EthereumAddress, EthereumLookupSource, EthereumSignature, LegacyTransaction, TransactionV0, TransactionV1, TransactionV2 } from '@polkadot/types/interfaces/eth';
import type { EvmAccount, EvmCallInfo, EvmCallInfoV2, EvmCreateInfo, EvmCreateInfoV2, EvmLog, EvmVicinity, EvmWeightInfo, ExitError, ExitFatal, ExitReason, ExitRevert, ExitSucceed } from '@polkadot/types/interfaces/evm';
import type { AnySignature, EcdsaSignature, Ed25519Signature, Era, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV4, ExtrinsicSignature, ExtrinsicSignatureV4, ExtrinsicUnknown, ExtrinsicV4, ImmortalEra, MortalEra, MultiSignature, Signature, SignerPayload, Sr25519Signature } from '@polkadot/types/interfaces/extrinsics';
import type { AnySignature, EcdsaSignature, Ed25519Signature, Era, Extrinsic, ExtrinsicEra, ExtrinsicPayload, ExtrinsicPayloadUnknown, ExtrinsicPayloadV4, ExtrinsicPayloadV5, ExtrinsicSignature, ExtrinsicSignatureV4, ExtrinsicSignatureV5, ExtrinsicUnknown, ExtrinsicV4, ExtrinsicV5, ImmortalEra, MortalEra, MultiSignature, Signature, SignerPayload, Sr25519Signature } from '@polkadot/types/interfaces/extrinsics';
import type { FungiblesAccessError } from '@polkadot/types/interfaces/fungibles';
import type { AssetOptions, Owner, PermissionLatest, PermissionVersions, PermissionsV1 } from '@polkadot/types/interfaces/genericAsset';
import type { GenesisBuildErr } from '@polkadot/types/interfaces/genesisBuilder';
Expand Down Expand Up @@ -504,12 +504,15 @@ declare module '@polkadot/types/types/registry' {
ExtrinsicPayload: ExtrinsicPayload;
ExtrinsicPayloadUnknown: ExtrinsicPayloadUnknown;
ExtrinsicPayloadV4: ExtrinsicPayloadV4;
ExtrinsicPayloadV5: ExtrinsicPayloadV5;
ExtrinsicSignature: ExtrinsicSignature;
ExtrinsicSignatureV4: ExtrinsicSignatureV4;
ExtrinsicSignatureV5: ExtrinsicSignatureV5;
ExtrinsicStatus: ExtrinsicStatus;
ExtrinsicsWeight: ExtrinsicsWeight;
ExtrinsicUnknown: ExtrinsicUnknown;
ExtrinsicV4: ExtrinsicV4;
ExtrinsicV5: ExtrinsicV5;
f32: f32;
F32: F32;
f64: f64;
Expand Down
1 change: 1 addition & 0 deletions packages/types-codec/src/types/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ export interface Registry {
getClassName (clazz: CodecClass): string | undefined;
getOrThrow <T extends Codec = Codec, K extends string = string> (name: K, msg?: string): CodecClass<T>;
getOrUnknown <T extends Codec = Codec, K extends string = string> (name: K): CodecClass<T>;
getTransactionExtensionVersion (): number;
getSignedExtensionExtra (): Record<string, string>;
getSignedExtensionTypes (): Record<string, string>;

Expand Down
5 changes: 5 additions & 0 deletions packages/types/src/create/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,11 @@ export class TypeRegistry implements Registry {
return this.get<T, K>(name, true) as unknown as CodecClass<R>;
}

// Only used in extrinsic version 5
public getTransactionExtensionVersion (): number {
return 0;
}

public getSignedExtensionExtra (): Record<string, string> {
return expandExtensionTypes(this.#signedExtensions, 'payload', this.#userExtensions);
}
Expand Down
77 changes: 77 additions & 0 deletions packages/types/src/extrinsic/Extrinsic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,81 @@ describe('Extrinsic', (): void => {
expect(extrinsic.toPrimitive()).toEqual({ method: { args: { dest: { id: '5DiuK2zR4asj2CEh77SKtUgTswTLkD8eiAKrByg5G3wL5w9b' }, value: 104560923320000 }, callIndex: '0x0600' }, signature: { era: { mortalEra: [1024, 186] }, nonce: 68, signature: { ed25519: '0xd99ffe3e610ad234e1414bda5831395a6df9098bf80b01561ce89a5065ae89d5c10e1619c6c99131b0bea4fb73ef04d07c07770e2ae9df5c325c331769ccb300' }, signer: { id: '5Hn8KKEp8qruCGWaN9MEsjTs4FXB4wv9xn7g1RWkNeKKNXCr' }, tip: 30000000000 } });
});
});

describe('V5', () => {
// Ensure it does not have its registry modified by the fallback extensions.
const registry = new TypeRegistry();
const metadata = new Metadata(registry, rpcMetadata);

registry.setMetadata(metadata);

describe('SignedExtrinsic', () => {
it('Should work when the version and preamble is passed in', () => {
const extrinsic = new Extrinsic(
registry,
'0x51028500d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d011e0b7d9438899333c50121f8e10144952d51c3bb8d0ea11dd1f24940d8ff615ad351d95ed9f41f078748ed7cf182864a20b38eebfaef6629433365eb90c0148c007502000000000603008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480b00a0724e1809',
{ preamble: 'signed', version: 5 }
);

expect(extrinsic.signer.toString()).toEqual('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
expect(extrinsic.era.toHuman()).toEqual({ MortalEra: { period: '64', phase: '39' } });
expect(extrinsic.nonce.toNumber()).toEqual(0);
expect(extrinsic.tip.toHuman()).toEqual('0');
expect(extrinsic.callIndex).toEqual(new Uint8Array([6, 3]));
expect(extrinsic.args[0].toHex()).toEqual('0x008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48');
expect(extrinsic.args[1].toHuman()).toEqual('10,000,000,000,000');
});

it('Should work when the version and preamble is not passed in', () => {
const extrinsic = new Extrinsic(
registry,
'0x51028500d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d011e0b7d9438899333c50121f8e10144952d51c3bb8d0ea11dd1f24940d8ff615ad351d95ed9f41f078748ed7cf182864a20b38eebfaef6629433365eb90c0148c007502000000000603008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a480b00a0724e1809'
);

expect(extrinsic.version).toEqual(133);
expect(extrinsic.signer.toString()).toEqual('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
expect(extrinsic.era.toHuman()).toEqual({ MortalEra: { period: '64', phase: '39' } });
expect(extrinsic.nonce.toNumber()).toEqual(0);
expect(extrinsic.tip.toHuman()).toEqual('0');
expect(extrinsic.callIndex).toEqual(new Uint8Array([6, 3]));
expect(extrinsic.args[0].toHex()).toEqual('0x008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48');
expect(extrinsic.args[1].toHuman()).toEqual('10,000,000,000,000');
});
});

describe('GeneralExtrinsic', () => {
it('Should work when the version and preamble is passed in', () => {
const extrinsic = new Extrinsic(
registry,
'0xc44500650000000000060000d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0700e40b5402',
{ preamble: 'general', version: 5 }
);

expect(extrinsic.version).toEqual(69);
// expect(extrinsic.transactionExtensionVersion.toNumber()).toEqual(0);
expect(extrinsic.method.toHuman()).toEqual({ args: { dest: { Id: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY' }, value: '10,000,000,000' }, method: 'transferAllowDeath', section: 'balances' });
expect(extrinsic.era.toHuman()).toEqual({ MortalEra: { period: '64', phase: '6' } });
expect(extrinsic.tip.toNumber()).toEqual(0);
expect(extrinsic.mode.toNumber()).toEqual(0);
expect(extrinsic.assetId.toHuman()).toEqual(null);
expect(extrinsic.nonce.toNumber()).toEqual(0);
});

it('Should work when there is no version and preamble is passed in', () => {
const extrinsic = new Extrinsic(
registry,
'0xc44500650000000000060000d43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d0700e40b5402'
);

expect(extrinsic.version).toEqual(69);
// expect(extrinsic.transactionExtensionVersion.toNumber()).toEqual(0);
expect(extrinsic.method.toHuman()).toEqual({ args: { dest: { Id: '5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY' }, value: '10,000,000,000' }, method: 'transferAllowDeath', section: 'balances' });
expect(extrinsic.era.toHuman()).toEqual({ MortalEra: { period: '64', phase: '6' } });
expect(extrinsic.tip.toNumber()).toEqual(0);
expect(extrinsic.mode.toNumber()).toEqual(0);
expect(extrinsic.assetId.toHuman()).toEqual(null);
expect(extrinsic.nonce.toNumber()).toEqual(0);
});
});
});
});
Loading

0 comments on commit c146727

Please sign in to comment.