mirror of
https://github.com/ton-blockchain/ton
synced 2025-03-09 15:40:10 +00:00
updated smartcontract code
updated lite-client and configuration smartcontract updated tonlib code
This commit is contained in:
parent
8e5bd938aa
commit
bce33f588a
46 changed files with 677 additions and 299 deletions
|
@ -24,10 +24,61 @@
|
|||
#include "common/util.h"
|
||||
#include "td/utils/crypto.h"
|
||||
#include "td/utils/tl_storers.h"
|
||||
#include "td/utils/misc.h"
|
||||
|
||||
namespace block {
|
||||
using namespace std::literals::string_literals;
|
||||
|
||||
td::Result<PublicKey> PublicKey::from_bytes(td::Slice key) {
|
||||
if (key.size() != 32) {
|
||||
return td::Status::Error("Ed25519 public key must be exactly 32 bytes long");
|
||||
}
|
||||
PublicKey res;
|
||||
res.key = key.str();
|
||||
return res;
|
||||
}
|
||||
|
||||
td::Result<PublicKey> PublicKey::parse(td::Slice key) {
|
||||
if (key.size() != 48) {
|
||||
return td::Status::Error("Serialized Ed25519 public key must be exactly 48 characters long");
|
||||
}
|
||||
td::uint8 buf[36];
|
||||
if (!buff_base64_decode(td::MutableSlice(buf, 36), key, true)) {
|
||||
return td::Status::Error("Public key is not serialized in base64 encoding");
|
||||
}
|
||||
|
||||
td::uint16 hash = static_cast<td::uint16>((static_cast<unsigned>(buf[34]) << 8) + buf[35]);
|
||||
if (hash != td::crc16(td::Slice(buf, 34))) {
|
||||
return td::Status::Error("Public key has incorrect crc16 hash");
|
||||
}
|
||||
|
||||
if (buf[0] != 0x3e) {
|
||||
return td::Status::Error("Not a public key");
|
||||
}
|
||||
if (buf[1] != 0xe6) {
|
||||
return td::Status::Error("Not an ed25519 public key");
|
||||
}
|
||||
|
||||
return from_bytes(td::Slice(buf + 2, 32));
|
||||
}
|
||||
|
||||
std::string PublicKey::serialize(bool base64_url) {
|
||||
CHECK(key.size() == 32);
|
||||
std::string buf(36, 0);
|
||||
td::MutableSlice bytes(buf);
|
||||
|
||||
bytes[0] = static_cast<char>(0x3e);
|
||||
bytes[1] = static_cast<char>(0xe6);
|
||||
bytes.substr(2).copy_from(key);
|
||||
auto hash = td::crc16(bytes.substr(0, 34));
|
||||
bytes[34] = static_cast<char>(hash >> 8);
|
||||
bytes[35] = static_cast<char>(hash & 255);
|
||||
|
||||
std::string res(48, 0);
|
||||
buff_base64_encode(res, bytes, base64_url);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool pack_std_smc_addr_to(char result[48], bool base64_url, ton::WorkchainId wc, const ton::StdSmcAddress& addr,
|
||||
bool bounceable, bool testnet) {
|
||||
if (wc < -128 || wc >= 128) {
|
||||
|
@ -316,14 +367,14 @@ std::unique_ptr<MsgProcessedUptoCollection> MsgProcessedUptoCollection::unpack(t
|
|||
return v && v->valid ? std::move(v) : std::unique_ptr<MsgProcessedUptoCollection>{};
|
||||
}
|
||||
|
||||
bool MsgProcessedUpto::contains(const MsgProcessedUpto& other) const & {
|
||||
bool MsgProcessedUpto::contains(const MsgProcessedUpto& other) const& {
|
||||
return ton::shard_is_ancestor(shard, other.shard) && mc_seqno >= other.mc_seqno &&
|
||||
(last_inmsg_lt > other.last_inmsg_lt ||
|
||||
(last_inmsg_lt == other.last_inmsg_lt && !(last_inmsg_hash < other.last_inmsg_hash)));
|
||||
}
|
||||
|
||||
bool MsgProcessedUpto::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& {
|
||||
return ton::shard_is_ancestor(shard, other_shard) && mc_seqno >= other_mc_seqno &&
|
||||
(last_inmsg_lt > other_lt || (last_inmsg_lt == other_lt && !(last_inmsg_hash < other_hash)));
|
||||
}
|
||||
|
|
|
@ -33,6 +33,16 @@ namespace block {
|
|||
|
||||
using td::Ref;
|
||||
|
||||
struct PublicKey {
|
||||
std::string key;
|
||||
|
||||
static td::Result<PublicKey> from_bytes(td::Slice key);
|
||||
|
||||
static td::Result<PublicKey> parse(td::Slice key);
|
||||
|
||||
std::string serialize(bool base64_url = false);
|
||||
};
|
||||
|
||||
struct StdAddress {
|
||||
ton::WorkchainId workchain{ton::workchainInvalid};
|
||||
bool bounceable{true}; // addresses must be bounceable by default
|
||||
|
@ -149,12 +159,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;
|
||||
};
|
||||
|
@ -470,13 +480,14 @@ struct BlockProofLink {
|
|||
bool incomplete() const {
|
||||
return dest_proof.is_null();
|
||||
}
|
||||
td::Status validate() const;
|
||||
td::Status validate(td::uint32* save_utime = nullptr) const;
|
||||
};
|
||||
|
||||
struct BlockProofChain {
|
||||
ton::BlockIdExt from, to;
|
||||
int mode;
|
||||
bool complete{false}, has_key_block{false}, valid{false};
|
||||
td::uint32 last_utime{0};
|
||||
bool complete{false}, has_key_block{false}, has_utime{false}, valid{false};
|
||||
ton::BlockIdExt key_blkid;
|
||||
std::vector<BlockProofLink> links;
|
||||
std::size_t link_count() const {
|
||||
|
|
|
@ -599,6 +599,10 @@ gas_prices#dd gas_price:uint64 gas_limit:uint64 gas_credit:uint64
|
|||
block_gas_limit:uint64 freeze_due_limit:uint64 delete_due_limit:uint64
|
||||
= GasLimitsPrices;
|
||||
|
||||
gas_prices_ext#de gas_price:uint64 gas_limit:uint64 special_gas_limit:uint64 gas_credit:uint64
|
||||
block_gas_limit:uint64 freeze_due_limit:uint64 delete_due_limit:uint64
|
||||
= GasLimitsPrices;
|
||||
|
||||
config_mc_gas_prices#_ GasLimitsPrices = ConfigParam 20;
|
||||
config_gas_prices#_ GasLimitsPrices = ConfigParam 21;
|
||||
|
||||
|
|
|
@ -296,7 +296,10 @@ td::Result<TransactionList::Info> TransactionList::validate() const {
|
|||
return std::move(res);
|
||||
}
|
||||
|
||||
td::Status BlockProofLink::validate() const {
|
||||
td::Status BlockProofLink::validate(td::uint32* save_utime) const {
|
||||
if (save_utime) {
|
||||
*save_utime = 0;
|
||||
}
|
||||
if (!(from.is_masterchain_ext() && to.is_masterchain_ext())) {
|
||||
return td::Status::Error("BlockProofLink must have both source and destination blocks in the masterchain");
|
||||
}
|
||||
|
@ -346,6 +349,9 @@ td::Status BlockProofLink::validate() const {
|
|||
return td::Status::Error(PSTRING() << "incorrect is_key_block value " << is_key << " for destination block "
|
||||
<< to.to_str());
|
||||
}
|
||||
if (save_utime) {
|
||||
*save_utime = info.gen_utime;
|
||||
}
|
||||
} else if (!is_key) {
|
||||
// return td::Status::Error("Zerostate destination block "s + to.to_str() + " does not have is_key_block set");
|
||||
}
|
||||
|
@ -414,6 +420,8 @@ td::Status BlockProofLink::validate() const {
|
|||
td::Status BlockProofChain::validate() {
|
||||
valid = false;
|
||||
has_key_block = false;
|
||||
has_utime = false;
|
||||
last_utime = 0;
|
||||
key_blkid.invalidate();
|
||||
if (!(from.is_masterchain_ext() && to.is_masterchain_ext())) {
|
||||
return td::Status::Error("BlockProofChain must have both source and destination blocks in the masterchain");
|
||||
|
@ -435,7 +443,7 @@ td::Status BlockProofChain::validate() {
|
|||
<< link.from.to_str() << " but the previous link ends at different block "
|
||||
<< cur.to_str());
|
||||
}
|
||||
auto err = link.validate();
|
||||
auto err = link.validate(&last_utime);
|
||||
if (err.is_error()) {
|
||||
return td::Status::Error(PSTRING() << "link #" << i << " in BlockProofChain is invalid: " << err.to_string());
|
||||
}
|
||||
|
@ -449,6 +457,7 @@ td::Status BlockProofChain::validate() {
|
|||
return td::Status::Error("last link of BlockProofChain ends at block "s + cur.to_str() +
|
||||
" different from declared chain destination block " + to.to_str());
|
||||
}
|
||||
has_utime = (last_utime > 0);
|
||||
valid = true;
|
||||
return td::Status::OK();
|
||||
}
|
||||
|
|
|
@ -695,7 +695,7 @@ td::RefInt256 ComputePhaseConfig::compute_gas_price(td::uint64 gas_used) const {
|
|||
bool Transaction::compute_gas_limits(ComputePhase& cp, const ComputePhaseConfig& cfg) {
|
||||
// Compute gas limits
|
||||
if (account.is_special) {
|
||||
cp.gas_max = cfg.gas_limit; // TODO: introduce special gas limits?
|
||||
cp.gas_max = cfg.special_gas_limit;
|
||||
} else {
|
||||
cp.gas_max = cfg.gas_bought_for(balance.grams);
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ struct StoragePhase {
|
|||
struct ComputePhaseConfig {
|
||||
td::uint64 gas_price;
|
||||
td::uint64 gas_limit;
|
||||
td::uint64 special_gas_limit;
|
||||
td::uint64 gas_credit;
|
||||
static constexpr td::uint64 gas_infty = (1ULL << 63) - 1;
|
||||
td::RefInt256 gas_price256;
|
||||
|
@ -104,7 +105,11 @@ struct ComputePhaseConfig {
|
|||
Ref<vm::Cell> global_config;
|
||||
td::BitArray<256> block_rand_seed;
|
||||
ComputePhaseConfig(td::uint64 _gas_price = 0, td::uint64 _gas_limit = 0, td::uint64 _gas_credit = 0)
|
||||
: gas_price(_gas_price), gas_limit(_gas_limit), gas_credit(_gas_credit) {
|
||||
: gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_gas_limit), gas_credit(_gas_credit) {
|
||||
compute_threshold();
|
||||
}
|
||||
ComputePhaseConfig(td::uint64 _gas_price, td::uint64 _gas_limit, td::uint64 _spec_gas_limit, td::uint64 _gas_credit)
|
||||
: gas_price(_gas_price), gas_limit(_gas_limit), special_gas_limit(_spec_gas_limit), gas_credit(_gas_credit) {
|
||||
compute_threshold();
|
||||
}
|
||||
void compute_threshold();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue