mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
slightly changed block format
- small change in block format - added config in blockchain explorer - bugfixes
This commit is contained in:
parent
7f3a22a217
commit
090e0c16eb
82 changed files with 1852 additions and 391 deletions
|
@ -789,10 +789,11 @@ td::Status ShardState::unpack_state(ton::BlockIdExt blkid, Ref<vm::Cell> prev_st
|
|||
return td::Status::Error(-666, "ShardState of "s + id_.to_str() + " does not contain a valid global_balance");
|
||||
}
|
||||
if (extra.r1.flags & 1) {
|
||||
if (extra.r1.block_create_stats->prefetch_ulong(8) != 0x17) {
|
||||
if (extra.r1.block_create_stats->prefetch_ulong(8) == 0x17) {
|
||||
block_create_stats_ = std::make_unique<vm::Dictionary>(extra.r1.block_create_stats->prefetch_ref(), 256);
|
||||
} else {
|
||||
return td::Status::Error(-666, "ShardState of "s + id_.to_str() + " does not contain a valid BlockCreateStats");
|
||||
}
|
||||
block_create_stats_ = std::make_unique<vm::Dictionary>(extra.r1.block_create_stats->prefetch_ref(), 256);
|
||||
} else {
|
||||
block_create_stats_ = std::make_unique<vm::Dictionary>(256);
|
||||
}
|
||||
|
@ -1846,6 +1847,18 @@ td::Status check_block_header(Ref<vm::Cell> block_root, const ton::BlockIdExt& i
|
|||
return td::Status::OK();
|
||||
}
|
||||
|
||||
std::unique_ptr<vm::Dictionary> get_block_create_stats_dict(Ref<vm::Cell> state_root) {
|
||||
block::gen::ShardStateUnsplit::Record info;
|
||||
block::gen::McStateExtra::Record extra;
|
||||
block::gen::BlockCreateStats::Record_block_create_stats cstats;
|
||||
if (!(::tlb::unpack_cell(std::move(state_root), info) && info.custom->size_refs() &&
|
||||
::tlb::unpack_cell(info.custom->prefetch_ref(), extra) && (extra.r1.flags & 1) &&
|
||||
::tlb::csr_unpack(std::move(extra.r1.block_create_stats), cstats))) {
|
||||
return {};
|
||||
}
|
||||
return std::make_unique<vm::Dictionary>(std::move(cstats.counters), 256);
|
||||
}
|
||||
|
||||
std::unique_ptr<vm::AugmentedDictionary> get_prev_blocks_dict(Ref<vm::Cell> state_root) {
|
||||
block::gen::ShardStateUnsplit::Record info;
|
||||
block::gen::McStateExtra::Record extra_info;
|
||||
|
|
|
@ -163,12 +163,12 @@ struct MsgProcessedUpto {
|
|||
MsgProcessedUpto(ton::ShardId _shard, ton::BlockSeqno _mcseqno, ton::LogicalTime _lt, td::ConstBitPtr _hash)
|
||||
: shard(_shard), mc_seqno(_mcseqno), last_inmsg_lt(_lt), last_inmsg_hash(_hash) {
|
||||
}
|
||||
bool operator<(const MsgProcessedUpto& other) const& {
|
||||
bool operator<(const MsgProcessedUpto& other) const & {
|
||||
return shard < other.shard || (shard == other.shard && mc_seqno < other.mc_seqno);
|
||||
}
|
||||
bool contains(const MsgProcessedUpto& other) const&;
|
||||
bool contains(const MsgProcessedUpto& other) const &;
|
||||
bool contains(ton::ShardId other_shard, ton::LogicalTime other_lt, td::ConstBitPtr other_hash,
|
||||
ton::BlockSeqno other_mc_seqno) const&;
|
||||
ton::BlockSeqno other_mc_seqno) const &;
|
||||
// NB: this is for checking whether we have already imported an internal message
|
||||
bool already_processed(const EnqueuedMsgDescr& msg) const;
|
||||
};
|
||||
|
@ -514,6 +514,9 @@ struct DiscountedCounter {
|
|||
return last_updated == other.last_updated && total == other.total && cnt2048 <= other.cnt2048 + 1 &&
|
||||
other.cnt2048 <= cnt2048 + 1 && cnt65536 <= other.cnt65536 + 1 && other.cnt65536 <= cnt65536 + 1;
|
||||
}
|
||||
bool modified_since(ton::UnixTime utime) const {
|
||||
return last_updated >= utime;
|
||||
}
|
||||
bool validate();
|
||||
bool increase_by(unsigned count, ton::UnixTime now);
|
||||
bool fetch(vm::CellSlice& cs);
|
||||
|
@ -629,6 +632,8 @@ td::Status unpack_block_prev_blk_try(Ref<vm::Cell> block_root, const ton::BlockI
|
|||
td::Status check_block_header(Ref<vm::Cell> block_root, const ton::BlockIdExt& id,
|
||||
ton::Bits256* store_shard_hash_to = nullptr);
|
||||
|
||||
std::unique_ptr<vm::Dictionary> get_block_create_stats_dict(Ref<vm::Cell> state_root);
|
||||
|
||||
std::unique_ptr<vm::AugmentedDictionary> get_prev_blocks_dict(Ref<vm::Cell> state_root);
|
||||
bool get_old_mc_block_id(vm::AugmentedDictionary* prev_blocks_dict, ton::BlockSeqno seqno, ton::BlockIdExt& blkid,
|
||||
ton::LogicalTime* end_lt = nullptr);
|
||||
|
|
|
@ -366,6 +366,10 @@ action_send_msg#0ec3c86d mode:(## 8)
|
|||
action_set_code#ad4de08e new_code:^Cell = OutAction;
|
||||
action_reserve_currency#36e6b809 mode:(## 8)
|
||||
currency:CurrencyCollection = OutAction;
|
||||
libref_hash$0 lib_hash:bits256 = LibRef;
|
||||
libref_ref$1 library:^Cell = LibRef;
|
||||
action_change_library#26fa1dd4 mode:(## 7) { mode <= 2 }
|
||||
libref:LibRef = OutAction;
|
||||
|
||||
out_list_node$_ prev:^Cell action:OutAction = OutListNode;
|
||||
//
|
||||
|
@ -505,6 +509,7 @@ _ (HashmapAugE 32 KeyExtBlkRef KeyMaxLt) = OldMcBlocksInfo;
|
|||
counters#_ last_updated:uint32 total:uint64 cnt2048:uint64 cnt65536:uint64 = Counters;
|
||||
creator_info#4 mc_blocks:Counters shard_blocks:Counters = CreatorStats;
|
||||
block_create_stats#17 counters:(HashmapE 256 CreatorStats) = BlockCreateStats;
|
||||
block_create_stats_ext#34 counters:(HashmapAugE 256 CreatorStats uint32) = BlockCreateStats;
|
||||
|
||||
masterchain_state_extra#cc26
|
||||
shard_hashes:ShardHashes
|
||||
|
|
|
@ -1710,6 +1710,30 @@ std::vector<ton::ValidatorDescr> Config::compute_total_validator_set(int next) c
|
|||
return res.move_as_ok()->export_validator_set();
|
||||
}
|
||||
|
||||
td::Result<std::pair<ton::UnixTime, ton::UnixTime>> Config::unpack_validator_set_start_stop(Ref<vm::Cell> vset_root) {
|
||||
if (vset_root.is_null()) {
|
||||
return td::Status::Error("validator set absent");
|
||||
}
|
||||
gen::ValidatorSet::Record_validators_ext rec;
|
||||
if (tlb::unpack_cell(vset_root, rec)) {
|
||||
return std::pair<ton::UnixTime, ton::UnixTime>(rec.utime_since, rec.utime_until);
|
||||
}
|
||||
gen::ValidatorSet::Record_validators rec0;
|
||||
if (tlb::unpack_cell(std::move(vset_root), rec0)) {
|
||||
return std::pair<ton::UnixTime, ton::UnixTime>(rec0.utime_since, rec0.utime_until);
|
||||
}
|
||||
return td::Status::Error("validator set is invalid");
|
||||
}
|
||||
|
||||
std::pair<ton::UnixTime, ton::UnixTime> Config::get_validator_set_start_stop(int next) const {
|
||||
auto res = unpack_validator_set_start_stop(get_config_param(next < 0 ? 32 : (next ? 36 : 34)));
|
||||
if (res.is_error()) {
|
||||
return {0, 0};
|
||||
} else {
|
||||
return res.move_as_ok();
|
||||
}
|
||||
}
|
||||
|
||||
bool WorkchainInfo::unpack(ton::WorkchainId wc, vm::CellSlice& cs) {
|
||||
workchain = ton::workchainInvalid;
|
||||
if (wc == ton::workchainInvalid) {
|
||||
|
|
|
@ -50,7 +50,7 @@ struct ValidatorDescr {
|
|||
: pubkey(_pubkey), weight(_weight), cum_weight(_cum_weight) {
|
||||
adnl_addr.set_zero();
|
||||
}
|
||||
bool operator<(td::uint64 wt_pos) const& {
|
||||
bool operator<(td::uint64 wt_pos) const & {
|
||||
return cum_weight < wt_pos;
|
||||
}
|
||||
};
|
||||
|
@ -558,6 +558,7 @@ class Config {
|
|||
const ValidatorSet* get_cur_validator_set() const {
|
||||
return cur_validators_.get();
|
||||
}
|
||||
std::pair<ton::UnixTime, ton::UnixTime> get_validator_set_start_stop(int next = 0) const;
|
||||
ton::ValidatorSessionConfig get_consensus_config() const;
|
||||
bool foreach_config_param(std::function<bool(int, Ref<vm::Cell>)> scan_func) const;
|
||||
Ref<WorkchainInfo> get_workchain_info(ton::WorkchainId workchain_id) const;
|
||||
|
@ -577,6 +578,7 @@ class Config {
|
|||
static td::Result<std::unique_ptr<Config>> unpack_config(Ref<vm::CellSlice> config_csr, int mode = 0);
|
||||
static td::Result<std::unique_ptr<Config>> extract_from_state(Ref<vm::Cell> mc_state_root, int mode = 0);
|
||||
static td::Result<std::unique_ptr<Config>> extract_from_key_block(Ref<vm::Cell> key_block_root, int mode = 0);
|
||||
static td::Result<std::pair<ton::UnixTime, ton::UnixTime>> unpack_validator_set_start_stop(Ref<vm::Cell> root);
|
||||
|
||||
protected:
|
||||
Config(int _mode) : mode(_mode) {
|
||||
|
|
|
@ -1098,6 +1098,9 @@ bool Transaction::prepare_action_phase(const ActionPhaseConfig& cfg) {
|
|||
case block::gen::OutAction::action_reserve_currency:
|
||||
err_code = try_action_reserve_currency(cs, ap, cfg);
|
||||
break;
|
||||
case block::gen::OutAction::action_change_library:
|
||||
err_code = try_action_change_library(cs, ap, cfg);
|
||||
break;
|
||||
}
|
||||
if (err_code) {
|
||||
ap.result_code = (err_code == -1 ? 34 : err_code);
|
||||
|
@ -1148,6 +1151,56 @@ int Transaction::try_action_set_code(vm::CellSlice& cs, ActionPhase& ap, const A
|
|||
return 0;
|
||||
}
|
||||
|
||||
int Transaction::try_action_change_library(vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg) {
|
||||
block::gen::OutAction::Record_action_change_library rec;
|
||||
if (!tlb::unpack_exact(cs, rec)) {
|
||||
return -1;
|
||||
}
|
||||
// mode: +0 = remove library, +1 = add private library, +2 = add public library
|
||||
Ref<vm::Cell> lib_ref = rec.libref->prefetch_ref();
|
||||
ton::Bits256 hash;
|
||||
if (lib_ref.not_null()) {
|
||||
hash = lib_ref->get_hash().bits();
|
||||
} else {
|
||||
CHECK(rec.libref.write().fetch_ulong(1) == 0 && rec.libref.write().fetch_bits_to(hash));
|
||||
}
|
||||
try {
|
||||
vm::Dictionary dict{new_library, 256};
|
||||
if (!rec.mode) {
|
||||
// remove library
|
||||
dict.lookup_delete(hash);
|
||||
LOG(DEBUG) << "removed " << ((rec.mode >> 1) ? "public" : "private") << " library with hash " << hash.to_hex();
|
||||
} else {
|
||||
auto val = dict.lookup(hash);
|
||||
if (val.not_null()) {
|
||||
bool is_public = val->prefetch_ulong(1);
|
||||
auto ref = val->prefetch_ref();
|
||||
if (hash == ref->get_hash().bits()) {
|
||||
lib_ref = ref;
|
||||
if (is_public == (rec.mode >> 1)) {
|
||||
// library already in required state
|
||||
ap.spec_actions++;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lib_ref.is_null()) {
|
||||
// library code not found
|
||||
return 41;
|
||||
}
|
||||
vm::CellBuilder cb;
|
||||
CHECK(cb.store_bool_bool(rec.mode >> 1) && cb.store_ref_bool(std::move(lib_ref)));
|
||||
CHECK(dict.set_builder(hash, cb));
|
||||
LOG(DEBUG) << "added " << ((rec.mode >> 1) ? "public" : "private") << " library with hash " << hash.to_hex();
|
||||
}
|
||||
new_library = std::move(dict).extract_root_cell();
|
||||
} catch (vm::VmError& vme) {
|
||||
return 42;
|
||||
}
|
||||
ap.spec_actions++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// msg_fwd_fees = (lump_price + ceil((bit_price * msg.bits + cell_price * msg.cells)/2^16)) nanograms
|
||||
// ihr_fwd_fees = ceil((msg_fwd_fees * ihr_price_factor)/2^16) nanograms
|
||||
// bits in the root cell of a message are not included in msg.bits (lump_price pays for them)
|
||||
|
|
|
@ -65,10 +65,10 @@ struct NewOutMsg {
|
|||
NewOutMsg(ton::LogicalTime _lt, Ref<vm::Cell> _msg, Ref<vm::Cell> _trans)
|
||||
: lt(_lt), msg(std::move(_msg)), trans(std::move(_trans)) {
|
||||
}
|
||||
bool operator<(const NewOutMsg& other) const& {
|
||||
bool operator<(const NewOutMsg& other) const & {
|
||||
return lt < other.lt || (lt == other.lt && msg->get_hash() < other.msg->get_hash());
|
||||
}
|
||||
bool operator>(const NewOutMsg& other) const& {
|
||||
bool operator>(const NewOutMsg& other) const & {
|
||||
return lt > other.lt || (lt == other.lt && other.msg->get_hash() < msg->get_hash());
|
||||
}
|
||||
};
|
||||
|
@ -371,6 +371,7 @@ struct Transaction {
|
|||
Ref<vm::Tuple> prepare_vm_c7(const ComputePhaseConfig& cfg) const;
|
||||
bool prepare_rand_seed(td::BitArray<256>& rand_seed, const ComputePhaseConfig& cfg) const;
|
||||
int try_action_set_code(vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg);
|
||||
int try_action_change_library(vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg);
|
||||
int try_action_send_msg(const vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg, int redoing = 0);
|
||||
int try_action_reserve_currency(vm::CellSlice& cs, ActionPhase& ap, const ActionPhaseConfig& cfg);
|
||||
bool check_replace_src_addr(Ref<vm::CellSlice>& src_addr) const;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue