mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
updated tonlib, fixed bugs
updated tonlib fixed bugs in func validator: partial support for hardforks liteserver: support for waitMasterchainBlock prefix transactions: support for gas flat rate
This commit is contained in:
parent
841d5ebac2
commit
7ea00ebfcf
89 changed files with 1922 additions and 608 deletions
|
@ -1143,6 +1143,20 @@ bool TrStoragePhase::validate_skip(vm::CellSlice& cs, bool weak) const {
|
|||
&& t_AccStatusChange.validate_skip(cs, weak); // status_change:AccStatusChange
|
||||
}
|
||||
|
||||
bool TrStoragePhase::get_storage_fees(vm::CellSlice& cs, td::RefInt256& storage_fees) const {
|
||||
return t_Grams.as_integer_skip_to(cs, storage_fees); // storage_fees_collected:Grams
|
||||
}
|
||||
|
||||
bool TrStoragePhase::maybe_get_storage_fees(vm::CellSlice& cs, td::RefInt256& storage_fees) const {
|
||||
auto z = cs.fetch_ulong(1);
|
||||
if (!z) {
|
||||
storage_fees = td::make_refint(0);
|
||||
return true;
|
||||
} else {
|
||||
return z == 1 && get_storage_fees(cs, storage_fees);
|
||||
}
|
||||
}
|
||||
|
||||
const TrStoragePhase t_TrStoragePhase;
|
||||
|
||||
bool TrCreditPhase::skip(vm::CellSlice& cs) const {
|
||||
|
@ -1322,13 +1336,14 @@ bool TransactionDescr::skip(vm::CellSlice& cs) const {
|
|||
&& t_TrStoragePhase.skip(cs); // storage_ph:TrStoragePhase
|
||||
case trans_tick_tock:
|
||||
return cs.advance(4) // trans_tick_tock$001 is_tock:Bool
|
||||
&& t_TrStoragePhase.skip(cs) // storage:TrStoragePhase
|
||||
&& t_TrStoragePhase.skip(cs) // storage_ph:TrStoragePhase
|
||||
&& t_TrComputePhase.skip(cs) // compute_ph:TrComputePhase
|
||||
&& Maybe<RefTo<TrActionPhase>>{}.skip(cs) // action:(Maybe ^TrActionPhase)
|
||||
&& cs.advance(2); // aborted:Bool destroyed:Bool
|
||||
case trans_split_prepare:
|
||||
return cs.advance(4) // trans_split_prepare$0100
|
||||
&& t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo
|
||||
&& Maybe<TrStoragePhase>{}.skip(cs) // storage_ph:(Maybe TrStoragePhase)
|
||||
&& t_TrComputePhase.skip(cs) // compute_ph:TrComputePhase
|
||||
&& Maybe<RefTo<TrActionPhase>>{}.skip(cs) // action:(Maybe ^TrActionPhase)
|
||||
&& cs.advance(2); // aborted:Bool destroyed:Bool
|
||||
|
@ -1346,6 +1361,7 @@ bool TransactionDescr::skip(vm::CellSlice& cs) const {
|
|||
return cs.advance(4) // trans_merge_install$0111
|
||||
&& t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo
|
||||
&& t_Ref_Transaction.skip(cs) // prepare_transaction:^Transaction
|
||||
&& Maybe<TrStoragePhase>{}.skip(cs) // storage_ph:(Maybe TrStoragePhase)
|
||||
&& Maybe<TrCreditPhase>{}.skip(cs) // credit_ph:(Maybe TrCreditPhase)
|
||||
&& Maybe<TrComputePhase>{}.skip(cs) // compute_ph:TrComputePhase
|
||||
&& Maybe<RefTo<TrActionPhase>>{}.skip(cs) // action:(Maybe ^TrActionPhase)
|
||||
|
@ -1370,13 +1386,14 @@ bool TransactionDescr::validate_skip(vm::CellSlice& cs, bool weak) const {
|
|||
&& t_TrStoragePhase.validate_skip(cs, weak); // storage_ph:TrStoragePhase
|
||||
case trans_tick_tock:
|
||||
return cs.advance(4) // trans_tick_tock$001 is_tock:Bool
|
||||
&& t_TrStoragePhase.validate_skip(cs, weak) // storage:TrStoragePhase
|
||||
&& t_TrStoragePhase.validate_skip(cs, weak) // storage_ph:TrStoragePhase
|
||||
&& t_TrComputePhase.validate_skip(cs, weak) // compute_ph:TrComputePhase
|
||||
&& Maybe<RefTo<TrActionPhase>>{}.validate_skip(cs, weak) // action:(Maybe ^TrActionPhase)
|
||||
&& cs.advance(2); // aborted:Bool destroyed:Bool
|
||||
case trans_split_prepare:
|
||||
return cs.advance(4) // trans_split_prepare$0100
|
||||
&& t_SplitMergeInfo.validate_skip(cs, weak) // split_info:SplitMergeInfo
|
||||
&& Maybe<TrStoragePhase>{}.validate_skip(cs, weak) // storage_ph:(Maybe TrStoragePhase)
|
||||
&& t_TrComputePhase.validate_skip(cs, weak) // compute_ph:TrComputePhase
|
||||
&& Maybe<RefTo<TrActionPhase>>{}.validate_skip(cs, weak) // action:(Maybe ^TrActionPhase)
|
||||
&& cs.advance(2); // aborted:Bool destroyed:Bool
|
||||
|
@ -1394,6 +1411,7 @@ bool TransactionDescr::validate_skip(vm::CellSlice& cs, bool weak) const {
|
|||
return cs.advance(4) // trans_merge_install$0111
|
||||
&& t_SplitMergeInfo.validate_skip(cs, weak) // split_info:SplitMergeInfo
|
||||
&& t_Ref_Transaction.validate_skip(cs, weak) // prepare_transaction:^Transaction
|
||||
&& Maybe<TrStoragePhase>{}.validate_skip(cs, weak) // storage_ph:(Maybe TrStoragePhase)
|
||||
&& Maybe<TrCreditPhase>{}.validate_skip(cs, weak) // credit_ph:(Maybe TrCreditPhase)
|
||||
&& Maybe<TrComputePhase>{}.validate_skip(cs, weak) // compute_ph:TrComputePhase
|
||||
&& Maybe<RefTo<TrActionPhase>>{}.validate_skip(cs, weak) // action:(Maybe ^TrActionPhase)
|
||||
|
@ -1407,6 +1425,53 @@ int TransactionDescr::get_tag(const vm::CellSlice& cs) const {
|
|||
return (t >= 0 && t <= 7) ? (t == 3 ? 2 : t) : -1;
|
||||
}
|
||||
|
||||
bool TransactionDescr::skip_to_storage_phase(vm::CellSlice& cs, bool& found) const {
|
||||
found = false;
|
||||
switch (get_tag(cs)) {
|
||||
case trans_ord:
|
||||
return cs.advance(4 + 1) // trans_ord$0000 storage_first:Bool
|
||||
&& cs.fetch_bool_to(found); // storage_ph:(Maybe TrStoragePhase)
|
||||
case trans_storage:
|
||||
return cs.advance(4) // trans_storage$0001
|
||||
&& (found = true); // storage_ph:TrStoragePhase
|
||||
case trans_tick_tock:
|
||||
return cs.advance(4) // trans_tick_tock$001 is_tock:Bool
|
||||
&& (found = true); // storage_ph:TrStoragePhase
|
||||
case trans_split_prepare:
|
||||
return cs.advance(4) // trans_split_prepare$0100
|
||||
&& t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo
|
||||
&& cs.fetch_bool_to(found); // storage_ph:(Maybe TrStoragePhase)
|
||||
case trans_split_install:
|
||||
return true;
|
||||
case trans_merge_prepare:
|
||||
return cs.advance(4) // trans_merge_prepare$0110
|
||||
&& t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo
|
||||
&& (found = true); // storage_ph:TrStoragePhase
|
||||
case trans_merge_install:
|
||||
return cs.advance(4) // trans_merge_install$0111
|
||||
&& t_SplitMergeInfo.skip(cs) // split_info:SplitMergeInfo
|
||||
&& t_Ref_Transaction.skip(cs) // prepare_transaction:^Transaction
|
||||
&& cs.fetch_bool_to(found); // storage_ph:(Maybe TrStoragePhase)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TransactionDescr::get_storage_fees(Ref<vm::Cell> cell, td::RefInt256& storage_fees) const {
|
||||
if (cell.is_null()) {
|
||||
return false;
|
||||
}
|
||||
auto cs = vm::load_cell_slice(std::move(cell));
|
||||
bool found;
|
||||
if (!skip_to_storage_phase(cs, found)) {
|
||||
return false;
|
||||
} else if (found) {
|
||||
return t_TrStoragePhase.get_storage_fees(cs, storage_fees);
|
||||
} else {
|
||||
storage_fees = td::make_refint(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
const TransactionDescr t_TransactionDescr;
|
||||
|
||||
bool Transaction_aux::skip(vm::CellSlice& cs) const {
|
||||
|
@ -1447,6 +1512,32 @@ bool Transaction::validate_skip(vm::CellSlice& cs, bool weak) const {
|
|||
&& RefTo<TransactionDescr>{}.validate_skip(cs, weak); // description:^TransactionDescr
|
||||
}
|
||||
|
||||
bool Transaction::get_storage_fees(Ref<vm::Cell> cell, td::RefInt256& storage_fees) const {
|
||||
Ref<vm::Cell> tdescr;
|
||||
return get_descr(std::move(cell), tdescr) && t_TransactionDescr.get_storage_fees(std::move(tdescr), storage_fees);
|
||||
}
|
||||
|
||||
bool Transaction::get_descr(Ref<vm::Cell> cell, Ref<vm::Cell>& tdescr) const {
|
||||
if (cell.is_null()) {
|
||||
return false;
|
||||
} else {
|
||||
auto cs = vm::load_cell_slice(std::move(cell));
|
||||
return cs.is_valid() && get_descr(cs, tdescr) && cs.empty_ext();
|
||||
}
|
||||
}
|
||||
|
||||
bool Transaction::get_descr(vm::CellSlice& cs, Ref<vm::Cell>& tdescr) const {
|
||||
return cs.advance(
|
||||
4 + 256 + 64 + 256 + 64 + 32 +
|
||||
15) // transaction$0111 account_addr:uint256 lt:uint64 prev_trans_hash:bits256 prev_trans_lt:uint64 now:uint32 outmsg_cnt:uint15
|
||||
&& t_AccountStatus.skip(cs) // orig_status:AccountStatus
|
||||
&& t_AccountStatus.skip(cs) // end_status:AccountStatus
|
||||
&& cs.advance_refs(1) // ^[ in_msg:(Maybe ^Message) out_msgs:(HashmapE 15 ^Message) ]
|
||||
&& t_CurrencyCollection.skip(cs) // total_fees:CurrencyCollection
|
||||
&& cs.advance_refs(1) // state_update:^(MERKLE_UPDATE Account)
|
||||
&& cs.fetch_ref_to(tdescr); // description:^TransactionDescr
|
||||
}
|
||||
|
||||
bool Transaction::get_total_fees(vm::CellSlice&& cs, block::CurrencyCollection& total_fees) const {
|
||||
return cs.is_valid() && cs.fetch_ulong(4) == 7 // transaction$0111
|
||||
&&
|
||||
|
|
|
@ -614,6 +614,8 @@ extern const AccStatusChange t_AccStatusChange;
|
|||
struct TrStoragePhase final : TLB_Complex {
|
||||
bool skip(vm::CellSlice& cs) const override;
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override;
|
||||
bool get_storage_fees(vm::CellSlice& cs, td::RefInt256& storage_fees) const;
|
||||
bool maybe_get_storage_fees(vm::CellSlice& cs, td::RefInt256& storage_fees) const;
|
||||
};
|
||||
|
||||
extern const TrStoragePhase t_TrStoragePhase;
|
||||
|
@ -693,6 +695,8 @@ struct TransactionDescr final : TLB_Complex {
|
|||
bool skip(vm::CellSlice& cs) const override;
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override;
|
||||
int get_tag(const vm::CellSlice& cs) const override;
|
||||
bool skip_to_storage_phase(vm::CellSlice& cs, bool& found) const;
|
||||
bool get_storage_fees(Ref<vm::Cell> cell, td::RefInt256& storage_fees) const;
|
||||
};
|
||||
|
||||
extern const TransactionDescr t_TransactionDescr;
|
||||
|
@ -708,6 +712,9 @@ struct Transaction final : TLB_Complex {
|
|||
bool skip(vm::CellSlice& cs) const override;
|
||||
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override;
|
||||
bool get_total_fees(vm::CellSlice&& cs, block::CurrencyCollection& total_fees) const;
|
||||
bool get_descr(Ref<vm::Cell> cell, Ref<vm::Cell>& tdescr) const;
|
||||
bool get_descr(vm::CellSlice& cs, Ref<vm::Cell>& tdescr) const;
|
||||
bool get_storage_fees(Ref<vm::Cell> cell, td::RefInt256& storage_fees) const;
|
||||
};
|
||||
|
||||
extern const Transaction t_Transaction;
|
||||
|
|
|
@ -325,7 +325,7 @@ trans_ord$0000 credit_first:Bool
|
|||
trans_storage$0001 storage_ph:TrStoragePhase
|
||||
= TransactionDescr;
|
||||
|
||||
trans_tick_tock$001 is_tock:Bool storage:TrStoragePhase
|
||||
trans_tick_tock$001 is_tock:Bool storage_ph:TrStoragePhase
|
||||
compute_ph:TrComputePhase action:(Maybe ^TrActionPhase)
|
||||
aborted:Bool destroyed:Bool = TransactionDescr;
|
||||
//
|
||||
|
@ -333,6 +333,7 @@ split_merge_info$_ cur_shard_pfx_len:(## 6)
|
|||
acc_split_depth:(## 6) this_addr:bits256 sibling_addr:bits256
|
||||
= SplitMergeInfo;
|
||||
trans_split_prepare$0100 split_info:SplitMergeInfo
|
||||
storage_ph:(Maybe TrStoragePhase)
|
||||
compute_ph:TrComputePhase action:(Maybe ^TrActionPhase)
|
||||
aborted:Bool destroyed:Bool
|
||||
= TransactionDescr;
|
||||
|
@ -345,6 +346,7 @@ trans_merge_prepare$0110 split_info:SplitMergeInfo
|
|||
= TransactionDescr;
|
||||
trans_merge_install$0111 split_info:SplitMergeInfo
|
||||
prepare_transaction:^Transaction
|
||||
storage_ph:(Maybe TrStoragePhase)
|
||||
credit_ph:(Maybe TrCreditPhase)
|
||||
compute_ph:TrComputePhase action:(Maybe ^TrActionPhase)
|
||||
aborted:Bool destroyed:Bool
|
||||
|
@ -609,6 +611,9 @@ gas_prices_ext#de gas_price:uint64 gas_limit:uint64 special_gas_limit:uint64 gas
|
|||
block_gas_limit:uint64 freeze_due_limit:uint64 delete_due_limit:uint64
|
||||
= GasLimitsPrices;
|
||||
|
||||
gas_flat_pfx#d1 flat_gas_limit:uint64 flat_gas_price:uint64 other:GasLimitsPrices
|
||||
= GasLimitsPrices;
|
||||
|
||||
config_mc_gas_prices#_ GasLimitsPrices = ConfigParam 20;
|
||||
config_gas_prices#_ GasLimitsPrices = ConfigParam 21;
|
||||
|
||||
|
|
|
@ -672,9 +672,56 @@ bool Transaction::prepare_credit_phase() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ComputePhaseConfig::parse_GasLimitsPrices(Ref<vm::Cell> cell, td::RefInt256& freeze_due_limit,
|
||||
td::RefInt256& delete_due_limit) {
|
||||
return cell.not_null() &&
|
||||
parse_GasLimitsPrices(vm::load_cell_slice_ref(std::move(cell)), freeze_due_limit, delete_due_limit);
|
||||
}
|
||||
|
||||
bool ComputePhaseConfig::parse_GasLimitsPrices(Ref<vm::CellSlice> cs, td::RefInt256& freeze_due_limit,
|
||||
td::RefInt256& delete_due_limit) {
|
||||
if (cs.is_null()) {
|
||||
return false;
|
||||
}
|
||||
block::gen::GasLimitsPrices::Record_gas_flat_pfx flat;
|
||||
if (tlb::csr_unpack(cs, flat)) {
|
||||
bool ok = parse_GasLimitsPrices(std::move(flat.other), freeze_due_limit, delete_due_limit);
|
||||
flat_gas_limit = flat.flat_gas_limit;
|
||||
flat_gas_price = flat.flat_gas_price;
|
||||
return ok;
|
||||
}
|
||||
flat_gas_limit = flat_gas_price = 0;
|
||||
auto f = [&](const auto& r, td::uint64 spec_limit) {
|
||||
gas_limit = r.gas_limit;
|
||||
special_gas_limit = spec_limit;
|
||||
gas_credit = r.gas_credit;
|
||||
gas_price = r.gas_price;
|
||||
freeze_due_limit = td::RefInt256{true, r.freeze_due_limit};
|
||||
delete_due_limit = td::RefInt256{true, r.delete_due_limit};
|
||||
};
|
||||
block::gen::GasLimitsPrices::Record_gas_prices_ext rec;
|
||||
if (tlb::csr_unpack(cs, rec)) {
|
||||
f(rec, rec.special_gas_limit);
|
||||
} else {
|
||||
block::gen::GasLimitsPrices::Record_gas_prices rec0;
|
||||
if (tlb::csr_unpack(std::move(cs), rec0)) {
|
||||
f(rec0, rec0.gas_limit);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
compute_threshold();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ComputePhaseConfig::compute_threshold() {
|
||||
gas_price256 = td::RefInt256{true, gas_price};
|
||||
max_gas_threshold = td::rshift(gas_price256 * gas_limit, 16, 1);
|
||||
if (gas_limit > flat_gas_limit) {
|
||||
max_gas_threshold =
|
||||
td::rshift(gas_price256 * (gas_limit - flat_gas_limit), 16, 1) + td::make_refint(flat_gas_price);
|
||||
} else {
|
||||
max_gas_threshold = td::make_refint(flat_gas_price);
|
||||
}
|
||||
}
|
||||
|
||||
td::uint64 ComputePhaseConfig::gas_bought_for(td::RefInt256 nanograms) const {
|
||||
|
@ -684,8 +731,11 @@ td::uint64 ComputePhaseConfig::gas_bought_for(td::RefInt256 nanograms) const {
|
|||
if (nanograms >= max_gas_threshold) {
|
||||
return gas_limit;
|
||||
}
|
||||
auto res = td::div(std::move(nanograms) << 16, gas_price256);
|
||||
return res->to_long();
|
||||
if (nanograms < flat_gas_price) {
|
||||
return 0;
|
||||
}
|
||||
auto res = td::div((std::move(nanograms) - flat_gas_price) << 16, gas_price256);
|
||||
return res->to_long() + flat_gas_limit;
|
||||
}
|
||||
|
||||
td::RefInt256 ComputePhaseConfig::compute_gas_price(td::uint64 gas_used) const {
|
||||
|
@ -855,6 +905,16 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
|
|||
cp.skip_reason = ComputePhase::sk_no_gas;
|
||||
return true;
|
||||
}
|
||||
// Compute gas limits
|
||||
if (!compute_gas_limits(cp, cfg)) {
|
||||
compute_phase.reset();
|
||||
return false;
|
||||
}
|
||||
if (!cp.gas_limit && !cp.gas_credit) {
|
||||
// no gas
|
||||
cp.skip_reason = ComputePhase::sk_no_gas;
|
||||
return true;
|
||||
}
|
||||
if (in_msg_state.not_null()) {
|
||||
LOG(DEBUG) << "HASH(in_msg_state) = " << in_msg_state->get_hash().bits().to_hex(256)
|
||||
<< ", account_state_hash = " << account.state_hash.to_hex();
|
||||
|
@ -883,11 +943,6 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) {
|
|||
} else if (in_msg_state.not_null()) {
|
||||
unpack_msg_state(true); // use only libraries
|
||||
}
|
||||
// Compute gas limits
|
||||
if (!compute_gas_limits(cp, cfg)) {
|
||||
compute_phase.reset();
|
||||
return false;
|
||||
}
|
||||
// initialize VM
|
||||
Ref<vm::Stack> stack = prepare_vm_stack(cp);
|
||||
if (stack.is_null()) {
|
||||
|
|
|
@ -98,6 +98,8 @@ struct ComputePhaseConfig {
|
|||
td::uint64 gas_limit;
|
||||
td::uint64 special_gas_limit;
|
||||
td::uint64 gas_credit;
|
||||
td::uint64 flat_gas_limit = 0;
|
||||
td::uint64 flat_gas_price = 0;
|
||||
static constexpr td::uint64 gas_infty = (1ULL << 63) - 1;
|
||||
td::RefInt256 gas_price256;
|
||||
td::RefInt256 max_gas_threshold;
|
||||
|
@ -126,6 +128,8 @@ struct ComputePhaseConfig {
|
|||
Ref<vm::Cell> get_lib_root() const {
|
||||
return libraries ? libraries->get_root_cell() : Ref<vm::Cell>{};
|
||||
}
|
||||
bool parse_GasLimitsPrices(Ref<vm::CellSlice> cs, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit);
|
||||
bool parse_GasLimitsPrices(Ref<vm::Cell> cell, td::RefInt256& freeze_due_limit, td::RefInt256& delete_due_limit);
|
||||
};
|
||||
|
||||
// msg_fwd_fees = (lump_price + ceil((bit_price * msg.bits + cell_price * msg.cells)/2^16)) nanograms
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue