mirror of
https://github.com/ton-blockchain/ton
synced 2025-02-12 11:12:16 +00:00
Support extra currencies in reserve action with +2 flag (#1429)
* Support extra currencies in reserve action with +2 flag * Enable new reserve behavior in version 9
This commit is contained in:
parent
f6fa986b33
commit
62838571eb
6 changed files with 48 additions and 10 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 {
|
bool CurrencyCollection::operator==(const CurrencyCollection& other) const {
|
||||||
return is_valid() && other.is_valid() && !td::cmp(grams, other.grams) &&
|
return is_valid() && other.is_valid() && !td::cmp(grams, other.grams) &&
|
||||||
(extra.not_null() == other.extra.not_null()) &&
|
(extra.not_null() == other.extra.not_null()) &&
|
||||||
|
|
|
@ -390,6 +390,7 @@ struct CurrencyCollection {
|
||||||
CurrencyCollection operator-(const CurrencyCollection& other) const;
|
CurrencyCollection operator-(const CurrencyCollection& other) const;
|
||||||
CurrencyCollection operator-(CurrencyCollection&& other) const;
|
CurrencyCollection operator-(CurrencyCollection&& other) const;
|
||||||
CurrencyCollection operator-(td::RefInt256 other_grams) const;
|
CurrencyCollection operator-(td::RefInt256 other_grams) const;
|
||||||
|
bool clamp(const CurrencyCollection& other);
|
||||||
bool store(vm::CellBuilder& cb) const;
|
bool store(vm::CellBuilder& cb) const;
|
||||||
bool store_or_zero(vm::CellBuilder& cb) const;
|
bool store_or_zero(vm::CellBuilder& cb) const;
|
||||||
bool fetch(vm::CellSlice& cs);
|
bool fetch(vm::CellSlice& cs);
|
||||||
|
|
|
@ -2760,22 +2760,25 @@ int Transaction::try_action_reserve_currency(vm::CellSlice& cs, ActionPhase& ap,
|
||||||
LOG(DEBUG) << "cannot reserve a negative amount: " << reserve.to_str();
|
LOG(DEBUG) << "cannot reserve a negative amount: " << reserve.to_str();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (reserve.grams > ap.remaining_balance.grams) {
|
if (mode & 2) {
|
||||||
if (mode & 2) {
|
if (cfg.reserve_extra_enabled) {
|
||||||
reserve.grams = ap.remaining_balance.grams;
|
if (!reserve.clamp(ap.remaining_balance)) {
|
||||||
|
LOG(DEBUG) << "failed to clamp reserve amount" << mode;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG(DEBUG) << "cannot reserve " << reserve.grams << " nanograms : only " << ap.remaining_balance.grams
|
reserve.grams = std::min(reserve.grams, ap.remaining_balance.grams);
|
||||||
<< " available";
|
|
||||||
return 37; // not enough 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)) {
|
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()
|
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()
|
<< " required, only " << block::CurrencyCollection{0, ap.remaining_balance.extra}.to_str()
|
||||||
<< " available";
|
<< " 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
|
return 38; // not enough (extra) funds
|
||||||
}
|
}
|
||||||
newc.grams = ap.remaining_balance.grams - reserve.grams;
|
newc.grams = ap.remaining_balance.grams - reserve.grams;
|
||||||
|
@ -3778,6 +3781,7 @@ td::Status FetchConfigParams::fetch_config_params(
|
||||||
action_phase_cfg->bounce_on_fail_enabled = config.get_global_version() >= 4;
|
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->message_skip_enabled = config.get_global_version() >= 8;
|
||||||
action_phase_cfg->disable_custom_fess = 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;
|
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 bounce_on_fail_enabled{false};
|
||||||
bool message_skip_enabled{false};
|
bool message_skip_enabled{false};
|
||||||
bool disable_custom_fess{false};
|
bool disable_custom_fess{false};
|
||||||
|
bool reserve_extra_enabled{false};
|
||||||
td::optional<td::Bits256> mc_blackhole_addr;
|
td::optional<td::Bits256> mc_blackhole_addr;
|
||||||
const MsgPrices& fetch_msg_prices(bool is_masterchain) const {
|
const MsgPrices& fetch_msg_prices(bool is_masterchain) const {
|
||||||
return is_masterchain ? fwd_mc : fwd_std;
|
return is_masterchain ? fwd_mc : fwd_std;
|
||||||
|
|
|
@ -122,4 +122,5 @@ Operations for working with Merkle proofs, where cells can have non-zero level a
|
||||||
### Other changes
|
### Other changes
|
||||||
- Fix `RAWRESERVE` action with flag `4` (use original balance of the account) by explicitly setting `original_balance` to `balance - msg_balance_remaining`.
|
- Fix `RAWRESERVE` action with flag `4` (use original balance of the account) by explicitly setting `original_balance` to `balance - msg_balance_remaining`.
|
||||||
- Previously it did not work if storage fee was greater than the original balance.
|
- Previously it did not work if storage fee was greater than the original balance.
|
||||||
- Jumps to nested continuations of depth more than 8 consume 1 gas for eact subsequent continuation (this does not affect most of TVM code).
|
- Jumps to nested continuations of depth more than 8 consume 1 gas for eact subsequent continuation (this does not affect most of TVM code).
|
||||||
|
- Support extra currencies in reserve action with `+2` mode.
|
|
@ -1002,6 +1002,7 @@ bool ValidateQuery::fetch_config_params() {
|
||||||
action_phase_cfg_.bounce_on_fail_enabled = config_->get_global_version() >= 4;
|
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_.message_skip_enabled = config_->get_global_version() >= 8;
|
||||||
action_phase_cfg_.disable_custom_fess = 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;
|
action_phase_cfg_.mc_blackhole_addr = config_->get_burning_config().blackhole_addr;
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue