mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
vm bugfixes
This commit is contained in:
parent
e27fb1e09c
commit
dd4ac0f440
9 changed files with 107 additions and 30 deletions
|
@ -500,8 +500,8 @@ bool HashmapE::add_values(vm::CellBuilder& cb, vm::CellSlice& cs1, vm::CellSlice
|
|||
int n = root_type.n;
|
||||
vm::Dictionary dict1{vm::DictAdvance(), cs1, n}, dict2{vm::DictAdvance(), cs2, n};
|
||||
const TLB& vt = root_type.value_type;
|
||||
vm::Dictionary::simple_combine_func_t combine = [vt](vm::CellBuilder& cb, Ref<vm::CellSlice> cs1_ref,
|
||||
Ref<vm::CellSlice> cs2_ref) -> bool {
|
||||
vm::Dictionary::simple_combine_func_t combine = [&vt](vm::CellBuilder& cb, Ref<vm::CellSlice> cs1_ref,
|
||||
Ref<vm::CellSlice> cs2_ref) -> bool {
|
||||
if (!vt.add_values(cb, cs1_ref.write(), cs2_ref.write())) {
|
||||
throw CombineError{};
|
||||
}
|
||||
|
@ -514,8 +514,8 @@ bool HashmapE::add_values_ref(Ref<vm::Cell>& res, Ref<vm::Cell> arg1, Ref<vm::Ce
|
|||
int n = root_type.n;
|
||||
vm::Dictionary dict1{std::move(arg1), n}, dict2{std::move(arg2), n};
|
||||
const TLB& vt = root_type.value_type;
|
||||
vm::Dictionary::simple_combine_func_t combine = [vt](vm::CellBuilder& cb, Ref<vm::CellSlice> cs1_ref,
|
||||
Ref<vm::CellSlice> cs2_ref) -> bool {
|
||||
vm::Dictionary::simple_combine_func_t combine = [&vt](vm::CellBuilder& cb, Ref<vm::CellSlice> cs1_ref,
|
||||
Ref<vm::CellSlice> cs2_ref) -> bool {
|
||||
if (!vt.add_values(cb, cs1_ref.write(), cs2_ref.write())) {
|
||||
throw CombineError{};
|
||||
}
|
||||
|
@ -535,8 +535,8 @@ int HashmapE::sub_values(vm::CellBuilder& cb, vm::CellSlice& cs1, vm::CellSlice&
|
|||
int n = root_type.n;
|
||||
vm::Dictionary dict1{vm::DictAdvance(), cs1, n}, dict2{vm::DictAdvance(), cs2, n};
|
||||
const TLB& vt = root_type.value_type;
|
||||
vm::Dictionary::simple_combine_func_t combine = [vt](vm::CellBuilder& cb, Ref<vm::CellSlice> cs1_ref,
|
||||
Ref<vm::CellSlice> cs2_ref) -> bool {
|
||||
vm::Dictionary::simple_combine_func_t combine = [&vt](vm::CellBuilder& cb, Ref<vm::CellSlice> cs1_ref,
|
||||
Ref<vm::CellSlice> cs2_ref) -> bool {
|
||||
int r = vt.sub_values(cb, cs1_ref.write(), cs2_ref.write());
|
||||
if (r < 0) {
|
||||
throw CombineError{};
|
||||
|
@ -555,8 +555,8 @@ int HashmapE::sub_values_ref(Ref<vm::Cell>& res, Ref<vm::Cell> arg1, Ref<vm::Cel
|
|||
int n = root_type.n;
|
||||
vm::Dictionary dict1{std::move(arg1), n}, dict2{std::move(arg2), n};
|
||||
const TLB& vt = root_type.value_type;
|
||||
vm::Dictionary::simple_combine_func_t combine = [vt](vm::CellBuilder& cb, Ref<vm::CellSlice> cs1_ref,
|
||||
Ref<vm::CellSlice> cs2_ref) -> bool {
|
||||
vm::Dictionary::simple_combine_func_t combine = [&vt](vm::CellBuilder& cb, Ref<vm::CellSlice> cs1_ref,
|
||||
Ref<vm::CellSlice> cs2_ref) -> bool {
|
||||
int r = vt.sub_values(cb, cs1_ref.write(), cs2_ref.write());
|
||||
if (r < 0) {
|
||||
throw CombineError{};
|
||||
|
|
|
@ -68,6 +68,9 @@ struct VarUInteger final : TLB_Complex {
|
|||
bool store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const override;
|
||||
unsigned precompute_integer_size(const td::BigInt256& value) const;
|
||||
unsigned precompute_integer_size(td::RefInt256 value) const;
|
||||
std::ostream& print_type(std::ostream& os) const override {
|
||||
return os << "(VarUInteger " << n << ")";
|
||||
}
|
||||
};
|
||||
|
||||
extern const VarUInteger t_VarUInteger_3, t_VarUInteger_7, t_VarUInteger_16, t_VarUInteger_32;
|
||||
|
@ -82,6 +85,9 @@ struct VarUIntegerPos final : TLB_Complex {
|
|||
td::RefInt256 as_integer_skip(vm::CellSlice& cs) const override;
|
||||
unsigned long long as_uint(const vm::CellSlice& cs) const override;
|
||||
bool store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const override;
|
||||
std::ostream& print_type(std::ostream& os) const override {
|
||||
return os << "(VarUIntegerPos " << n << ")";
|
||||
}
|
||||
};
|
||||
|
||||
extern const VarUIntegerPos t_VarUIntegerPos_16, t_VarUIntegerPos_32;
|
||||
|
@ -99,6 +105,9 @@ struct VarInteger final : TLB_Complex {
|
|||
return cb.store_zeroes_bool(ln);
|
||||
}
|
||||
bool store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const override;
|
||||
std::ostream& print_type(std::ostream& os) const override {
|
||||
return os << "(VarInteger " << n << ")";
|
||||
}
|
||||
};
|
||||
|
||||
struct VarIntegerNz final : TLB_Complex {
|
||||
|
@ -111,6 +120,9 @@ struct VarIntegerNz final : TLB_Complex {
|
|||
td::RefInt256 as_integer_skip(vm::CellSlice& cs) const override;
|
||||
long long as_int(const vm::CellSlice& cs) const override;
|
||||
bool store_integer_value(vm::CellBuilder& cb, const td::BigInt256& value) const override;
|
||||
std::ostream& print_type(std::ostream& os) const override {
|
||||
return os << "(VarIntegerNz " << n << ")";
|
||||
}
|
||||
};
|
||||
|
||||
struct Unary final : TLB {
|
||||
|
@ -312,8 +324,8 @@ struct MsgAddress final : TLB_Complex {
|
|||
extern const MsgAddress t_MsgAddress;
|
||||
|
||||
struct ExtraCurrencyCollection final : TLB {
|
||||
HashmapE dict_type;
|
||||
ExtraCurrencyCollection() : dict_type(32, t_VarUIntegerPos_32) {
|
||||
HashmapE dict_type, dict_type2;
|
||||
ExtraCurrencyCollection() : dict_type(32, t_VarUIntegerPos_32), dict_type2(32, t_VarUInteger_32) {
|
||||
}
|
||||
int get_size(const vm::CellSlice& cs) const override {
|
||||
return dict_type.get_size(cs);
|
||||
|
@ -328,13 +340,13 @@ struct ExtraCurrencyCollection final : TLB {
|
|||
return dict_type.add_values(cb, cs1, cs2);
|
||||
}
|
||||
int sub_values(vm::CellBuilder& cb, vm::CellSlice& cs1, vm::CellSlice& cs2) const override {
|
||||
return dict_type.sub_values(cb, cs1, cs2);
|
||||
return dict_type2.sub_values(cb, cs1, cs2);
|
||||
}
|
||||
bool add_values_ref(Ref<vm::Cell>& res, Ref<vm::Cell> arg1, Ref<vm::Cell> arg2) const {
|
||||
return dict_type.add_values_ref(res, std::move(arg1), std::move(arg2));
|
||||
}
|
||||
int sub_values_ref(Ref<vm::Cell>& res, Ref<vm::Cell> arg1, Ref<vm::Cell> arg2) const {
|
||||
return dict_type.sub_values_ref(res, std::move(arg1), std::move(arg2));
|
||||
return dict_type2.sub_values_ref(res, std::move(arg1), std::move(arg2));
|
||||
}
|
||||
bool store_ref(vm::CellBuilder& cb, Ref<vm::Cell> arg) const {
|
||||
return dict_type.store_ref(cb, std::move(arg));
|
||||
|
|
|
@ -1651,7 +1651,7 @@ bool sub_extra_currency(Ref<vm::Cell> extra1, Ref<vm::Cell> extra2, Ref<vm::Cell
|
|||
res.clear();
|
||||
return false;
|
||||
} else {
|
||||
return block::tlb::t_ExtraCurrencyCollection.sub_values_ref(res, std::move(extra1), std::move(extra2));
|
||||
return block::tlb::t_ExtraCurrencyCollection.sub_values_ref(res, std::move(extra1), std::move(extra2)) >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -616,6 +616,24 @@ void interpret_is_workchain_descr(vm::Stack& stack) {
|
|||
stack.push_bool(block::gen::t_WorkchainDescr.validate_ref(std::move(cell)));
|
||||
}
|
||||
|
||||
void interpret_add_extra_currencies(vm::Stack& stack) {
|
||||
Ref<vm::Cell> y = stack.pop_maybe_cell(), x = stack.pop_maybe_cell(), res;
|
||||
bool ok = block::add_extra_currency(std::move(x), std::move(y), res);
|
||||
if (ok) {
|
||||
stack.push_maybe_cell(std::move(res));
|
||||
}
|
||||
stack.push_bool(ok);
|
||||
}
|
||||
|
||||
void interpret_sub_extra_currencies(vm::Stack& stack) {
|
||||
Ref<vm::Cell> y = stack.pop_maybe_cell(), x = stack.pop_maybe_cell(), res;
|
||||
bool ok = block::sub_extra_currency(std::move(x), std::move(y), res);
|
||||
if (ok) {
|
||||
stack.push_maybe_cell(std::move(res));
|
||||
}
|
||||
stack.push_bool(ok);
|
||||
}
|
||||
|
||||
void init_words_custom(fift::Dictionary& d) {
|
||||
d.def_stack_word("verb@ ", interpret_get_verbosity);
|
||||
d.def_stack_word("verb! ", interpret_set_verbosity);
|
||||
|
@ -631,6 +649,8 @@ void init_words_custom(fift::Dictionary& d) {
|
|||
d.def_stack_word("create_state ", interpret_create_state);
|
||||
d.def_stack_word("isShardState? ", interpret_is_shard_state);
|
||||
d.def_stack_word("isWorkchainDescr? ", interpret_is_workchain_descr);
|
||||
d.def_stack_word("CC+? ", interpret_add_extra_currencies);
|
||||
d.def_stack_word("CC-? ", interpret_sub_extra_currencies);
|
||||
}
|
||||
|
||||
tlb::TypenameLookup tlb_dict;
|
||||
|
|
|
@ -1555,9 +1555,17 @@ int Transaction::try_action_send_msg(const vm::CellSlice& cs0, ActionPhase& ap,
|
|||
Ref<vm::Cell> new_extra;
|
||||
|
||||
if (!block::sub_extra_currency(ap.remaining_balance.extra, req.extra, new_extra)) {
|
||||
LOG(DEBUG) << "not enough extra currency to send with the message";
|
||||
LOG(DEBUG) << "not enough extra currency to send with the message: "
|
||||
<< block::CurrencyCollection{0, req.extra}.to_str() << " required, only "
|
||||
<< block::CurrencyCollection{0, ap.remaining_balance.extra}.to_str() << " available";
|
||||
return skip_invalid ? 0 : 38; // not enough (extra) funds
|
||||
}
|
||||
if (ap.remaining_balance.extra.not_null() || req.extra.not_null()) {
|
||||
LOG(WARNING) << "subtracting extra currencies: "
|
||||
<< block::CurrencyCollection{0, ap.remaining_balance.extra}.to_str() << " minus "
|
||||
<< block::CurrencyCollection{0, req.extra}.to_str() << " equals "
|
||||
<< block::CurrencyCollection{0, new_extra}.to_str();
|
||||
}
|
||||
|
||||
auto fwd_fee_mine = msg_prices.get_first_part(fwd_fee);
|
||||
auto fwd_fee_remain = fwd_fee - fwd_fee_mine;
|
||||
|
@ -1691,7 +1699,9 @@ int Transaction::try_action_reserve_currency(vm::CellSlice& cs, ActionPhase& ap,
|
|||
}
|
||||
}
|
||||
if (!block::sub_extra_currency(ap.remaining_balance.extra, reserve.extra, newc.extra)) {
|
||||
LOG(DEBUG) << "not enough extra currency to reserve";
|
||||
LOG(DEBUG) << "not enough extra currency to reserve: " << block::CurrencyCollection{0, reserve.extra}.to_str()
|
||||
<< " required, only " << block::CurrencyCollection{0, ap.remaining_balance.extra}.to_str()
|
||||
<< " available";
|
||||
if (mode & 2) {
|
||||
// TODO: process (mode & 2) correctly by setting res_extra := inf (reserve.extra, ap.remaining_balance.extra)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue