From 866fbf936b2669cf337027d3de636facaf62e56f Mon Sep 17 00:00:00 2001 From: SpyCheese Date: Thu, 12 Oct 2023 14:53:54 +0300 Subject: [PATCH 1/5] Explicitly handle special cells in action list (#777) --- crypto/block/transaction.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/crypto/block/transaction.cpp b/crypto/block/transaction.cpp index 0a02d6fd..e82b1eeb 100644 --- a/crypto/block/transaction.cpp +++ b/crypto/block/transaction.cpp @@ -943,7 +943,12 @@ int output_actions_count(Ref list) { int i = -1; do { ++i; - list = load_cell_slice(std::move(list)).prefetch_ref(); + bool special = true; + auto cs = load_cell_slice_special(std::move(list), special); + if (special) { + break; + } + list = cs.prefetch_ref(); } while (list.not_null()); return i; } @@ -1122,7 +1127,8 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) { int out_act_num = output_actions_count(cp.actions); if (verbosity > 2) { std::cerr << "new smart contract data: "; - load_cell_slice(cp.new_data).print_rec(std::cerr); + bool can_be_special = true; + load_cell_slice_special(cp.new_data, can_be_special).print_rec(std::cerr); std::cerr << "output actions: "; block::gen::OutList{out_act_num}.print_ref(std::cerr, cp.actions); } @@ -1192,7 +1198,15 @@ bool Transaction::prepare_action_phase(const ActionPhaseConfig& cfg) { int n = 0; while (true) { ap.action_list.push_back(list); - auto cs = load_cell_slice(std::move(list)); + bool special = true; + auto cs = load_cell_slice_special(std::move(list), special); + if (special) { + ap.result_code = 32; // action list invalid + ap.result_arg = n; + ap.action_list_invalid = true; + LOG(DEBUG) << "action list invalid: special cell"; + return true; + } if (!cs.size_ext()) { break; } From 2f8e80ef5617aa546222564c62952ba9efd4a6d8 Mon Sep 17 00:00:00 2001 From: SpyCheese Date: Thu, 12 Oct 2023 14:54:14 +0300 Subject: [PATCH 2/5] Do not retranslate external messages with wrong initstate (#778) --- crypto/block/transaction.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crypto/block/transaction.cpp b/crypto/block/transaction.cpp index e82b1eeb..b1be19c4 100644 --- a/crypto/block/transaction.cpp +++ b/crypto/block/transaction.cpp @@ -1065,6 +1065,11 @@ bool Transaction::prepare_compute_phase(const ComputePhaseConfig& cfg) { } else if (in_msg_state.not_null()) { unpack_msg_state(true); // use only libraries } + if (in_msg_extern && in_msg_state.not_null() && account.addr != in_msg_state->get_hash().bits()) { + LOG(DEBUG) << "in_msg_state hash mismatch in external message"; + cp.skip_reason = ComputePhase::sk_bad_state; + return true; + } // initialize VM Ref stack = prepare_vm_stack(cp); if (stack.is_null()) { From e1df0b3c9088097724b8feba29b7d60d3dba5a5c Mon Sep 17 00:00:00 2001 From: SpyCheese Date: Thu, 12 Oct 2023 14:54:38 +0300 Subject: [PATCH 3/5] Check peers prior to saving it to local db (#779) --- overlay/overlay.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/overlay/overlay.cpp b/overlay/overlay.cpp index a562beb6..fcf766fe 100644 --- a/overlay/overlay.cpp +++ b/overlay/overlay.cpp @@ -291,7 +291,11 @@ void OverlayImpl::alarm() { if (peers_.size() > 0) { std::vector vec; for (td::uint32 i = 0; i < 20; i++) { - vec.push_back(get_random_peer()->get()); + auto P = get_random_peer(); + if (!P) { + break; + } + vec.push_back(P->get()); } td::actor::send_closure(manager_, &OverlayManager::save_to_db, local_id_, overlay_id_, std::move(vec)); } From 9a06a2ebfbdb2a8e18d45a3967fa51b96da4e2b3 Mon Sep 17 00:00:00 2001 From: SpyCheese Date: Thu, 12 Oct 2023 14:55:26 +0300 Subject: [PATCH 4/5] Human-readable timestamps in explorer (#776) --- .../blockchain-explorer-http.cpp | 40 ++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/blockchain-explorer/blockchain-explorer-http.cpp b/blockchain-explorer/blockchain-explorer-http.cpp index 8642e900..e2322ff7 100644 --- a/blockchain-explorer/blockchain-explorer-http.cpp +++ b/blockchain-explorer/blockchain-explorer-http.cpp @@ -35,9 +35,38 @@ #include "vm/cells/MerkleProof.h" #include "block/mc-config.h" #include "ton/ton-shard.h" +#include "td/utils/date.h" bool local_scripts{false}; +static std::string time_to_human(unsigned ts) { + td::StringBuilder sb; + sb << date::format("%F %T", + std::chrono::time_point{std::chrono::seconds(ts)}) + << ", "; + auto now = (unsigned)td::Clocks::system(); + bool past = now >= ts; + unsigned x = past ? now - ts : ts - now; + if (!past) { + sb << "in "; + } + if (x < 60) { + sb << x << "s"; + } else if (x < 3600) { + sb << x / 60 << "m " << x % 60 << "s"; + } else if (x < 3600 * 24) { + x /= 60; + sb << x / 60 << "h " << x % 60 << "m"; + } else { + x /= 3600; + sb << x / 24 << "d " << x % 24 << "h"; + } + if (past) { + sb << " ago"; + } + return sb.as_cslice().str(); +} + HttpAnswer& HttpAnswer::operator<<(AddressCell addr_c) { ton::WorkchainId wc; ton::StdSmcAddress addr; @@ -84,7 +113,7 @@ HttpAnswer& HttpAnswer::operator<<(MessageCell msg) { << "source" << AddressCell{info.src} << "\n" << "destinationNONE\n" << "lt" << info.created_lt << "\n" - << "time" << info.created_at << "\n"; + << "time" << info.created_at << " (" << time_to_human(info.created_at) << ")\n"; break; } case block::gen::CommonMsgInfo::int_msg_info: { @@ -103,7 +132,7 @@ HttpAnswer& HttpAnswer::operator<<(MessageCell msg) { << "source" << AddressCell{info.src} << "\n" << "destination" << AddressCell{info.dest} << "\n" << "lt" << info.created_lt << "\n" - << "time" << info.created_at << "\n" + << "time" << info.created_at << " (" << time_to_human(info.created_at) << ")\n" << "value" << value << "\n"; break; } @@ -277,7 +306,7 @@ HttpAnswer& HttpAnswer::operator<<(TransactionCell trans_c) { << "account" << trans_c.addr.rserialize(true) << "" << "hash" << trans_c.root->get_hash().to_hex() << "\n" << "lt" << trans.lt << "\n" - << "time" << trans.now << "\n" + << "time" << trans.now << " (" << time_to_human(trans.now) << ")\n" << "out messages"; vm::Dictionary dict{trans.r1.out_msgs, 15}; for (td::int32 i = 0; i < trans.outmsg_cnt; i++) { @@ -456,7 +485,7 @@ HttpAnswer& HttpAnswer::operator<<(BlockHeaderCell head_c) { << "block" << block_id.id.to_str() << "\n" << "roothash" << block_id.root_hash.to_hex() << "\n" << "filehash" << block_id.file_hash.to_hex() << "\n" - << "time" << info.gen_utime << "\n" + << "time" << info.gen_utime << " (" << time_to_human(info.gen_utime) << ")\n" << "lt" << info.start_lt << " .. " << info.end_lt << "\n" << "global_id" << blk.global_id << "\n" << "version" << info.version << "\n" @@ -543,7 +572,8 @@ HttpAnswer& HttpAnswer::operator<<(BlockShardsCell shards_c) { ton::ShardIdFull shard{id.workchain, id.shard}; if (ref.not_null()) { *this << "" << shard.to_str() << "top_block_id()} - << "\">" << ref->top_block_id().id.seqno << "" << ref->created_at() << "" + << "\">" << ref->top_block_id().id.seqno << "created_at()) << "\">" << ref->created_at() << "" << "" << ref->want_split_ << "" << "" << ref->want_merge_ << "" << "" << ref->before_split_ << "" From 6e6081c6573aba798a45733478701860755c502a Mon Sep 17 00:00:00 2001 From: EmelyanenkoK Date: Mon, 23 Oct 2023 09:49:02 +0300 Subject: [PATCH 5/5] Add 2023.10 update changelog --- Changelog.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Changelog.md b/Changelog.md index 1deebc61..fba3c5c5 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,3 +1,9 @@ +## 2023.10 Update +1. A series of additional security checks in node: special cells in action list, init state in external messages, peers data prior to saving to disk. +2. Human-readable timestamps in explorer + +Besides the work of the core team, this update is based on the efforts of @akifoq and @mr-tron. + ## 2023.06 Update 1. (disabled by default) New deflation mechanisms: partial fee burning and blackhole address 2. Storage-contract improvement