-
Notifications
You must be signed in to change notification settings - Fork 39
/
TransactionComputePhase.ts
113 lines (105 loc) · 3.84 KB
/
TransactionComputePhase.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/**
* Copyright (c) Whales Corp.
* All Rights Reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import { beginCell, Builder } from "../boc/Builder";
import { Slice } from "../boc/Slice";
import { Maybe } from "../utils/maybe";
import { ComputeSkipReason, loadComputeSkipReason, storeComputeSkipReason } from "./ComputeSkipReason";
// Source: https://github.com/ton-blockchain/ton/blob/24dc184a2ea67f9c47042b4104bbb4d82289fac1/crypto/block/block.tlb#L296
// tr_phase_compute_skipped$0 reason:ComputeSkipReason
// = TrComputePhase;
// tr_phase_compute_vm$1 success:Bool msg_state_used:Bool
// account_activated:Bool gas_fees:Grams
// ^[ gas_used:(VarUInteger 7)
// gas_limit:(VarUInteger 7) gas_credit:(Maybe (VarUInteger 3))
// mode:int8 exit_code:int32 exit_arg:(Maybe int32)
// vm_steps:uint32
// vm_init_state_hash:bits256 vm_final_state_hash:bits256 ]
// = TrComputePhase;
export type TransactionComputePhase = TransactionComputeSkipped | TransactionComputeVm;
export type TransactionComputeSkipped = { type: 'skipped', reason: ComputeSkipReason };
export type TransactionComputeVm = {
type: 'vm',
success: boolean,
messageStateUsed: boolean,
accountActivated: boolean,
gasFees: bigint,
gasUsed: bigint,
gasLimit: bigint,
gasCredit?: Maybe<bigint>,
mode: number,
exitCode: number,
exitArg?: Maybe<number>,
vmSteps: number,
vmInitStateHash: bigint,
vmFinalStateHash: bigint
}
export function loadTransactionComputePhase(slice: Slice): TransactionComputePhase {
// Skipped
if (!slice.loadBit()) {
let reason = loadComputeSkipReason(slice);
return {
type: 'skipped',
reason
};
}
let success = slice.loadBit();
let messageStateUsed = slice.loadBit();
let accountActivated = slice.loadBit();
let gasFees = slice.loadCoins();
const vmState = slice.loadRef().beginParse();
let gasUsed = vmState.loadVarUintBig(3);
let gasLimit = vmState.loadVarUintBig(3);
let gasCredit = vmState.loadBit() ? vmState.loadVarUintBig(2) : undefined;
let mode = vmState.loadUint(8);
let exitCode = vmState.loadInt(32);
let exitArg = vmState.loadBit() ? vmState.loadInt(32) : undefined;
let vmSteps = vmState.loadUint(32);
let vmInitStateHash = vmState.loadUintBig(256);
let vmFinalStateHash = vmState.loadUintBig(256);
return {
type: 'vm',
success,
messageStateUsed,
accountActivated,
gasFees,
gasUsed,
gasLimit,
gasCredit,
mode,
exitCode,
exitArg,
vmSteps,
vmInitStateHash,
vmFinalStateHash
};
}
export function storeTransactionComputePhase(src: TransactionComputePhase) {
return (builder: Builder) => {
if (src.type === 'skipped') {
builder.storeBit(0);
builder.store(storeComputeSkipReason(src.reason));
return;
}
builder.storeBit(1);
builder.storeBit(src.success);
builder.storeBit(src.messageStateUsed);
builder.storeBit(src.accountActivated);
builder.storeCoins(src.gasFees);
builder.storeRef(beginCell()
.storeVarUint(src.gasUsed, 3)
.storeVarUint(src.gasLimit, 3)
.store((b) => (src.gasCredit !== undefined && src.gasCredit !== null) ? b.storeBit(1).storeVarUint(src.gasCredit, 2) : b.storeBit(0))
.storeUint(src.mode, 8)
.storeInt(src.exitCode, 32)
.store((b) => (src.exitArg !== undefined && src.exitArg !== null) ? b.storeBit(1).storeInt(src.exitArg, 32) : b.storeBit(0))
.storeUint(src.vmSteps, 32)
.storeUint(src.vmInitStateHash, 256)
.storeUint(src.vmFinalStateHash, 256)
.endCell());
}
}