mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
Merge branch 'testnet' into tvm-v9
This commit is contained in:
commit
77e5a2f4a2
24 changed files with 169 additions and 76 deletions
|
@ -1319,6 +1319,36 @@ CurrencyCollection CurrencyCollection::operator-(td::RefInt256 other_grams) cons
|
|||
}
|
||||
}
|
||||
|
||||
bool CurrencyCollection::clamp(const CurrencyCollection& other) {
|
||||
if (!is_valid() || !other.is_valid()) {
|
||||
return invalidate();
|
||||
}
|
||||
grams = std::min(grams, other.grams);
|
||||
vm::Dictionary dict1{extra, 32}, dict2(other.extra, 32);
|
||||
bool ok = dict1.check_for_each([&](td::Ref<vm::CellSlice> cs1, td::ConstBitPtr key, int n) {
|
||||
CHECK(n == 32);
|
||||
td::Ref<vm::CellSlice> cs2 = dict2.lookup(key, 32);
|
||||
td::RefInt256 val1 = tlb::t_VarUIntegerPos_32.as_integer(cs1);
|
||||
if (val1.is_null()) {
|
||||
return false;
|
||||
}
|
||||
td::RefInt256 val2 = cs2.is_null() ? td::zero_refint() : tlb::t_VarUIntegerPos_32.as_integer(cs2);
|
||||
if (val2.is_null()) {
|
||||
return false;
|
||||
}
|
||||
if (val1 > val2) {
|
||||
if (val2->sgn() == 0) {
|
||||
dict1.lookup_delete(key, 32);
|
||||
} else {
|
||||
dict1.set(key, 32, cs2);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
extra = dict1.get_root_cell();
|
||||
return ok || invalidate();
|
||||
}
|
||||
|
||||
bool CurrencyCollection::operator==(const CurrencyCollection& other) const {
|
||||
return is_valid() && other.is_valid() && !td::cmp(grams, other.grams) &&
|
||||
(extra.not_null() == other.extra.not_null()) &&
|
||||
|
|
|
@ -390,6 +390,7 @@ struct CurrencyCollection {
|
|||
CurrencyCollection operator-(const CurrencyCollection& other) const;
|
||||
CurrencyCollection operator-(CurrencyCollection&& other) const;
|
||||
CurrencyCollection operator-(td::RefInt256 other_grams) const;
|
||||
bool clamp(const CurrencyCollection& other);
|
||||
bool store(vm::CellBuilder& cb) const;
|
||||
bool store_or_zero(vm::CellBuilder& cb) const;
|
||||
bool fetch(vm::CellSlice& cs);
|
||||
|
|
|
@ -296,7 +296,7 @@ transaction$0111 account_addr:bits256 lt:uint64
|
|||
total_fees:CurrencyCollection state_update:^(HASH_UPDATE Account)
|
||||
description:^TransactionDescr = Transaction;
|
||||
|
||||
!merkle_update#02 {X:Type} old_hash:bits256 new_hash:bits256
|
||||
!merkle_update#04 {X:Type} old_hash:bits256 new_hash:bits256 old_depth:uint16 new_depth:uint16
|
||||
old:^X new:^X = MERKLE_UPDATE X;
|
||||
update_hashes#72 {X:Type} old_hash:bits256 new_hash:bits256
|
||||
= HASH_UPDATE X;
|
||||
|
|
|
@ -2795,22 +2795,25 @@ int Transaction::try_action_reserve_currency(vm::CellSlice& cs, ActionPhase& ap,
|
|||
LOG(DEBUG) << "cannot reserve a negative amount: " << reserve.to_str();
|
||||
return -1;
|
||||
}
|
||||
if (reserve.grams > ap.remaining_balance.grams) {
|
||||
if (mode & 2) {
|
||||
reserve.grams = ap.remaining_balance.grams;
|
||||
if (mode & 2) {
|
||||
if (cfg.reserve_extra_enabled) {
|
||||
if (!reserve.clamp(ap.remaining_balance)) {
|
||||
LOG(DEBUG) << "failed to clamp reserve amount" << mode;
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
LOG(DEBUG) << "cannot reserve " << reserve.grams << " nanograms : only " << ap.remaining_balance.grams
|
||||
<< " available";
|
||||
return 37; // not enough grams
|
||||
reserve.grams = std::min(reserve.grams, ap.remaining_balance.grams);
|
||||
}
|
||||
}
|
||||
if (reserve.grams > ap.remaining_balance.grams) {
|
||||
LOG(DEBUG) << "cannot reserve " << reserve.grams << " nanograms : only " << ap.remaining_balance.grams
|
||||
<< " available";
|
||||
return 37; // not enough grams
|
||||
}
|
||||
if (!block::sub_extra_currency(ap.remaining_balance.extra, reserve.extra, newc.extra)) {
|
||||
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)
|
||||
}
|
||||
return 38; // not enough (extra) funds
|
||||
}
|
||||
newc.grams = ap.remaining_balance.grams - reserve.grams;
|
||||
|
@ -3813,6 +3816,7 @@ td::Status FetchConfigParams::fetch_config_params(
|
|||
action_phase_cfg->bounce_on_fail_enabled = config.get_global_version() >= 4;
|
||||
action_phase_cfg->message_skip_enabled = config.get_global_version() >= 8;
|
||||
action_phase_cfg->disable_custom_fess = config.get_global_version() >= 8;
|
||||
action_phase_cfg->reserve_extra_enabled = config.get_global_version() >= 9;
|
||||
action_phase_cfg->mc_blackhole_addr = config.get_burning_config().blackhole_addr;
|
||||
}
|
||||
{
|
||||
|
|
|
@ -169,6 +169,7 @@ struct ActionPhaseConfig {
|
|||
bool bounce_on_fail_enabled{false};
|
||||
bool message_skip_enabled{false};
|
||||
bool disable_custom_fess{false};
|
||||
bool reserve_extra_enabled{false};
|
||||
td::optional<td::Bits256> mc_blackhole_addr;
|
||||
const MsgPrices& fetch_msg_prices(bool is_masterchain) const {
|
||||
return is_masterchain ? fwd_mc : fwd_std;
|
||||
|
|
|
@ -149,16 +149,17 @@ td::Ref<vm::Tuple> prepare_vm_c7(SmartContract::Args args, td::Ref<vm::Cell> cod
|
|||
}
|
||||
|
||||
std::vector<vm::StackEntry> tuple = {
|
||||
td::make_refint(0x076ef1ea), // [ magic:0x076ef1ea
|
||||
td::make_refint(0), // actions:Integer
|
||||
td::make_refint(0), // msgs_sent:Integer
|
||||
td::make_refint(now), // unixtime:Integer
|
||||
td::make_refint(0), //TODO: // block_lt:Integer
|
||||
td::make_refint(0), //TODO: // trans_lt:Integer
|
||||
std::move(rand_seed_int), // rand_seed:Integer
|
||||
block::CurrencyCollection(args.balance).as_vm_tuple(), // balance_remaining:[Integer (Maybe Cell)]
|
||||
vm::load_cell_slice_ref(address), // myself:MsgAddressInt
|
||||
vm::StackEntry::maybe(config) // vm::StackEntry::maybe(td::Ref<vm::Cell>())
|
||||
td::make_refint(0x076ef1ea), // [ magic:0x076ef1ea
|
||||
td::make_refint(0), // actions:Integer
|
||||
td::make_refint(0), // msgs_sent:Integer
|
||||
td::make_refint(now), // unixtime:Integer
|
||||
td::make_refint(0), // block_lt:Integer (TODO)
|
||||
td::make_refint(0), // trans_lt:Integer (TODO)
|
||||
std::move(rand_seed_int), // rand_seed:Integer
|
||||
block::CurrencyCollection(args.balance, args.extra_currencies)
|
||||
.as_vm_tuple(), // balance_remaining:[Integer (Maybe Cell)]
|
||||
vm::load_cell_slice_ref(address), // myself:MsgAddressInt
|
||||
vm::StackEntry::maybe(config) // vm::StackEntry::maybe(td::Ref<vm::Cell>())
|
||||
};
|
||||
if (args.config && args.config.value()->get_global_version() >= 4) {
|
||||
tuple.push_back(vm::StackEntry::maybe(code)); // code:Cell
|
||||
|
|
|
@ -64,6 +64,7 @@ class SmartContract : public td::CntObject {
|
|||
bool ignore_chksig{false};
|
||||
td::uint64 amount{0};
|
||||
td::uint64 balance{0};
|
||||
td::Ref<vm::Cell> extra_currencies;
|
||||
int vm_log_verbosity_level{0};
|
||||
bool debug_enabled{false};
|
||||
|
||||
|
@ -121,6 +122,10 @@ class SmartContract : public td::CntObject {
|
|||
this->balance = balance;
|
||||
return std::move(*this);
|
||||
}
|
||||
Args&& set_extra_currencies(td::Ref<vm::Cell> extra_currencies) {
|
||||
this->extra_currencies = std::move(extra_currencies);
|
||||
return std::move(*this);
|
||||
}
|
||||
Args&& set_address(block::StdAddress address) {
|
||||
this->address = address;
|
||||
return std::move(*this);
|
||||
|
|
|
@ -2074,7 +2074,7 @@ void CppTypeCode::generate_skip_field(const Constructor& constr, const Field& fi
|
|||
output_cpp_expr(ss, expr, 100);
|
||||
ss << '.';
|
||||
}
|
||||
ss << "validate_skip_ref(ops, cs, weak)" << tail;
|
||||
ss << "validate_skip_ref(ops, cs, " << (constr.is_special ? "true" : "weak") << ")" << tail;
|
||||
actions += Action{ss.str()};
|
||||
}
|
||||
|
||||
|
|
|
@ -1800,9 +1800,6 @@ void Constructor::show(std::ostream& os, int mode) const {
|
|||
}
|
||||
for (int i = 0; i < type_arity; i++) {
|
||||
os << ' ';
|
||||
if (param_negated.at(i)) {
|
||||
os << '~';
|
||||
}
|
||||
params.at(i)->show(os, this, 100, mode | 1);
|
||||
}
|
||||
if (!(mode & 2)) {
|
||||
|
|
|
@ -133,7 +133,13 @@ bool TLB::validate_ref_internal(int* ops, Ref<vm::Cell> cell_ref, bool weak) con
|
|||
}
|
||||
bool is_special;
|
||||
auto cs = load_cell_slice_special(std::move(cell_ref), is_special);
|
||||
return always_special() ? is_special : (is_special ? weak : (validate_skip(ops, cs) && cs.empty_ext()));
|
||||
if (cs.special_type() == vm::Cell::SpecialType::PrunnedBranch && weak) {
|
||||
return true;
|
||||
}
|
||||
if (always_special() != is_special) {
|
||||
return false;
|
||||
}
|
||||
return validate_skip(ops, cs, weak) && cs.empty_ext();
|
||||
}
|
||||
|
||||
bool TLB::print_skip(PrettyPrinter& pp, vm::CellSlice& cs) const {
|
||||
|
|
|
@ -100,8 +100,18 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
|
|||
return get_cell_info_lazy(level_mask, hash, depth).cell;
|
||||
}
|
||||
td::Result<Ref<DataCell>> load_cell(td::Slice hash) override {
|
||||
TRY_RESULT(loaded_cell, get_cell_info_force(hash).cell->load_cell());
|
||||
return std::move(loaded_cell.data_cell);
|
||||
auto info = hash_table_.get_if_exists(hash);
|
||||
if (info && info->sync_with_db) {
|
||||
TRY_RESULT(loaded_cell, info->cell->load_cell());
|
||||
return std::move(loaded_cell.data_cell);
|
||||
}
|
||||
TRY_RESULT(res, loader_->load(hash, true, *this));
|
||||
if (res.status != CellLoader::LoadResult::Ok) {
|
||||
return td::Status::Error("cell not found");
|
||||
}
|
||||
Ref<DataCell> cell = res.cell();
|
||||
hash_table_.apply(hash, [&](CellInfo &info) { update_cell_info_loaded(info, hash, std::move(res)); });
|
||||
return cell;
|
||||
}
|
||||
td::Result<Ref<DataCell>> load_root(td::Slice hash) override {
|
||||
return load_cell(hash);
|
||||
|
@ -145,9 +155,6 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
|
|||
promise->set_result(std::move(cell));
|
||||
});
|
||||
}
|
||||
CellInfo &get_cell_info_force(td::Slice hash) {
|
||||
return hash_table_.apply(hash, [&](CellInfo &info) { update_cell_info_force(info, hash); });
|
||||
}
|
||||
CellInfo &get_cell_info_lazy(Cell::LevelMask level_mask, td::Slice hash, td::Slice depth) {
|
||||
return hash_table_.apply(hash.substr(hash.size() - Cell::hash_bytes),
|
||||
[&](CellInfo &info) { update_cell_info_lazy(info, level_mask, hash, depth); });
|
||||
|
|
|
@ -1301,7 +1301,7 @@ void register_ton_crypto_ops(OpcodeTable& cp0) {
|
|||
}
|
||||
|
||||
int exec_compute_data_size(VmState* st, int mode) {
|
||||
VM_LOG(st) << (mode & 2 ? 'S' : 'C') << "DATASIZE" << (mode & 1 ? "Q" : "");
|
||||
VM_LOG(st) << "execute " << (mode & 2 ? 'S' : 'C') << "DATASIZE" << (mode & 1 ? "Q" : "");
|
||||
Stack& stack = st->get_stack();
|
||||
stack.check_underflow(2);
|
||||
auto bound = stack.pop_int();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue