1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

updated vm (breaking compatibility)

- updated vm
- new actor scheduler
- updated tonlib
- updated DNS smartcontract
This commit is contained in:
ton 2020-02-28 14:28:47 +04:00
parent 9e4816e7f6
commit e27fb1e09c
100 changed files with 3692 additions and 1299 deletions

View file

@ -30,6 +30,7 @@ struct PrettyPrinter;
class TLB {
public:
enum { default_validate_max_cells = 1024 };
virtual ~TLB() = default;
virtual int get_size(const vm::CellSlice& cs) const {
return -1;
@ -37,14 +38,26 @@ class TLB {
virtual bool skip(vm::CellSlice& cs) const {
return cs.skip_ext(get_size(cs));
}
virtual bool validate(const vm::CellSlice& cs, bool weak = false) const {
virtual bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const {
return cs.have_ext(get_size(cs));
}
virtual bool validate_exact(const vm::CellSlice& cs, bool weak = false) const {
virtual bool validate_exact(int* ops, const vm::CellSlice& cs, bool weak = false) const {
return (int)cs.size_ext() == get_size(cs);
}
bool validate_upto(int ops, const vm::CellSlice& cs, bool weak = false) const {
return validate(&ops, cs, weak);
}
bool validate_exact_upto(int ops, const vm::CellSlice& cs, bool weak = false) const {
return validate_exact(&ops, cs, weak);
}
bool validate_csr(int* ops, Ref<vm::CellSlice> cs_ref, bool weak = false) const {
return cs_ref.not_null() && validate_skip_exact(ops, cs_ref.write(), weak);
}
bool validate_csr(int ops, Ref<vm::CellSlice> cs_ref, bool weak = false) const {
return validate_csr(&ops, std::move(cs_ref), weak);
}
bool validate_csr(Ref<vm::CellSlice> cs_ref, bool weak = false) const {
return cs_ref.not_null() && validate_skip_exact(cs_ref.write(), weak);
return validate_csr(default_validate_max_cells, std::move(cs_ref), weak);
}
Ref<vm::CellSlice> fetch(vm::CellSlice& cs) const {
return cs.fetch_subslice_ext(get_size(cs));
@ -52,67 +65,71 @@ class TLB {
Ref<vm::CellSlice> prefetch(const vm::CellSlice& cs) const {
return cs.prefetch_subslice_ext(get_size(cs));
}
virtual Ref<vm::CellSlice> validate_fetch(vm::CellSlice& cs, bool weak = false) const {
return validate(cs, weak) ? cs.fetch_subslice_ext(get_size(cs)) : Ref<vm::CellSlice>{};
virtual Ref<vm::CellSlice> validate_fetch(int* ops, vm::CellSlice& cs, bool weak = false) const {
return validate(ops, cs, weak) ? cs.fetch_subslice_ext(get_size(cs)) : Ref<vm::CellSlice>{};
}
virtual Ref<vm::CellSlice> validate_prefetch(const vm::CellSlice& cs, bool weak = false) const {
return validate(cs, weak) ? cs.prefetch_subslice_ext(get_size(cs)) : Ref<vm::CellSlice>{};
virtual Ref<vm::CellSlice> validate_prefetch(int* ops, const vm::CellSlice& cs, bool weak = false) const {
return validate(ops, cs, weak) ? cs.prefetch_subslice_ext(get_size(cs)) : Ref<vm::CellSlice>{};
}
bool fetch_to(vm::CellSlice& cs, Ref<vm::CellSlice>& res) const {
return (res = fetch(cs)).not_null();
}
bool validate_fetch_to(vm::CellSlice& cs, Ref<vm::CellSlice>& res, bool weak = false) const {
return (res = validate_fetch(cs, weak)).not_null();
bool validate_fetch_to(int* ops, vm::CellSlice& cs, Ref<vm::CellSlice>& res, bool weak = false) const {
return (res = validate_fetch(ops, cs, weak)).not_null();
}
bool store_from(vm::CellBuilder& cb, Ref<vm::CellSlice> field) const {
return field.not_null() && get_size(*field) == (int)field->size_ext() && cb.append_cellslice_bool(std::move(field));
}
bool validate_store_from(vm::CellBuilder& cb, Ref<vm::CellSlice> field, bool weak = false) const {
bool validate_store_from(int* ops, vm::CellBuilder& cb, Ref<vm::CellSlice> field, bool weak = false) const {
if (field.is_null()) {
return false;
}
vm::CellSlice cs{*field};
return validate_skip(cs, weak) && cs.empty_ext() && cb.append_cellslice_bool(std::move(field));
return validate_skip(ops, cs, weak) && cs.empty_ext() && cb.append_cellslice_bool(std::move(field));
}
virtual bool extract(vm::CellSlice& cs) const {
return cs.only_ext(get_size(cs));
}
virtual bool validate_extract(vm::CellSlice& cs, bool weak = false) const {
return validate(cs, weak) && extract(cs);
virtual bool validate_extract(int* ops, vm::CellSlice& cs, bool weak = false) const {
return validate(ops, cs, weak) && extract(cs);
}
int get_size_by_skip(const vm::CellSlice& cs) const {
vm::CellSlice copy{cs};
return skip(copy) ? copy.subtract_base_ext(cs) : -1;
}
virtual bool validate_skip(vm::CellSlice& cs, bool weak = false) const {
return validate(cs, weak) && skip(cs);
virtual bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const {
return validate(ops, cs, weak) && skip(cs);
}
bool validate_skip_exact(vm::CellSlice& cs, bool weak = false) const {
return validate_skip(cs, weak) && cs.empty_ext();
bool validate_skip_upto(int ops, vm::CellSlice& cs, bool weak = false) const {
return validate_skip(&ops, cs, weak);
}
bool validate_by_skip(const vm::CellSlice& cs, bool weak = false) const {
bool validate_skip_exact(int* ops, vm::CellSlice& cs, bool weak = false) const {
return validate_skip(ops, cs, weak) && cs.empty_ext();
}
bool validate_by_skip(int* ops, const vm::CellSlice& cs, bool weak = false) const {
vm::CellSlice copy{cs};
return validate_skip(copy, weak);
return validate_skip(ops, copy, weak);
}
bool validate_by_skip_exact(const vm::CellSlice& cs, bool weak = false) const {
bool validate_by_skip_exact(int* ops, const vm::CellSlice& cs, bool weak = false) const {
vm::CellSlice copy{cs};
return validate_skip_exact(copy, weak);
return validate_skip_exact(ops, copy, weak);
}
bool extract_by_skip(vm::CellSlice& cs) const {
vm::CellSlice copy{cs};
return skip(copy) && cs.cut_tail(copy);
}
bool validate_extract_by_skip(vm::CellSlice& cs, bool weak = false) const {
bool validate_extract_by_skip(int* ops, vm::CellSlice& cs, bool weak = false) const {
vm::CellSlice copy{cs};
return validate_skip(copy, weak) && cs.cut_tail(copy);
return validate_skip(ops, copy, weak) && cs.cut_tail(copy);
}
Ref<vm::CellSlice> validate_fetch_by_skip(vm::CellSlice& cs, bool weak = false) const {
Ref<vm::CellSlice> validate_fetch_by_skip(int* ops, vm::CellSlice& cs, bool weak = false) const {
Ref<vm::CellSlice> copy{true, cs};
return validate_skip(cs, weak) && copy.unique_write().cut_tail(cs) ? copy : Ref<vm::CellSlice>{};
return validate_skip(ops, cs, weak) && copy.unique_write().cut_tail(cs) ? copy : Ref<vm::CellSlice>{};
}
Ref<vm::CellSlice> validate_prefetch_by_skip(const vm::CellSlice& cs, bool weak = false) const {
Ref<vm::CellSlice> validate_prefetch_by_skip(int* ops, const vm::CellSlice& cs, bool weak = false) const {
vm::CellSlice copy{cs};
return validate_skip(copy, false) ? cs.prefetch_subslice_ext(copy.subtract_base_ext(cs)) : Ref<vm::CellSlice>{};
return validate_skip(ops, copy, false) ? cs.prefetch_subslice_ext(copy.subtract_base_ext(cs))
: Ref<vm::CellSlice>{};
}
virtual bool skip_copy(vm::CellBuilder& cb, vm::CellSlice& cs) const {
return cb.append_cellslice_bool(fetch(cs));
@ -156,14 +173,29 @@ class TLB {
bool as_integer_to(Ref<vm::CellSlice> cs_ref, td::RefInt256& res) const {
return (res = as_integer(std::move(cs_ref))).not_null();
}
bool validate_ref(int* ops, Ref<vm::Cell> cell_ref, bool weak = false) const {
return cell_ref.not_null() && validate_ref_internal(ops, std::move(cell_ref), weak);
}
bool validate_ref(int ops, Ref<vm::Cell> cell_ref, bool weak = false) const {
return validate_ref(&ops, std::move(cell_ref), weak);
}
bool validate_ref(Ref<vm::Cell> cell_ref, bool weak = false) const {
return cell_ref.not_null() && validate_ref_internal(std::move(cell_ref), weak);
return validate_ref(default_validate_max_cells, std::move(cell_ref), weak);
}
bool force_validate_ref(int* ops, Ref<vm::Cell> cell_ref) const {
return cell_ref.not_null() && validate_ref_internal(ops, std::move(cell_ref), false);
}
bool force_validate_ref(int ops, Ref<vm::Cell> cell_ref) const {
return force_validate_ref(&ops, std::move(cell_ref));
}
bool force_validate_ref(Ref<vm::Cell> cell_ref) const {
return cell_ref.not_null() && validate_ref_internal(std::move(cell_ref), false);
return force_validate_ref(default_validate_max_cells, std::move(cell_ref));
}
bool validate_skip_ref(vm::CellSlice& cs, bool weak = false) const {
return validate_ref(cs.fetch_ref(), weak);
bool validate_skip_ref(int* ops, vm::CellSlice& cs, bool weak = false) const {
return validate_ref(ops, cs.fetch_ref(), weak);
}
bool validate_skip_ref(int ops, vm::CellSlice& cs, bool weak = false) const {
return validate_skip_ref(&ops, cs, weak);
}
virtual bool null_value(vm::CellBuilder& cb) const {
return false;
@ -214,6 +246,9 @@ class TLB {
return print(os, *cs_ref, indent, rec_limit);
}
bool print_ref(std::ostream& os, Ref<vm::Cell> cell_ref, int indent = 0, int rec_limit = 0) const;
bool print_ref(int rec_limit, std::ostream& os, Ref<vm::Cell> cell_ref, int indent = 0) const {
return print_ref(os, std::move(cell_ref), indent, rec_limit);
}
std::string as_string_skip(vm::CellSlice& cs, int indent = 0) const;
std::string as_string(const vm::CellSlice& cs, int indent = 0) const;
std::string as_string(Ref<vm::CellSlice> cs_ref, int indent = 0) const {
@ -225,7 +260,7 @@ class TLB {
}
protected:
bool validate_ref_internal(Ref<vm::Cell> cell_ref, bool weak = false) const;
bool validate_ref_internal(int* ops, Ref<vm::Cell> cell_ref, bool weak = false) const;
};
static inline std::ostream& operator<<(std::ostream& os, const TLB& type) {
@ -234,29 +269,29 @@ static inline std::ostream& operator<<(std::ostream& os, const TLB& type) {
struct TLB_Complex : TLB {
bool skip(vm::CellSlice& cs) const override {
return validate_skip(cs);
return validate_skip(nullptr, cs);
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override = 0;
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override = 0;
int get_size(const vm::CellSlice& cs) const override {
return get_size_by_skip(cs);
}
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
return validate_by_skip(cs, weak);
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return validate_by_skip(ops, cs, weak);
}
bool validate_exact(const vm::CellSlice& cs, bool weak = false) const override {
return validate_by_skip_exact(cs, weak);
bool validate_exact(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return validate_by_skip_exact(ops, cs, weak);
}
bool extract(vm::CellSlice& cs) const override {
return extract_by_skip(cs);
}
bool validate_extract(vm::CellSlice& cs, bool weak = false) const override {
return validate_extract_by_skip(cs, weak);
bool validate_extract(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return validate_extract_by_skip(ops, cs, weak);
}
Ref<vm::CellSlice> validate_fetch(vm::CellSlice& cs, bool weak = false) const override {
return validate_fetch_by_skip(cs, weak);
Ref<vm::CellSlice> validate_fetch(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return validate_fetch_by_skip(ops, cs, weak);
}
Ref<vm::CellSlice> validate_prefetch(const vm::CellSlice& cs, bool weak = false) const override {
return validate_prefetch_by_skip(cs, weak);
Ref<vm::CellSlice> validate_prefetch(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return validate_prefetch_by_skip(ops, cs, weak);
}
td::RefInt256 as_integer(const vm::CellSlice& cs) const override {
vm::CellSlice copy{cs};
@ -615,23 +650,23 @@ struct FwdT final : TLB {
bool skip(vm::CellSlice& cs) const override {
return X.skip(cs);
}
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
return X.validate(cs, weak);
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return X.validate(ops, cs, weak);
}
Ref<vm::CellSlice> validate_fetch(vm::CellSlice& cs, bool weak = false) const override {
return X.validate_fetch(cs, weak);
Ref<vm::CellSlice> validate_fetch(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return X.validate_fetch(ops, cs, weak);
}
Ref<vm::CellSlice> validate_prefetch(const vm::CellSlice& cs, bool weak = false) const override {
return X.validate_prefetch(cs, weak);
Ref<vm::CellSlice> validate_prefetch(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return X.validate_prefetch(ops, cs, weak);
}
bool extract(vm::CellSlice& cs) const override {
return X.extract(cs);
}
bool validate_extract(vm::CellSlice& cs, bool weak = false) const override {
return X.validate_extract(cs, weak);
bool validate_extract(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return X.validate_extract(ops, cs, weak);
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
return X.validate_skip(cs, weak);
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return X.validate_skip(ops, cs, weak);
}
bool skip_copy(vm::CellBuilder& cb, vm::CellSlice& cs) const override {
return X.skip_copy(cb, cs);
@ -726,10 +761,10 @@ struct NatLess final : TLB {
int get_size(const vm::CellSlice& cs) const override {
return n >= 0 ? w : -1;
}
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return n >= 0 && (unsigned)cs.prefetch_ulong(w) <= (unsigned)n;
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return n >= 0 && (unsigned)cs.fetch_ulong(w) <= (unsigned)n;
}
unsigned long long as_uint(const vm::CellSlice& cs) const override {
@ -749,10 +784,10 @@ struct NatLeq final : TLB {
int get_size(const vm::CellSlice& cs) const override {
return n >= 0 ? w : -1;
}
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return n >= 0 && (unsigned)cs.prefetch_ulong(w) <= (unsigned)n;
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return n >= 0 && (unsigned)cs.fetch_ulong(w) <= (unsigned)n;
}
unsigned long long as_uint(const vm::CellSlice& cs) const override {
@ -771,7 +806,7 @@ struct TupleT final : TLB_Complex {
TupleT(int _n, const TLB& _X) : n(_n), X(_X) {
}
bool skip(vm::CellSlice& cs) const override;
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override;
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override;
int get_tag(const vm::CellSlice& cs) const override {
return 0;
}
@ -786,8 +821,8 @@ struct CondT final : TLB_Complex {
bool skip(vm::CellSlice& cs) const override {
return !n || X.skip(cs);
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
return !n || (n > 0 && X.validate_skip(cs, weak));
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return !n || (n > 0 && X.validate_skip(ops, cs, weak));
}
int get_tag(const vm::CellSlice& cs) const override {
return 0;
@ -808,8 +843,8 @@ struct Cond final : TLB_Complex {
bool skip(vm::CellSlice& cs) const override {
return !n || field_type.skip(cs);
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
return !n || (n > 0 && field_type.validate_skip(cs, weak));
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return !n || (n > 0 && field_type.validate_skip(ops, cs, weak));
}
int get_tag(const vm::CellSlice& cs) const override {
return 0;
@ -905,7 +940,7 @@ struct Maybe : TLB_Complex {
Maybe(Args... args) : field_type(args...) {
}
bool skip(vm::CellSlice& cs) const override;
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override;
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override;
int get_tag(const vm::CellSlice& cs) const override {
return cs.have(1) ? (int)cs.prefetch_ulong(1) : -1;
}
@ -928,10 +963,10 @@ bool Maybe<T>::skip(vm::CellSlice& cs) const {
}
template <class T>
bool Maybe<T>::validate_skip(vm::CellSlice& cs, bool weak) const {
bool Maybe<T>::validate_skip(int* ops, vm::CellSlice& cs, bool weak) const {
int t = get_tag(cs);
if (t > 0) {
return cs.advance(1) && field_type.validate_skip(cs, weak);
return cs.advance(1) && field_type.validate_skip(ops, cs, weak);
} else if (!t) {
return cs.advance(1);
} else {
@ -979,11 +1014,11 @@ struct RefTo final : TLB {
int get_size(const vm::CellSlice& cs) const override {
return 0x10000;
}
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
return cs.size_refs() ? ref_type.validate_ref(cs.prefetch_ref(), weak) : false;
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return cs.size_refs() ? ref_type.validate_ref(ops, cs.prefetch_ref(), weak) : false;
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
return ref_type.validate_skip_ref(cs, weak);
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return ref_type.validate_skip_ref(ops, cs, weak);
}
std::ostream& print_type(std::ostream& os) const override {
return os << '^' << ref_type;
@ -1000,11 +1035,11 @@ struct RefT final : TLB {
int get_size(const vm::CellSlice& cs) const override {
return 0x10000;
}
bool validate(const vm::CellSlice& cs, bool weak = false) const override {
return X.validate_ref(cs.prefetch_ref(), weak);
bool validate(int* ops, const vm::CellSlice& cs, bool weak = false) const override {
return X.validate_ref(ops, cs.prefetch_ref(), weak);
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
return X.validate_skip_ref(cs, weak);
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return X.validate_skip_ref(ops, cs, weak);
}
std::ostream& print_type(std::ostream& os) const override {
return os << '^' << X;
@ -1021,9 +1056,10 @@ struct Either final : TLB_Complex {
bool skip(vm::CellSlice& cs) const override {
return cs.have(1) ? (cs.fetch_ulong(1) ? right_type.skip(cs) : left_type.skip(cs)) : false;
}
bool validate_skip(vm::CellSlice& cs, bool weak = false) const override {
return cs.have(1) ? (cs.fetch_ulong(1) ? right_type.validate_skip(cs, weak) : left_type.validate_skip(cs, weak))
: false;
bool validate_skip(int* ops, vm::CellSlice& cs, bool weak = false) const override {
return cs.have(1)
? (cs.fetch_ulong(1) ? right_type.validate_skip(ops, cs, weak) : left_type.validate_skip(ops, cs, weak))
: false;
}
int get_tag(const vm::CellSlice& cs) const override {
return (int)cs.prefetch_ulong(1);