本期小E将为大家带来EOCS 最低资源保障机制。

为满足普通用户日常的转账等基本需求,无需再为较少的初始资源抵押担心无法使用链上功能。EOCS可以通过链的参数来调整分配给每个用户免费的资源额度,相当于EOCS链上的最低资源保障机制。

系统合约中最低资源保障代码

 void system_contract::setmrs( int64_t cpu_us, int64_t net_bytes, int64_t ram_bytes){
require_auth(_self);
set_minimum_resource_security(ram_bytes, net_bytes, cpu_us);
}

其中privileged_api::set_minimum_resource_security是主链提供的供智能合约调用的接口,该函数参数很简单,分别为要设置的cpu,net,和ram的资源,privileged_api::get_resource_limits为获取账户资源状态的接口。函数在头文件eosiolib/privileged.h中声明。

下面为set_minimum_resource_security函数的实现

 void set_minimum_resource_security(int64_t ram_bytes, int64_t net_bytes, int64_t cpu_us) {
EOS_ASSERT(cpu_us >= , wasm_execution_error, "cpu_us must be >= 0");
EOS_ASSERT(net_bytes >= , wasm_execution_error, "net_bytes must be >= 0");
EOS_ASSERT(ram_bytes >= , wasm_execution_error, "ram_bytes must be >= 0");
auto& resource_limits = context.control.get_mutable_resource_limits_manager();
int64_t x, y, current_ram_bytes;
resource_limits.get_mrs_parameters(current_ram_bytes, x, y);
EOS_ASSERT(ram_bytes >= current_ram_bytes, wasm_execution_error,
"ram_bytes cannot be reduced, current_ram_bytes: '${current_ram_bytes}', set_ram_bytes: '${set_ram_bytes}'",
("current_ram_bytes", current_ram_bytes)("set_ram_bytes", ram_bytes));
resource_limits.set_mrs_parameters(ram_bytes, net_bytes, cpu_us);
}

函数中通过resource_limits_manager::get_mrs_parameters()和resource_limits_manager::set_mrs_parameters()分别去获取和设置最低资源保障

最低资源保障定义在resource_limits_config_object类中

 class resource_limits_config_object : public chainbase::object<resource_limits_config_object_type, resource_limits_config_object> {
OBJECT_CTOR(resource_limits_config_object);
id_type id; …


// Minimal Resource Security (MRS)
int64_t mrs_cpu_us = config::default_mrs_cpu_us;// 200 microseconds
int64_t mrs_net_bytes = config::default_mrs_net_bytes;// 10 KB
int64_t mrs_ram_bytes = config::default_mrs_ram_bytes;// 0 KB };

设置了最低资源保障后可以通过privileged_api::get_resource_limits->resource_limits_manager::get_account_limits查询

//所以返回的账户资源是否加上最低资源保障根据includes_mrs_ram

 void resource_limits_manager::get_account_limits( const account_name& account, int64_t& ram_bytes, int64_t& net_weight, int64_t& cpu_weight, bool includes_mrs_ram ) const {
const auto* pending_buo = _db.find<resource_limits_object,by_owner>( boost::make_tuple(true, account) );
const auto& config = _db.get<resource_limits_config_object>(); if (pending_buo) {
ram_bytes = pending_buo->ram_bytes;
net_weight = pending_buo->net_weight;
cpu_weight = pending_buo->cpu_weight;
} else {
const auto& buo = _db.get<resource_limits_object,by_owner>( boost::make_tuple( false, account ) );
ram_bytes = buo.ram_bytes;
net_weight = buo.net_weight;
cpu_weight = buo.cpu_weight;
} if (includes_mrs_ram) {
ram_bytes += config.mrs_ram_bytes;
} }

CPU和NET通过抵押EOC获得,每个账户所能获得的资源为:系统总资源 * 抵押代币 / 总的抵押代币 + 最低资源保障

// 获取账户当前可用的虚拟CPU

 int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name, bool elastic ) const {
auto arl = get_account_cpu_limit_ex(name, elastic);
return arl.available;
}

// 获取账户的虚拟CPU限制

 account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, bool elastic) const {

    const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
const auto& config = _db.get<resource_limits_config_object>(); int64_t cpu_weight, x, y;
get_account_limits( name, x, y, cpu_weight ); if( cpu_weight < || state.total_cpu_weight == ) {
return { -, -, - };
} account_resource_limit arl; uint128_t window_size = config.account_cpu_usage_average_window;

   // 计算窗口期(在这里为24h)内的虚拟计算能力

 uint128_t virtual_cpu_capacity_in_window = (uint128_t)(elastic ? state.virtu   al_cpu_limit : config.cpu_limit_parameters.max) * window_size;
uint128_t user_weight = (uint128_t)cpu_weight;
uint128_t all_user_weight = (uint128_t)state.total_cpu_weight;

  // 每个账户所能获得的资源为:系统总资源 * 抵押代币 / 总的抵押代币 + 最低资源保障cpu资源

    auto max_user_use_in_window = (virtual_cpu_capacity_in_window * user_weight) / all_user_weight + config.mrs_cpu_us;
auto cpu_used_in_window=impl::integer_divide_ceil((uint128_t)usage.cpu_usage.value_ex * window_size, (uint128_t)config::rate_limiting_precision);
if( max_user_use_in_window <= cpu_used_in_window )
arl.available = ;
else
arl.available = impl::downgrade_cast<int64_t>(max_user_use_in_window - cpu_used_in_window);
arl.used = impl::downgrade_cast<int64_t>(cpu_used_in_window);
arl.max = impl::downgrade_cast<int64_t>(max_user_use_in_window);
return arl;
}

EOCS对CPU、NET和RAM资源进行统一管理,对系统可用资源和账户可用资源集中记账。

// 将交易消耗的CPU和NET资源计入账户,并且加到块消耗的CPU和NET资源内,通常在交易验证后调用

 void resource_limits_manager::add_transaction_usage(const flat_set<account_name>& accounts, uint64_t cpu_usage, uint64_t net_usage, uint32_t time_slot ) {
const auto& state = _db.get<resource_limits_state_object>();
const auto& config = _db.get<resource_limits_config_object>();
for( const auto& a : accounts ) {
const auto& usage = _db.get<resource_usage_object,by_owner>( a );
int64_t unused;
int64_t net_weight;
int64_t cpu_weight;
get_account_limits( a, unused, net_weight, cpu_weight );
_db.modify( usage, [&]( auto& bu ){
bu.net_usage.add( net_usage, time_slot, config.account_net_usage_average_window );
bu.cpu_usage.add( cpu_usage, time_slot, config.account_cpu_usage_average_window );
}); if( cpu_weight >= && state.total_cpu_weight > ) {
uint128_t window_size = config.account_cpu_usage_average_window;
auto virtual_network_capacity_in_window = (uint128_t)state.virtual_cpu_limit * window_size;
auto cpu_used_in_window = ((uint128_t)usage.cpu_usage.value_ex * window_size) / (uint128_t)config::rate_limiting_precision;
uint128_t user_weight = (uint128_t)cpu_weight;
uint128_t all_user_weight = state.total_cpu_weight;
}
}

 //此处每个账户所获得的资源需要加上最低资源保障

      auto max_user_use_in_window = (virtual_network_capacity_in_window * user_weight) / all_user_weight + config.mrs_cpu_us;
EOS_ASSERT( cpu_used_in_window <= max_user_use_in_window,
tx_cpu_usage_exceeded,
"authorizing account '${n}' has insufficient cpu resources for this transaction",
("n", name(a))
("cpu_used_in_window",cpu_used_in_window)
("max_user_use_in_window",max_user_use_in_window) );
} if( net_weight >= && state.total_net_weight > ) {
uint128_t window_size = config.account_net_usage_average_window;
auto virtual_network_capacity_in_window = (uint128_t)state.virtual_net_limit * window_size;
auto net_used_in_window = ((uint128_t)usage.net_usage.value_ex * window_size) / (uint128_t)config::rate_limiting_precision;
uint128_t user_weight = (uint128_t)net_weight;
uint128_t all_user_weight = state.total_net_weight;

      //此处每个账户所获得的资源需要加上最低资源保障

    auto max_user_use_in_window = (virtual_network_capacity_in_window * user_weight) / all_user_weight + config.mrs_net_bytes;
EOS_ASSERT( net_used_in_window <= max_user_use_in_window,
tx_net_usage_exceeded,
"authorizing account '${n}' has insufficient net resources for this transaction",
("n", name(a))
("net_used_in_window",net_used_in_window)
("max_user_use_in_window",max_user_use_in_window) ); }
} // account for this transaction in the block and do not exceed those limits either
_db.modify(state, [&](resource_limits_state_object& rls){
rls.pending_cpu_usage += cpu_usage;
rls.pending_net_usage += net_usage;
}); EOS_ASSERT( state.pending_cpu_usage <= config.cpu_limit_parameters.max, block_resource_exhausted, "Block has insufficient cpu resources" );
EOS_ASSERT( state.pending_net_usage <= config.net_limit_parameters.max, block_resource_exhausted, "Block has insufficient net resources" );
}

以上即为EOCS最低资源保障代码分析,此处稍微提一下,EOS引入了虚拟资源,实现动态调节,virtual_block_cpu_limit和virtual_block_net_limit的总资源的初始值分别为block_cpu_limit和block_net_limit,也就是说,虚拟资源一开始等于实际资源,然后随着系统忙闲不断调整,最低值等于实际资源,最高值等于实际资源的1000倍。

详细细节,大家可以下载源码仔细参阅,本期小E为大家带来的EOCS 最低资源保障机制就介绍到这里,欢迎大家关注EOCS官方微信公众号及添加EOCS小秘书共同探讨交流更多技术。

 

EOCS 最低资源保障机制的更多相关文章

  1. atitit.资源释放机制--attilax总结

    atitit.资源释放机制--attilax总结 1. .全手工, 1 2. 引用计数, 1 2.1. 成本也显而易见. 1 2.2. 循环引用的问题, 2 2.3. 引用计数方式事实上也有经典的卡顿 ...

  2. 【原】Storm 消息处理保障机制

    Storm入门教程 1. Storm基础 Storm Storm主要特点 Storm基本概念 Storm调度器 Storm配置 Guaranteeing Message Processing(消息处理 ...

  3. Android源代码分析-资源载入机制

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 我们 ...

  4. MySQL 持久化保障机制-redo 日志

    我们在 聊一聊 MySQL 中的事务及其实现原理 中提到了 redo 日志,redo 日志是用来保证 MySQL 持久化功能的,需要注意的是 redo 日志是 InnoDB 引擎特有的功能. 为什么 ...

  5. Yarn的资源隔离机制

    源调度和资源隔离是YARN作为一个资源管理系统,最重要和最基础的两个功能.资源调度由ResourceManager完成,而资源隔离由各个NodeManager实现,在文章“Hadoop YARN中内存 ...

  6. Tornado 的安全性保障机制Cookie XSRF跨站请求伪造阻断 &用户验证机制

    6.1 Cookie 对于RequestHandler,除了在第二章中讲到的之外,还提供了操作cookie的方法. 设置/获取 注意:Cookie 在浏览器调试时, 只有在第一次访问该网站的时候获取到 ...

  7. hadoop作业调度策略

    一个Mapreduce作业是通过JobClient向master的JobTasker提交的(JobTasker一直在等待JobClient通过RPC协议提交作业),JobTasker接到JobClie ...

  8. MapReduce多用户任务调度器——容量调度器(Capacity Scheduler)原理和源码研究

    前言:为了研究需要,将Capacity Scheduler和Fair Scheduler的原理和代码进行学习,用两篇文章作为记录.如有理解错误之处,欢迎批评指正. 容量调度器(Capacity Sch ...

  9. 大数据基础总结---MapReduce和YARN技术原理

    Map Reduce和YARN技术原理 学习目标 熟悉MapReduce和YARN是什么 掌握MapReduce使用的场景及其原理 掌握MapReduce和YARN功能与架构 熟悉YARN的新特性 M ...

随机推荐

  1. 03 前端篇(JS)

    参考博客:http://www.cnblogs.com/yuanchenqi/articles/5980312.html JavaScript包括三部分: ECMAScript.DOM.BOM Jav ...

  2. Linux新增和删除环境变量

    vi ~/.bashrc 添加 export 变量名=值 使环境变量生效 source ~/.bashrc

  3. Linux(Ubuntu)使用日记------Mongodb的安装与使用

    1.安装 Linux下安装mongodb还是比较容易的 直接使用apt-get安装即可,命令如下: sudo apt-get install mongodb 安装完成之后进行检验, “mongo sh ...

  4. nginx 返回json格式内容

    例子: #如果访问的ip是192.168.1.1,就直接返回json格式的内容 location / { default_type application/json; #####格式 if ( $re ...

  5. 原型设计的工具-----Axure RP

     原型设计的工具-----Axure RP 1.原型设计的工具 目前能用于原型设计的工具有很多,其中有七种比较好. (1)    Axure RP (2)    Mockplus (3)    Jus ...

  6. 高新兴 ME3630-W 4G 模块 Android 平台适配

    2019-04-26 关键字:高新兴 ME3630-W 适配.rk3128 移植 4G 模块 本篇文章系笔者在移植 高新兴物联 ME3630-W 4G 模块到运行着 Android4.4 操作系统的 ...

  7. 论Scrapy中的数据持久化

    引入 Scrapy的数据持久化,主要包括存储到数据库.文件以及内置数据存储. 那我们今天就来讲讲如何把Scrapy中的数据存储到数据库和文件当中. 终端指令存储 保证爬虫文件的parse方法中有可迭代 ...

  8. 「洛谷5300」「GXOI/GZOI2019」与或和【单调栈+二进制转化】

    题目链接 [洛谷传送门] 题解 按位处理. 把每一位对应的图都处理出来 然后单调栈处理一下就好了. \(and\)操作处理全\(1\). \(or\)操作处理全\(0\). 代码 #include & ...

  9. react native定报预披项目知识点总结

    1.TextInput组件对安卓的适配问题 textInput 在iOS 显示正常,但是在android下会出现下横线,并且字会被遮盖 因此一般都这么用该组件 <TextInput style= ...

  10. P1282 多米诺骨牌 (背包变形问题)

    题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9, ...