Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support extra currencies in reserve action with +2 flag #1429

Open
wants to merge 2 commits into
base: testnet
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions crypto/block/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()) &&
Expand Down
1 change: 1 addition & 0 deletions crypto/block/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
22 changes: 13 additions & 9 deletions crypto/block/transaction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
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;
Expand Down Expand Up @@ -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->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;
}
{
Expand Down
1 change: 1 addition & 0 deletions crypto/block/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion doc/GlobalVersions.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,5 @@ Operations for working with Merkle proofs, where cells can have non-zero level a
### Other changes
- 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.
- 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.
1 change: 1 addition & 0 deletions validator/impl/validate-query.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -997,6 +997,7 @@ bool ValidateQuery::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;
}
{
Expand Down
Loading