diff --git a/src/types/CommonMessageInfo.ts b/src/types/CommonMessageInfo.ts index 6e3288e..11dd8bd 100644 --- a/src/types/CommonMessageInfo.ts +++ b/src/types/CommonMessageInfo.ts @@ -12,6 +12,7 @@ import { Builder } from "../boc/Builder"; import { Slice } from "../boc/Slice"; import { Maybe } from "../utils/maybe"; import { CurrencyCollection, loadCurrencyCollection, storeCurrencyCollection } from "./CurrencyCollection"; +import { loadMessageFlags, MessageFlags, storeMessageFlags } from "./extraFlags"; // Source: https://github.com/ton-blockchain/ton/blob/24dc184a2ea67f9c47042b4104bbb4d82289fac1/crypto/block/block.tlb#L123 @@ -37,7 +38,7 @@ export type CommonMessageInfoInternal = { src: Address, dest: Address, value: CurrencyCollection, - ihrFee: bigint, + extraFlags: MessageFlags, forwardFee: bigint, createdLt: bigint, createdAt: number @@ -69,7 +70,7 @@ export function loadCommonMessageInfo(slice: Slice): CommonMessageInfo { const src = slice.loadAddress(); const dest = slice.loadAddress(); const value = loadCurrencyCollection(slice); - const ihrFee = slice.loadCoins(); + const extraFlags = loadMessageFlags(slice); const forwardFee = slice.loadCoins(); const createdLt = slice.loadUintBig(64); const createdAt = slice.loadUint(32); @@ -82,7 +83,7 @@ export function loadCommonMessageInfo(slice: Slice): CommonMessageInfo { src, dest, value, - ihrFee, + extraFlags, forwardFee, createdLt, createdAt, @@ -128,7 +129,7 @@ export function storeCommonMessageInfo(source: CommonMessageInfo) { builder.storeAddress(source.src); builder.storeAddress(source.dest); builder.store(storeCurrencyCollection(source.value)); - builder.storeCoins(source.ihrFee); + builder.store(storeMessageFlags(source.extraFlags)); builder.storeCoins(source.forwardFee); builder.storeUint(source.createdLt, 64); builder.storeUint(source.createdAt, 32); diff --git a/src/types/CommonMessageInfoRelaxed.ts b/src/types/CommonMessageInfoRelaxed.ts index 2669bda..121a8fe 100644 --- a/src/types/CommonMessageInfoRelaxed.ts +++ b/src/types/CommonMessageInfoRelaxed.ts @@ -12,6 +12,7 @@ import { Builder } from "../boc/Builder"; import { Slice } from "../boc/Slice"; import { Maybe } from "../utils/maybe"; import { CurrencyCollection, loadCurrencyCollection, storeCurrencyCollection } from "./CurrencyCollection"; +import { loadMessageFlags, MessageFlags, storeMessageFlags } from "./extraFlags"; // Source: https://github.com/ton-blockchain/ton/blob/24dc184a2ea67f9c47042b4104bbb4d82289fac1/crypto/block/block.tlb#L132 // int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool @@ -33,7 +34,7 @@ export type CommonMessageInfoRelaxedInternal = { src?: Maybe
, dest: Address, value: CurrencyCollection, - ihrFee: bigint, + extraFlags: MessageFlags, forwardFee: bigint, createdLt: bigint, createdAt: number @@ -58,7 +59,7 @@ export function loadCommonMessageInfoRelaxed(slice: Slice): CommonMessageInfoRel const src = slice.loadMaybeAddress(); const dest = slice.loadAddress(); const value = loadCurrencyCollection(slice); - const ihrFee = slice.loadCoins(); + const extraFlags = loadMessageFlags(slice); const forwardFee = slice.loadCoins(); const createdLt = slice.loadUintBig(64); const createdAt = slice.loadUint(32); @@ -71,7 +72,7 @@ export function loadCommonMessageInfoRelaxed(slice: Slice): CommonMessageInfoRel src, dest, value, - ihrFee, + extraFlags, forwardFee, createdLt, createdAt, @@ -108,7 +109,7 @@ export function storeCommonMessageInfoRelaxed(source: CommonMessageInfoRelaxed) builder.storeAddress(source.src); builder.storeAddress(source.dest); builder.store(storeCurrencyCollection(source.value)); - builder.storeCoins(source.ihrFee); + builder.store(storeMessageFlags(source.extraFlags)); builder.storeCoins(source.forwardFee); builder.storeUint(source.createdLt, 64); builder.storeUint(source.createdAt, 32); diff --git a/src/types/Maybe.ts b/src/types/Maybe.ts new file mode 100644 index 0000000..28ece53 --- /dev/null +++ b/src/types/Maybe.ts @@ -0,0 +1,23 @@ +import { Builder } from "../boc/Builder"; +import { Slice } from "../boc/Slice"; +import { Maybe } from "../utils/maybe"; + +export const loadMaybe = (loadChild: (slice: Slice) => T) => (slice: Slice): Maybe => { + const flag = slice.loadBit(); + if (flag) { + return loadChild(slice); + } else { + return undefined; + } +}; + +export const storeMaybe = ( + storeChild: (source: T) => (builder: Builder) => void +) => (source: Maybe) => (builder: Builder): void => { + if (source === undefined || source === null) { + builder.storeBit(false); + } else { + builder.storeBit(true); + storeChild(source)(builder); + } +}; diff --git a/src/types/NewBounceBody.ts b/src/types/NewBounceBody.ts new file mode 100644 index 0000000..959e059 --- /dev/null +++ b/src/types/NewBounceBody.ts @@ -0,0 +1,57 @@ +// https://github.com/ton-blockchain/ton/blob/9f328c1d32b1ff826c0dd6d9934f5eb4dc606843/crypto/block/block.tlb#L168 +// new_bounce_body#fffffffe +// original_body:^Cell +// original_info:^NewBounceOriginalInfo +// bounced_by_phase:uint8 exit_code:int32 +// compute_phase:(Maybe NewBounceComputePhaseInfo) +// = NewBounceBody; + +import { beginCell, Builder } from "../boc/Builder"; +import { Cell } from "../boc/Cell"; +import { Slice } from "../boc/Slice"; +import { Maybe } from "../utils/maybe"; +import { loadMaybe, storeMaybe } from "./Maybe"; +import { loadNewBounceComputePhaseInfo, NewBounceComputePhaseInfo, storeNewBounceComputePhaseInfo } from "./NewBounceComputePhaseInfo"; +import { loadNewBounceOriginalInfo, NewBounceOriginalInfo, storeNewBounceOriginalInfo } from "./NewBounceOriginalInfo"; + +export type NewBounceBody = { + readonly originalBody: Cell; + readonly originalInfo: NewBounceOriginalInfo; + readonly bouncedByPhase: number; + readonly exitCode: number; + readonly computePhase: Maybe; +} + +const loadMaybeNewBounceComputePhaseInfo = loadMaybe(loadNewBounceComputePhaseInfo) + +export const loadNewBounceBody = (slice: Slice): NewBounceBody => { + const originalBody = slice.loadRef(); + const originalInfo = loadNewBounceOriginalInfo(slice.loadRef().asSlice()); + const bouncedByPhase = slice.loadUint(8); + const exitCode = slice.loadInt(32); + const computePhase = loadMaybeNewBounceComputePhaseInfo(slice); + + return { + originalBody, + originalInfo, + bouncedByPhase, + exitCode, + computePhase, + }; +}; + +const storeMaybeNewBounceComputePhaseInfo = storeMaybe(storeNewBounceComputePhaseInfo); + +export const storeNewBounceBody = (source: NewBounceBody) => { + return (builder: Builder): void => { + builder.storeRef(source.originalBody); + builder.storeRef( + beginCell() + .store(storeNewBounceOriginalInfo(source.originalInfo)) + .endCell() + ); + builder.storeUint(source.bouncedByPhase, 8); + builder.storeInt(source.exitCode, 32); + builder.store(storeMaybeNewBounceComputePhaseInfo(source.computePhase)); + }; +}; diff --git a/src/types/NewBounceComputePhaseInfo.ts b/src/types/NewBounceComputePhaseInfo.ts new file mode 100644 index 0000000..f4c2e88 --- /dev/null +++ b/src/types/NewBounceComputePhaseInfo.ts @@ -0,0 +1,27 @@ +// Follows [TEP-503](https://github.com/ton-blockchain/TEPs/pull/503/files) +// https://github.com/ton-blockchain/ton/blob/9f328c1d32b1ff826c0dd6d9934f5eb4dc606843/crypto/block/block.tlb#L167 +// _ gas_used:uint32 vm_steps:uint32 = NewBounceComputePhaseInfo; + +import { Builder } from "../boc/Builder"; +import { Slice } from "../boc/Slice"; + +export type NewBounceComputePhaseInfo = { + readonly gasUsed: number; + readonly vmSteps: number; +} + +export const loadNewBounceComputePhaseInfo = (slice: Slice): NewBounceComputePhaseInfo => { + const gasUsed = slice.loadUint(32); + const vmSteps = slice.loadUint(32); + return { + gasUsed, + vmSteps, + }; +}; + +export const storeNewBounceComputePhaseInfo = (source: NewBounceComputePhaseInfo) => { + return (builder: Builder): void => { + builder.storeUint(source.gasUsed, 32); + builder.storeUint(source.vmSteps, 32); + }; +}; diff --git a/src/types/NewBounceOriginalInfo.ts b/src/types/NewBounceOriginalInfo.ts new file mode 100644 index 0000000..6819b00 --- /dev/null +++ b/src/types/NewBounceOriginalInfo.ts @@ -0,0 +1,32 @@ +// Follows [TEP-503](https://github.com/ton-blockchain/TEPs/pull/503/files) +// https://github.com/ton-blockchain/ton/blob/9f328c1d32b1ff826c0dd6d9934f5eb4dc606843/crypto/block/block.tlb#L166 +// _ value:CurrencyCollection created_lt:uint64 created_at:uint32 = NewBounceOriginalInfo; + +import { Builder } from "../boc/Builder"; +import { Slice } from "../boc/Slice"; +import { CurrencyCollection, loadCurrencyCollection, storeCurrencyCollection } from "./CurrencyCollection"; + +export type NewBounceOriginalInfo = { + readonly value: CurrencyCollection; + readonly createdLt: bigint; + readonly createdAt: number; +} + +export const loadNewBounceOriginalInfo = (slice: Slice): NewBounceOriginalInfo => { + const value = loadCurrencyCollection(slice); + const createdLt = slice.loadUintBig(64); + const createdAt = slice.loadUint(32); + return { + value, + createdLt, + createdAt, + }; +}; + +export const storeNewBounceOriginalInfo = (source: NewBounceOriginalInfo) => { + return (builder: Builder): void => { + builder.store(storeCurrencyCollection(source.value)); + builder.storeUint(source.createdLt, 64); + builder.storeUint(source.createdAt, 32); + }; +}; diff --git a/src/types/extraFlags.ts b/src/types/extraFlags.ts new file mode 100644 index 0000000..050dbfb --- /dev/null +++ b/src/types/extraFlags.ts @@ -0,0 +1,51 @@ +/** + * Follows [TEP-503](https://github.com/ton-blockchain/TEPs/pull/503/files) + */ + +import { Builder } from "../boc/Builder"; +import { Slice } from "../boc/Slice"; + +export type MessageFlags = { + format: MessageFormat; +} + +export type MessageFormat = + | MessageFormatOld + | MessageFormatNew + +export type MessageFormatOld = { + readonly type: "old"; +} + +export type MessageFormatNew = { + readonly type: "new"; + readonly includeBody: boolean; +} + +export const loadMessageFlags = (slice: Slice): MessageFlags => { + const extraFlags = slice.loadCoins(); + if ((extraFlags & 1n) === 0n) { + return { + format: { + type: "old" + }, + }; + } else { + return { + format: { + type: "new", + includeBody: (extraFlags & 2n) !== 0n, + }, + }; + } +}; + +export const storeMessageFlags = ({ format }: MessageFlags) => { + return (builder: Builder): void => { + if (format.type === 'old') { + builder.storeCoins(0n); + } else { + builder.storeCoins(1n + (format.includeBody ? 2n : 0n)); + } + }; +};