Skip to content

Commit

Permalink
refactor(tx-builder)!: extract non-transaction into separate builder
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `buildTx`/`unpackTx` works only with transactions
If you need to work with node's entry use `packEntry`/`unpackEntry`.

BREAKING CHANGE: `Tag` include only transactions
Node entries tags moved to `EntryTag`.

BREAKING CHANGE: `buildTx` doesn't accept `prefix` anymore
Use `decode`/`encode` to convert payload to desired format.
  • Loading branch information
davidyuk committed Mar 13, 2024
1 parent 7db1f30 commit a551a1a
Show file tree
Hide file tree
Showing 25 changed files with 666 additions and 492 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ site
/src/apis/
/src/tx/builder/schema.generated.ts
/src/tx/builder/delegation/schema.generated.ts
/src/tx/builder/entry/schema.generated.ts
/tooling/autorest/compiler-swagger.yaml
/tooling/autorest/middleware-openapi.yaml
/test/environment/ledger/browser
Expand Down
11 changes: 7 additions & 4 deletions src/channel/Base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ import {
import { ChannelError } from '../utils/errors';
import { Encoded } from '../utils/encoder';
import { TxUnpacked } from '../tx/builder/schema.generated';
import { EntryTag } from '../tx/builder/entry/constants';
import { unpackEntry } from '../tx/builder/entry';
import { EntUnpacked } from '../tx/builder/entry/schema.generated';

function snakeToPascalObjKeys<Type>(obj: object): Type {
return Object.entries(obj).reduce((result, [key, val]) => ({
Expand Down Expand Up @@ -167,10 +170,10 @@ export default class Channel {
* Get current state
*/
async state(): Promise<{
calls: TxUnpacked & { tag: Tag.CallsMtree };
calls: EntUnpacked & { tag: EntryTag.CallsMtree };
halfSignedTx?: TxUnpacked & { tag: Tag.SignedTx };
signedTx?: TxUnpacked & { tag: Tag.SignedTx };
trees: TxUnpacked & { tag: Tag.StateTrees };
trees: EntUnpacked & { tag: EntryTag.StateTrees };
}> {
const res = snakeToPascalObjKeys<{
calls: Encoded.CallStateTree;
Expand All @@ -179,10 +182,10 @@ export default class Channel {
trees: Encoded.StateTrees;
}>(await call(this, 'channels.get.offchain_state', {}));
return {
calls: unpackTx(res.calls, Tag.CallsMtree),
calls: unpackEntry(res.calls),
...res.halfSignedTx !== '' && { halfSignedTx: unpackTx(res.halfSignedTx, Tag.SignedTx) },
...res.signedTx !== '' && { signedTx: unpackTx(res.signedTx, Tag.SignedTx) },
trees: unpackTx(res.trees, Tag.StateTrees),
trees: unpackEntry(res.trees),
};
}

Expand Down
14 changes: 7 additions & 7 deletions src/channel/Spend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { ChannelConnectionError } from '../utils/errors';
import {
awaitingCompletion, channelOpen, handleUnexpectedMessage, signAndNotify,
} from './handlers';
import { unpackTx } from '../tx/builder';
import { Tag } from '../tx/builder/constants';
import { TxUnpacked } from '../tx/builder/schema.generated';
import { EntryTag } from '../tx/builder/entry/constants';
import { EntUnpacked } from '../tx/builder/entry/schema.generated';
import { unpackEntry } from '../tx/builder/entry';

export default class ChannelSpend extends Channel {
/**
Expand Down Expand Up @@ -120,11 +120,11 @@ export default class ChannelSpend extends Channel {
accounts: Encoded.AccountAddress[];
contracts?: Encoded.ContractAddress[];
},
): Promise<TxUnpacked & { tag: Tag.TreesPoi }> {
return unpackTx(
(await call(this, 'channels.get.poi', { accounts, contracts })).poi,
Tag.TreesPoi,
): Promise<EntUnpacked & { tag: EntryTag.TreesPoi }> {
const { poi }: { poi: Encoded.Poi } = (
await call(this, 'channels.get.poi', { accounts, contracts })
);
return unpackEntry(poi);
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/contract/ga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import Node from '../Node';
import { getAccount } from '../chain';
import { sendTransaction, SendTransactionOptions } from '../send-transaction';
import CompilerBase from './compiler/Base';
import { packEntry } from '../tx/builder/entry';
import { EntryTag } from '../tx/builder/entry/constants';

/**
* Convert current account to GA
Expand Down Expand Up @@ -103,8 +105,8 @@ export async function buildAuthTxHash(
if (consensusProtocolVersion === ConsensusProtocolVersion.Ceres) {
if (fee == null) throw new ArgumentError('fee', 'provided (in Ceres)', fee);
if (gasPrice == null) throw new ArgumentError('gasPrice', 'provided (in Ceres)', gasPrice);
payload = hash(decode(buildTx({
tag: Tag.GaMetaTxAuthData,
payload = hash(decode(packEntry({
tag: EntryTag.GaMetaTxAuthData,
fee,
gasPrice,
txHash: encode(payload, Encoding.TxHash),
Expand Down
4 changes: 3 additions & 1 deletion src/index-browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ export {
} from './tx/builder/constants';
export type { Int, AensName } from './tx/builder/constants';
// TODO: move to constants
export { ORACLE_TTL_TYPES, CallReturnType } from './tx/builder/schema';
export { ORACLE_TTL_TYPES } from './tx/builder/schema';
export { DelegationTag } from './tx/builder/delegation/schema';
export { packDelegation, unpackDelegation } from './tx/builder/delegation';
export { EntryTag, CallReturnType } from './tx/builder/entry/constants';
export { packEntry, unpackEntry } from './tx/builder/entry';
export {
getExecutionCost, getExecutionCostBySignedTx, getExecutionCostUsingNode,
} from './tx/execution-cost';
Expand Down
2 changes: 1 addition & 1 deletion src/tx/builder/SchemaTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Field as OriginalField } from './field-types';
import { Field as OriginalField } from './field-types/interface';
import { UnionToIntersection } from '../../utils/other';

// TODO: figure out why this override is necessary
Expand Down
2 changes: 1 addition & 1 deletion src/tx/builder/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { decode as rlpDecode, encode as rlpEncode } from 'rlp';
import { Field, BinaryData } from './field-types';
import { Field, BinaryData } from './field-types/interface';
import {
ArgumentError, DecodeError, SchemaNotFoundError, InternalError,
} from '../../utils/errors';
Expand Down
32 changes: 0 additions & 32 deletions src/tx/builder/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,25 +92,17 @@ export enum AbiVersion {
*/
// TODO: implement serialisation for commented-out tags
export enum Tag {
Account = 10,
SignedTx = 11,
SpendTx = 12,
Oracle = 20,
// OracleQuery = 21,
OracleRegisterTx = 22,
OracleQueryTx = 23,
OracleResponseTx = 24,
OracleExtendTx = 25,
Name = 30,
// NameCommitment = 31,
NameClaimTx = 32,
NamePreclaimTx = 33,
NameUpdateTx = 34,
NameRevokeTx = 35,
NameTransferTx = 36,
// NameAuction = 37,
Contract = 40,
ContractCall = 41,
ContractCreateTx = 42,
ContractCallTx = 43,
ChannelCreateTx = 50,
Expand All @@ -123,33 +115,9 @@ export enum Tag {
ChannelSlashTx = 55,
ChannelSettleTx = 56,
ChannelOffChainTx = 57,
ChannelOffChainUpdateTransfer = 570,
ChannelOffChainUpdateDeposit = 571,
ChannelOffChainUpdateWithdraw = 572,
ChannelOffChainUpdateCreateContract = 573,
ChannelOffChainUpdateCallContract = 574,
// ChannelOffChainUpdateMeta = 576,
ChannelClientReconnectTx = 575,
Channel = 58,
ChannelSnapshotSoloTx = 59,
TreesPoi = 60,
// TreesDb = 61,
StateTrees = 62,
Mtree = 63,
MtreeValue = 64,
ContractsMtree = 621,
CallsMtree = 622,
ChannelsMtree = 623,
NameserviceMtree = 624,
OraclesMtree = 625,
AccountsMtree = 626,
// CompilerSophia = 70,
GaAttachTx = 80,
GaMetaTx = 81,
PayingForTx = 82,
GaMetaTxAuthData = 810,
// KeyBlock = 100,
// MicroBlock = 101,
// LightMicroBlock = 102,
// Pof = 200,
}
4 changes: 3 additions & 1 deletion src/tx/builder/delegation/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import SchemaTypes from '../SchemaTypes';
import { address, nameId, shortUIntConst } from '../field-types';
import address from '../field-types/address';
import nameId from '../field-types/name-id';
import shortUIntConst from '../field-types/short-u-int-const';
import {
Encoded, Encoding, decode, encode,
} from '../../../utils/encoder';
Expand Down
39 changes: 39 additions & 0 deletions src/tx/builder/entry/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export enum CallReturnType {
Ok = 0,
Error = 1,
Revert = 2,
}

/**
* @category entry building
*/
export enum EntryTag {
Account = 10,
Oracle = 20,
// OracleQuery = 21,
Name = 30,
// NameCommitment = 31,
// NameAuction = 37,
Contract = 40,
ContractCall = 41,
ChannelOffChainUpdateTransfer = 570,
ChannelOffChainUpdateDeposit = 571,
ChannelOffChainUpdateWithdraw = 572,
ChannelOffChainUpdateCreateContract = 573,
ChannelOffChainUpdateCallContract = 574,
// ChannelOffChainUpdateMeta = 576,
Channel = 58,
TreesPoi = 60,
// TreesDb = 61,
StateTrees = 62,
Mtree = 63,
MtreeValue = 64,
ContractsMtree = 621,
CallsMtree = 622,
ChannelsMtree = 623,
NameserviceMtree = 624,
OraclesMtree = 625,
AccountsMtree = 626,
// CompilerSophia = 70,
GaMetaTxAuthData = 810,
}
54 changes: 54 additions & 0 deletions src/tx/builder/entry/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Encoded, Encoding } from '../../../utils/encoder';
import { packRecord, unpackRecord } from '../common';
import { schemas } from './schema';
import { EntryTag } from './constants';
import { EntParams, EntUnpacked } from './schema.generated';

const encodingTag = [
[EntryTag.CallsMtree, Encoding.CallStateTree],
[EntryTag.StateTrees, Encoding.StateTrees],
[EntryTag.TreesPoi, Encoding.Poi],
] as const;

export function packEntry(params: EntParams & { tag: EntryTag.CallsMtree }): Encoded.CallStateTree;
export function packEntry(params: EntParams & { tag: EntryTag.StateTrees }): Encoded.StateTrees;
export function packEntry(params: EntParams & { tag: EntryTag.TreesPoi }): Encoded.Poi;
/**
* Pack entry
* @category entry builder
* @param params - Params of entry
* @returns Encoded entry
*/
export function packEntry(params: EntParams): Encoded.Any;
export function packEntry(params: EntParams): Encoded.Any {
const encoding = encodingTag.find(([tag]) => tag === params.tag)?.[1] ?? Encoding.Bytearray;

Check failure on line 24 in src/tx/builder/entry/index.ts

View workflow job for this annotation

GitHub Actions / main

Property 'tag' does not exist on type 'EntParams'.
return packRecord(schemas, EntryTag, params, { packEntry }, encoding);

Check failure on line 25 in src/tx/builder/entry/index.ts

View workflow job for this annotation

GitHub Actions / main

Argument of type 'EntParams' is not assignable to parameter of type '{ [k: string]: unknown; tag: number; version?: number | undefined; }'.
}

export function unpackEntry(
encoded: Encoded.CallStateTree,
): EntUnpacked & { tag: EntryTag.CallsMtree };
export function unpackEntry(
encoded: Encoded.StateTrees,
): EntUnpacked & { tag: EntryTag.StateTrees };
export function unpackEntry(
encoded: Encoded.Poi,
): EntUnpacked & { tag: EntryTag.TreesPoi };
/**
* Unpack entry
* @category entry builder
* @param encoded - Encoded entry
* @param expectedTag - Expected entry type
* @returns Params of entry
*/
export function unpackEntry<T extends EntryTag>(
encoded: Encoded.Any,
expectedTag?: T,
): EntUnpacked & { tag: T };
export function unpackEntry(
encoded: Encoded.Any,
expectedTag?: EntryTag,
): EntUnpacked {
expectedTag ??= encodingTag.find(([, enc]) => encoded.startsWith(enc))?.[0];
return unpackRecord(schemas, EntryTag, encoded, expectedTag, { unpackEntry }) as any;
}
Loading

0 comments on commit a551a1a

Please sign in to comment.