Comparing version 10.2.0 to 10.3.0
@@ -10,3 +10,3 @@ import BN from "bn.js"; | ||
}; | ||
export declare type StackNan = { | ||
export declare type StackNaN = { | ||
type: 'nan'; | ||
@@ -30,3 +30,4 @@ }; | ||
}; | ||
export declare type StackItem = StackNull | StackInt | StackNan | StackCell | StackSlice | StackBuilder | StackTuple; | ||
export declare type StackItem = StackNull | StackInt | StackNaN | StackCell | StackSlice | StackBuilder | StackTuple; | ||
export declare function serializeStack(src: StackItem[]): Cell; | ||
export declare function parseStack(src: Cell): StackItem[]; |
@@ -6,5 +6,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.serializeStack = void 0; | ||
exports.parseStack = exports.serializeStack = void 0; | ||
const bn_js_1 = __importDefault(require("bn.js")); | ||
const Builder_1 = require("../boc/Builder"); | ||
const Cell_1 = require("../boc/Cell"); | ||
const INT64_MIN = new bn_js_1.default('-9223372036854775808'); | ||
@@ -17,2 +18,13 @@ const INT64_MAX = new bn_js_1.default('9223372036854775807'); | ||
// vm_stk_cell#03 cell:^Cell = VmStackValue; | ||
//_ cell:^Cell st_bits:(## 10) end_bits:(## 10) { st_bits <= end_bits } | ||
// st_ref:(#<= 4) end_ref:(#<= 4) { st_ref <= end_ref } = VmCellSlice; | ||
// vm_stk_slice#04 _:VmCellSlice = VmStackValue; | ||
// vm_stk_builder#05 cell:^Cell = VmStackValue; | ||
// vm_stk_cont#06 cont:VmCont = VmStackValue; | ||
// vm_tupref_nil$_ = VmTupleRef 0; | ||
// vm_tupref_single$_ entry:^VmStackValue = VmTupleRef 1; | ||
// vm_tupref_any$_ {n:#} ref:^(VmTuple (n + 2)) = VmTupleRef (n + 2); | ||
// vm_tuple_nil$_ = VmTuple 0; | ||
// vm_tuple_tcons$_ {n:#} head:(VmTupleRef n) tail:^VmStackValue = VmTuple (n + 1); | ||
// vm_stk_tuple#07 len:(## 16) data:(VmTuple len) = VmStackValue; | ||
function serializeStackItem(src, builder) { | ||
@@ -28,10 +40,8 @@ if (src.type === 'null') { | ||
else { | ||
builder.storeUint8(0x02); | ||
builder.storeUint8(0x01); | ||
builder.storeInt(src.value, 256); | ||
builder.storeUint(0x0100, 15); | ||
builder.storeInt(src.value, 257); | ||
} | ||
} | ||
else if (src.type === 'nan') { | ||
builder.storeUint8(0x02); | ||
builder.storeUint8(0xff); | ||
builder.storeInt(0x02ff, 16); | ||
} | ||
@@ -46,2 +56,4 @@ else if (src.type === 'cell') { | ||
builder.storeUint(src.cell.bits.cursor, 10); | ||
builder.storeUint(0, 3); | ||
builder.storeUint(src.cell.refs.length, 3); | ||
builder.storeRef(src.cell); | ||
@@ -54,2 +66,27 @@ } | ||
else if (src.type === 'tuple') { | ||
let head = null; | ||
let tail = null; | ||
for (let i = 0; i < src.items.length; i++) { | ||
// Swap | ||
let s = head; | ||
head = tail; | ||
tail = s; | ||
if (i > 1) { | ||
head = (0, Builder_1.beginCell)() | ||
.storeRef(tail) | ||
.storeRef(head) | ||
.endCell(); | ||
} | ||
let bc = (0, Builder_1.beginCell)(); | ||
serializeStackItem(src.items[i], bc); | ||
tail = bc.endCell(); | ||
} | ||
builder.storeUint8(0x07); | ||
builder.storeUint(src.items.length, 16); | ||
if (head) { | ||
builder.storeRef(head); | ||
} | ||
if (tail) { | ||
builder.storeRef(tail); | ||
} | ||
} | ||
@@ -60,5 +97,75 @@ else { | ||
} | ||
function parseStackItem(cs) { | ||
let kind = cs.readUintNumber(8); | ||
if (kind === 0) { | ||
return { type: 'null' }; | ||
} | ||
else if (kind === 1) { | ||
return { type: 'int', value: cs.readInt(64) }; | ||
} | ||
else if (kind === 2) { | ||
if (cs.readUintNumber(7) === 0) { | ||
return { type: 'int', value: cs.readInt(257) }; | ||
} | ||
else { | ||
cs.readBit(); // must eq 1 | ||
return { type: 'nan' }; | ||
} | ||
} | ||
else if (kind === 3) { | ||
return { type: 'cell', cell: cs.readCell() }; | ||
} | ||
else if (kind === 4) { | ||
let startBits = cs.readUintNumber(10); | ||
let endBits = cs.readUintNumber(10); | ||
let startRefs = cs.readUintNumber(3); | ||
let endRefs = cs.readUintNumber(3); | ||
// Copy to new cell | ||
let rs = cs.readCell().beginParse(); | ||
rs.skip(startBits); | ||
let dt = rs.readBitString(endBits - startBits); | ||
let cell = new Cell_1.Cell('ordinary', dt); | ||
for (let i = 0; i < startRefs; i++) { | ||
cs.readCell(); | ||
} | ||
for (let i = 0; i < endRefs - startRefs; i++) { | ||
cell.refs.push(cs.readCell()); | ||
} | ||
return { type: 'slice', cell }; | ||
} | ||
else if (kind === 5) { | ||
return { type: 'builder', cell: cs.readCell() }; | ||
} | ||
else if (kind === 7) { | ||
let length = cs.readUintNumber(16); | ||
let items = []; | ||
if (length > 1) { | ||
let head = cs.readRef(); | ||
let tail = cs.readRef(); | ||
items.unshift(parseStackItem(tail)); | ||
for (let i = 0; i < length - 2; i++) { | ||
let ohead = head; | ||
head = ohead.readRef(); | ||
tail = ohead.readRef(); | ||
items.unshift(parseStackItem(tail)); | ||
} | ||
items.unshift(parseStackItem(head)); | ||
} | ||
else if (length === 1) { | ||
items.push(parseStackItem(cs.readRef())); | ||
} | ||
return { type: 'tuple', items }; | ||
} | ||
else { | ||
throw Error('Unsupported stack item'); | ||
} | ||
} | ||
// | ||
// Stack parsing | ||
// Source: https://github.com/ton-foundation/ton/blob/ae5c0720143e231c32c3d2034cfe4e533a16d969/crypto/block/block.tlb#L783 | ||
// | ||
// vm_stack#_ depth:(## 24) stack:(VmStackList depth) = VmStack; | ||
// vm_stk_cons#_ {n:#} rest:^(VmStackList n) tos:VmStackValue = VmStackList (n + 1); | ||
// vm_stk_nil#_ = VmStackList 0; | ||
// | ||
function serializeStackTail(src, builder) { | ||
@@ -68,6 +175,6 @@ if (src.length > 0) { | ||
let tail = (0, Builder_1.beginCell)(); | ||
serializeStackTail(src.slice(1), tail); | ||
serializeStackTail(src.slice(0, src.length - 1), tail); | ||
builder.storeRef(tail.endCell()); | ||
// tos | ||
serializeStackItem(src[0], builder); | ||
serializeStackItem(src[src.length - 1], builder); | ||
} | ||
@@ -78,5 +185,18 @@ } | ||
builder.storeUint(src.length, 24); | ||
serializeStackTail(src, builder); | ||
let r = [...src]; | ||
serializeStackTail(r, builder); | ||
return builder.endCell(); | ||
} | ||
exports.serializeStack = serializeStack; | ||
function parseStack(src) { | ||
let res = []; | ||
let cs = src.beginParse(); | ||
let size = cs.readUintNumber(24); | ||
for (let i = 0; i < size; i++) { | ||
let next = cs.readRef(); | ||
res.unshift(parseStackItem(cs)); | ||
cs = next; | ||
} | ||
return res; | ||
} | ||
exports.parseStack = parseStack; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const bn_js_1 = require("bn.js"); | ||
const Builder_1 = require("../boc/Builder"); | ||
const Cell_1 = require("../boc/Cell"); | ||
const stack_1 = require("./stack"); | ||
describe('stack', () => { | ||
it('should serialize stack with an address', () => { | ||
// te6ccgEBCAEAWQABGAAABwEAAAAABfXhAAEBEgEAAAAAAAAJxAIBEgEAAAAABfXhAAMBEgEAAAAABfXhAAQBEgEAAAALmE+yAAUBEgH//////////wYBEgH//////////wcAAA== | ||
// te6cckEBCAEAWQABGAAABwEAAAAABfXhAAEBEgEAAAAAAAAJxAIBEgEAAAAABfXhAAMBEgEAAAAABfXhAAQBEgEAAAALmE+yAAUBEgH//////////wYBEgH//////////wcAABC/n/0= | ||
it('should serialize stack with numbers', () => { | ||
let serialized = (0, stack_1.serializeStack)([{ | ||
"type": "int", "value": new bn_js_1.BN("100000000") | ||
"type": "int", "value": new bn_js_1.BN("-1") | ||
}, { | ||
"type": "int", "value": new bn_js_1.BN("2500") | ||
"type": "int", "value": new bn_js_1.BN("-1") | ||
}, { | ||
"type": "int", "value": new bn_js_1.BN("49800000000") | ||
}, { | ||
"type": "int", "value": new bn_js_1.BN("100000000") | ||
@@ -18,11 +20,55 @@ }, { | ||
}, { | ||
"type": "int", "value": new bn_js_1.BN("49800000000") | ||
"type": "int", "value": new bn_js_1.BN("2500") | ||
}, { | ||
"type": "int", "value": new bn_js_1.BN("-1") | ||
}, { | ||
"type": "int", "value": new bn_js_1.BN("-1") | ||
"type": "int", "value": new bn_js_1.BN("100000000") | ||
}]); | ||
expect(serialized.toBoc({ idx: false, crc32: false }).toString('base64')).toEqual('te6ccgEBCAEAWQABGAAABwEAAAAABfXhAAEBEgEAAAAAAAAJxAIBEgEAAAAABfXhAAMBEgEAAAAABfXhAAQBEgEAAAALmE+yAAUBEgH//////////wYBEgH//////////wcAAA=='); | ||
}); | ||
it('should serialize stack long unmbers', () => { | ||
const golden = 'te6ccgEBAgEAKgABSgAAAQIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqt4e0IsLXV0BAAA='; | ||
let serialized = (0, stack_1.serializeStack)([ | ||
{ | ||
"type": "int", "value": new bn_js_1.BN("12312312312312323421") | ||
} | ||
]); | ||
expect(serialized.toBoc({ idx: false, crc32: false }).toString('base64url')).toEqual('te6ccgEBCAEAWQABGAAABwEAAAAABfXhAAEBEgEAAAAAAAAJxAIBEgEAAAAABfXhAAMBEgEAAAAABfXhAAQBEgEAAAALmE+yAAUBEgH//////////wYBEgH//////////wcAAA=='); | ||
expect(serialized.toBoc({ idx: false, crc32: false }).toString('base64')).toEqual(golden); | ||
}); | ||
it('should serialize slices', () => { | ||
const golden = 'te6ccgEBAwEAHwACDwAAAQQAB0AgAgEAHeBhIIRGeIhda/QFs8ibOAAA'; | ||
let serialized = (0, stack_1.serializeStack)([ | ||
{ | ||
"type": "slice", "cell": (0, Builder_1.beginCell)().storeCoins(new bn_js_1.BN("123123123123123234211234123123123")).endCell() | ||
} | ||
]); | ||
expect(serialized.toBoc({ idx: false, crc32: false }).toString('base64')).toEqual(golden); | ||
}); | ||
it('should serialize tuples', () => { | ||
let golden = 'te6ccgEBEAEAjgADDAAABwcABAkDAQEGBwABAgEJBAAHQCAFAgAGBAECAwUAHeBhIIRGeIhda/QFs8ibOAIACAcAEgEAAAAAAAHimQASAQAAAAAAAAB7ARIB//////////8KARIBAAAAAAAAAAMLARIBAAAAAAAAAAIMARIBAAAAAAAAAAENAQIADgESAQAAAAAAAAABDwAA'; | ||
const st = (0, stack_1.parseStack)(Cell_1.Cell.fromBoc(Buffer.from(golden, 'base64'))[0]); | ||
let gs = (0, stack_1.serializeStack)(st); | ||
// console.warn(inspect(parseStack(gs), false, null, true)); | ||
// console.warn(inspect(st, false, null, true)); | ||
expect(gs.toBoc({ idx: false, crc32: false }).toString('base64')).toEqual(golden); | ||
// let serialized = serializeStack([ | ||
// { | ||
// type: 'int', value: new BN(1) | ||
// }, | ||
// { | ||
// type: 'null' | ||
// }, | ||
// { | ||
// type: 'int', value: new BN(1) | ||
// }, | ||
// { | ||
// type: 'int', value: new BN(2) | ||
// }, | ||
// { | ||
// type: 'int', value: new BN(3) | ||
// }, | ||
// { | ||
// type: 'int', value: new BN(-1) | ||
// }, | ||
// ]); | ||
// expect(serialized.toBoc({ idx: false, crc32: false }).toString('base64')).toEqual(golden); | ||
}); | ||
}); |
@@ -51,1 +51,2 @@ export { BitString } from './boc/BitString'; | ||
export { parseTransaction, parseAccountStatus, parseCurrencyCollection, parseCommonMsgInfo, parseStateInit, parseMessage, parseHashUpdate, parseAccountChange, parseStorageUsedShort, parseStoragePhase, parseCreditPhase, parseComputePhase, parseActionPhase, parseBouncePhase, parseTransactionDescription, parseRawTickTock, parseStorageUsed, parseStorageInfo, parseAccountState, parseAccountStorage, parseAccount, parseShardIdent, parseShardAccount, parseDepthBalanceInfo, parseShardAccounts, parseShardStateUnsplit, RawAccountStatus, RawCurrencyCollection, RawCommonMessageInfo, RawStateInit, RawMessage, RawHashUpdate, RawAccountStatusChange, RawStorageUsedShort, RawStoragePhase, RawComputePhase, RawActionPhase, RawBouncePhase, RawTransactionDescription, RawTransaction, RawTickTock, RawStorageUsed, RawStorageInfo, RawAccountState, RawAccountStorage, RawAccount, RawShardIdent, RawShardAccount, RawDepthBalanceInfo, RawShardAccountRef, RawShardStateUnsplit } from './block/parse'; | ||
export { StackNull, StackInt, StackNaN, StackCell, StackSlice, StackBuilder, StackTuple, StackItem, serializeStack, parseStack } from './block/stack'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.parseDictBitString = exports.parseDict = exports.ConfigStore = exports.WalletV3R2Source = exports.WalletV3R1Source = exports.WalletV2R2Source = exports.WalletV2R1Source = exports.WalletV1R3Source = exports.WalletV1R2Source = exports.WalletV1R1Source = exports.UnknownContractSource = exports.contractAddress = exports.createWalletTransferV3 = exports.createWalletTransferV2 = exports.createWalletTransferV1 = exports.WalletContract = exports.BinaryMessage = exports.CommentMessage = exports.CommonMessageInfo = exports.StateInit = exports.EmptyMessage = exports.ExternalMessage = exports.InternalMessage = exports.CellMessage = exports.parseSupportedMessage = exports.getSupportedInterfacesRaw = exports.resolveKnownInterface = exports.getSupportedInterfaces = exports.TupleSlice = exports.bnToAddress = exports.beginDict = exports.DictBuilder = exports.beginCell = exports.Builder = exports.ADNLKey = exports.ADNLAddress = exports.Slice = exports.HttpApi = exports.InMemoryCache = exports.SendMode = exports.KeyStore = exports.fromNano = exports.toNano = exports.Address = exports.validateWalletType = exports.Wallet = exports.TonClient = exports.Cell = exports.BitStringReader = exports.BitString = void 0; | ||
exports.parseShardStateUnsplit = exports.parseShardAccounts = exports.parseDepthBalanceInfo = exports.parseShardAccount = exports.parseShardIdent = exports.parseAccount = exports.parseAccountStorage = exports.parseAccountState = exports.parseStorageInfo = exports.parseStorageUsed = exports.parseRawTickTock = exports.parseTransactionDescription = exports.parseBouncePhase = exports.parseActionPhase = exports.parseComputePhase = exports.parseCreditPhase = exports.parseStoragePhase = exports.parseStorageUsedShort = exports.parseAccountChange = exports.parseHashUpdate = exports.parseMessage = exports.parseStateInit = exports.parseCommonMsgInfo = exports.parseCurrencyCollection = exports.parseAccountStatus = exports.parseTransaction = exports.safeSignVerify = exports.safeSign = exports.serializeDict = exports.parseDictRefs = void 0; | ||
exports.parseStack = exports.serializeStack = exports.parseShardStateUnsplit = exports.parseShardAccounts = exports.parseDepthBalanceInfo = exports.parseShardAccount = exports.parseShardIdent = exports.parseAccount = exports.parseAccountStorage = exports.parseAccountState = exports.parseStorageInfo = exports.parseStorageUsed = exports.parseRawTickTock = exports.parseTransactionDescription = exports.parseBouncePhase = exports.parseActionPhase = exports.parseComputePhase = exports.parseCreditPhase = exports.parseStoragePhase = exports.parseStorageUsedShort = exports.parseAccountChange = exports.parseHashUpdate = exports.parseMessage = exports.parseStateInit = exports.parseCommonMsgInfo = exports.parseCurrencyCollection = exports.parseAccountStatus = exports.parseTransaction = exports.safeSignVerify = exports.safeSign = exports.serializeDict = exports.parseDictRefs = void 0; | ||
var BitString_1 = require("./boc/BitString"); | ||
@@ -132,1 +132,5 @@ Object.defineProperty(exports, "BitString", { enumerable: true, get: function () { return BitString_1.BitString; } }); | ||
Object.defineProperty(exports, "parseShardStateUnsplit", { enumerable: true, get: function () { return parse_1.parseShardStateUnsplit; } }); | ||
// VM Stack | ||
var stack_1 = require("./block/stack"); | ||
Object.defineProperty(exports, "serializeStack", { enumerable: true, get: function () { return stack_1.serializeStack; } }); | ||
Object.defineProperty(exports, "parseStack", { enumerable: true, get: function () { return stack_1.parseStack; } }); |
{ | ||
"name": "ton", | ||
"version": "10.2.0", | ||
"version": "10.3.0", | ||
"repository": "https://github.com/tonwhales/ton.git", | ||
@@ -5,0 +5,0 @@ "author": "Steve Korshakov <steve@korshakov.com>", |
349927
9030