Skip to content

Commit b781993

Browse files
authored
Merge pull request #1202 from ton-blockchain/tvm-patch
Fix transaction original_balance and VmState::jump_to
2 parents 72020c0 + 2cca7fd commit b781993

File tree

6 files changed

+94
-70
lines changed

6 files changed

+94
-70
lines changed

common/global-version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@
1919
namespace ton {
2020

2121
// See doc/GlobalVersions.md
22-
const int SUPPORTED_VERSION = 8;
22+
const int SUPPORTED_VERSION = 9;
2323

2424
}

crypto/block/transaction.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1555,7 +1555,14 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
15551555
// ...
15561556
compute_phase = std::make_unique<ComputePhase>();
15571557
ComputePhase& cp = *(compute_phase.get());
1558-
original_balance -= total_fees;
1558+
if (cfg.global_version >= 9) {
1559+
original_balance = balance;
1560+
if (msg_balance_remaining.is_valid()) {
1561+
original_balance -= msg_balance_remaining;
1562+
}
1563+
} else {
1564+
original_balance -= total_fees;
1565+
}
15591566
if (td::sgn(balance.grams) <= 0) {
15601567
// no gas
15611568
cp.skip_reason = ComputePhase::sk_no_gas;

crypto/vm/continuation.cpp

Lines changed: 47 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@
2727

2828
namespace vm {
2929

30-
int Continuation::jump_w(VmState* st) & {
31-
return static_cast<const Continuation*>(this)->jump(st);
30+
td::Ref<Continuation> Continuation::jump_w(VmState* st, int& exitcode) & {
31+
return static_cast<const Continuation*>(this)->jump(st, exitcode);
3232
}
3333

3434
bool Continuation::has_c0() const {
@@ -286,15 +286,16 @@ std::string QuitCont::type() const {
286286
return "vmc_quit";
287287
}
288288

289-
int ExcQuitCont::jump(VmState* st) const & {
289+
td::Ref<Continuation> ExcQuitCont::jump(VmState* st, int& exitcode) const& {
290290
int n = 0;
291291
try {
292292
n = st->get_stack().pop_smallint_range(0xffff);
293293
} catch (const VmError& vme) {
294294
n = vme.get_errno();
295295
}
296296
VM_LOG(st) << "default exception handler, terminating vm with exit code " << n;
297-
return ~n;
297+
exitcode = ~n;
298+
return {};
298299
}
299300

300301
std::string ExcQuitCont::type() const {
@@ -311,16 +312,16 @@ Ref<ExcQuitCont> ExcQuitCont::deserialize(CellSlice& cs, int mode) {
311312
return cs.fetch_ulong(4) == 9 ? Ref<ExcQuitCont>{true} : Ref<ExcQuitCont>{};
312313
}
313314

314-
int PushIntCont::jump(VmState* st) const & {
315+
td::Ref<Continuation> PushIntCont::jump(VmState* st, int& exitcode) const& {
315316
VM_LOG(st) << "execute implicit PUSH " << push_val << " (slow)";
316317
st->get_stack().push_smallint(push_val);
317-
return st->jump(next);
318+
return next;
318319
}
319320

320-
int PushIntCont::jump_w(VmState* st) & {
321+
td::Ref<Continuation> PushIntCont::jump_w(VmState* st, int& exitcode) & {
321322
VM_LOG(st) << "execute implicit PUSH " << push_val;
322323
st->get_stack().push_smallint(push_val);
323-
return st->jump(std::move(next));
324+
return std::move(next);
324325
}
325326

326327
std::string PushIntCont::type() const {
@@ -345,20 +346,20 @@ Ref<PushIntCont> PushIntCont::deserialize(CellSlice& cs, int mode) {
345346
}
346347
}
347348

348-
int ArgContExt::jump(VmState* st) const & {
349+
td::Ref<Continuation> ArgContExt::jump(VmState* st, int& exitcode) const& {
349350
st->adjust_cr(data.save);
350351
if (data.cp != -1) {
351352
st->force_cp(data.cp);
352353
}
353-
return ext->jump(st);
354+
return ext;
354355
}
355356

356-
int ArgContExt::jump_w(VmState* st) & {
357+
td::Ref<Continuation> ArgContExt::jump_w(VmState* st, int& exitcode) & {
357358
st->adjust_cr(std::move(data.save));
358359
if (data.cp != -1) {
359360
st->force_cp(data.cp);
360361
}
361-
return st->jump_to(std::move(ext));
362+
return std::move(ext);
362363
}
363364

364365
bool ArgContExt::serialize(CellBuilder& cb) const {
@@ -382,32 +383,32 @@ std::string ArgContExt::type() const {
382383
return "vmc_envelope";
383384
}
384385

385-
int RepeatCont::jump(VmState* st) const & {
386+
td::Ref<Continuation> RepeatCont::jump(VmState* st, int& exitcode) const& {
386387
VM_LOG(st) << "repeat " << count << " more times (slow)\n";
387388
if (count <= 0) {
388-
return st->jump(after);
389+
return after;
389390
}
390391
if (body->has_c0()) {
391-
return st->jump(body);
392+
return body;
392393
}
393394
st->set_c0(Ref<RepeatCont>{true, body, after, count - 1});
394-
return st->jump(body);
395+
return body;
395396
}
396397

397-
int RepeatCont::jump_w(VmState* st) & {
398+
td::Ref<Continuation> RepeatCont::jump_w(VmState* st, int& exitcode) & {
398399
VM_LOG(st) << "repeat " << count << " more times\n";
399400
if (count <= 0) {
400401
body.clear();
401-
return st->jump(std::move(after));
402+
return std::move(after);
402403
}
403404
if (body->has_c0()) {
404405
after.clear();
405-
return st->jump(std::move(body));
406+
return std::move(body);
406407
}
407408
// optimization: since this is unique, reuse *this instead of creating new object
408409
--count;
409410
st->set_c0(Ref<RepeatCont>{this});
410-
return st->jump(body);
411+
return body;
411412
}
412413

413414
bool RepeatCont::serialize(CellBuilder& cb) const {
@@ -443,21 +444,21 @@ int VmState::repeat(Ref<Continuation> body, Ref<Continuation> after, long long c
443444
}
444445
}
445446

446-
int AgainCont::jump(VmState* st) const & {
447+
td::Ref<Continuation> AgainCont::jump(VmState* st, int& exitcode) const& {
447448
VM_LOG(st) << "again an infinite loop iteration (slow)\n";
448449
if (!body->has_c0()) {
449450
st->set_c0(Ref<AgainCont>{this});
450451
}
451-
return st->jump(body);
452+
return body;
452453
}
453454

454-
int AgainCont::jump_w(VmState* st) & {
455+
td::Ref<Continuation> AgainCont::jump_w(VmState* st, int& exitcode) & {
455456
VM_LOG(st) << "again an infinite loop iteration\n";
456457
if (!body->has_c0()) {
457458
st->set_c0(Ref<AgainCont>{this});
458-
return st->jump(body);
459+
return body;
459460
} else {
460-
return st->jump(std::move(body));
461+
return std::move(body);
461462
}
462463
}
463464

@@ -485,31 +486,31 @@ int VmState::again(Ref<Continuation> body) {
485486
return jump(Ref<AgainCont>{true, std::move(body)});
486487
}
487488

488-
int UntilCont::jump(VmState* st) const & {
489+
td::Ref<Continuation> UntilCont::jump(VmState* st, int& exitcode) const& {
489490
VM_LOG(st) << "until loop body end (slow)\n";
490491
if (st->get_stack().pop_bool()) {
491492
VM_LOG(st) << "until loop terminated\n";
492-
return st->jump(after);
493+
return after;
493494
}
494495
if (!body->has_c0()) {
495496
st->set_c0(Ref<UntilCont>{this});
496497
}
497-
return st->jump(body);
498+
return body;
498499
}
499500

500-
int UntilCont::jump_w(VmState* st) & {
501+
td::Ref<Continuation> UntilCont::jump_w(VmState* st, int& exitcode) & {
501502
VM_LOG(st) << "until loop body end\n";
502503
if (st->get_stack().pop_bool()) {
503504
VM_LOG(st) << "until loop terminated\n";
504505
body.clear();
505-
return st->jump(std::move(after));
506+
return std::move(after);
506507
}
507508
if (!body->has_c0()) {
508509
st->set_c0(Ref<UntilCont>{this});
509-
return st->jump(body);
510+
return body;
510511
} else {
511512
after.clear();
512-
return st->jump(std::move(body));
513+
return std::move(body);
513514
}
514515
}
515516

@@ -541,54 +542,54 @@ int VmState::until(Ref<Continuation> body, Ref<Continuation> after) {
541542
return jump(std::move(body));
542543
}
543544

544-
int WhileCont::jump(VmState* st) const & {
545+
td::Ref<Continuation> WhileCont::jump(VmState* st, int& exitcode) const& {
545546
if (chkcond) {
546547
VM_LOG(st) << "while loop condition end (slow)\n";
547548
if (!st->get_stack().pop_bool()) {
548549
VM_LOG(st) << "while loop terminated\n";
549-
return st->jump(after);
550+
return after;
550551
}
551552
if (!body->has_c0()) {
552553
st->set_c0(Ref<WhileCont>{true, cond, body, after, false});
553554
}
554-
return st->jump(body);
555+
return body;
555556
} else {
556557
VM_LOG(st) << "while loop body end (slow)\n";
557558
if (!cond->has_c0()) {
558559
st->set_c0(Ref<WhileCont>{true, cond, body, after, true});
559560
}
560-
return st->jump(cond);
561+
return cond;
561562
}
562563
}
563564

564-
int WhileCont::jump_w(VmState* st) & {
565+
td::Ref<Continuation> WhileCont::jump_w(VmState* st, int& exitcode) & {
565566
if (chkcond) {
566567
VM_LOG(st) << "while loop condition end\n";
567568
if (!st->get_stack().pop_bool()) {
568569
VM_LOG(st) << "while loop terminated\n";
569570
cond.clear();
570571
body.clear();
571-
return st->jump(std::move(after));
572+
return std::move(after);
572573
}
573574
if (!body->has_c0()) {
574575
chkcond = false; // re-use current object since we hold the unique pointer to it
575576
st->set_c0(Ref<WhileCont>{this});
576-
return st->jump(body);
577+
return body;
577578
} else {
578579
cond.clear();
579580
after.clear();
580-
return st->jump(std::move(body));
581+
return std::move(body);
581582
}
582583
} else {
583584
VM_LOG(st) << "while loop body end\n";
584585
if (!cond->has_c0()) {
585586
chkcond = true; // re-use current object
586587
st->set_c0(Ref<WhileCont>{this});
587-
return st->jump(cond);
588+
return cond;
588589
} else {
589590
body.clear();
590591
after.clear();
591-
return st->jump(std::move(cond));
592+
return std::move(cond);
592593
}
593594
}
594595
}
@@ -627,16 +628,16 @@ int VmState::loop_while(Ref<Continuation> cond, Ref<Continuation> body, Ref<Cont
627628
return jump(std::move(cond));
628629
}
629630

630-
int OrdCont::jump(VmState* st) const & {
631+
td::Ref<Continuation> OrdCont::jump(VmState* st, int& exitcode) const& {
631632
st->adjust_cr(data.save);
632633
st->set_code(code, data.cp);
633-
return 0;
634+
return {};
634635
}
635636

636-
int OrdCont::jump_w(VmState* st) & {
637+
td::Ref<Continuation> OrdCont::jump_w(VmState* st, int& exitcode) & {
637638
st->adjust_cr(std::move(data.save));
638639
st->set_code(std::move(code), data.cp);
639-
return 0;
640+
return {};
640641
}
641642

642643
bool OrdCont::serialize(CellBuilder& cb) const {

0 commit comments

Comments
 (0)