EOCS 最低资源保障机制
本期小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 最低资源保障机制的更多相关文章
- atitit.资源释放机制--attilax总结
atitit.资源释放机制--attilax总结 1. .全手工, 1 2. 引用计数, 1 2.1. 成本也显而易见. 1 2.2. 循环引用的问题, 2 2.3. 引用计数方式事实上也有经典的卡顿 ...
- 【原】Storm 消息处理保障机制
Storm入门教程 1. Storm基础 Storm Storm主要特点 Storm基本概念 Storm调度器 Storm配置 Guaranteeing Message Processing(消息处理 ...
- Android源代码分析-资源载入机制
转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 我们 ...
- MySQL 持久化保障机制-redo 日志
我们在 聊一聊 MySQL 中的事务及其实现原理 中提到了 redo 日志,redo 日志是用来保证 MySQL 持久化功能的,需要注意的是 redo 日志是 InnoDB 引擎特有的功能. 为什么 ...
- Yarn的资源隔离机制
源调度和资源隔离是YARN作为一个资源管理系统,最重要和最基础的两个功能.资源调度由ResourceManager完成,而资源隔离由各个NodeManager实现,在文章“Hadoop YARN中内存 ...
- Tornado 的安全性保障机制Cookie XSRF跨站请求伪造阻断 &用户验证机制
6.1 Cookie 对于RequestHandler,除了在第二章中讲到的之外,还提供了操作cookie的方法. 设置/获取 注意:Cookie 在浏览器调试时, 只有在第一次访问该网站的时候获取到 ...
- hadoop作业调度策略
一个Mapreduce作业是通过JobClient向master的JobTasker提交的(JobTasker一直在等待JobClient通过RPC协议提交作业),JobTasker接到JobClie ...
- MapReduce多用户任务调度器——容量调度器(Capacity Scheduler)原理和源码研究
前言:为了研究需要,将Capacity Scheduler和Fair Scheduler的原理和代码进行学习,用两篇文章作为记录.如有理解错误之处,欢迎批评指正. 容量调度器(Capacity Sch ...
- 大数据基础总结---MapReduce和YARN技术原理
Map Reduce和YARN技术原理 学习目标 熟悉MapReduce和YARN是什么 掌握MapReduce使用的场景及其原理 掌握MapReduce和YARN功能与架构 熟悉YARN的新特性 M ...
随机推荐
- 分布式存储ceph——(2)openstack对接ceph存储后端
ceph对接openstack环境 一.使用rbd方式提供存储如下数据: (1)image:保存glanc中的image: (2)volume存储:保存cinder的volume:保存创建虚拟机时选择 ...
- 分布式存储ceph——(1)部署ceph
前言: 很多朋友想学ceph,但是开始ceph部署就让初学者举步为艰,ceph部署时由于国外源的问题(具体大家应该懂得),下载和安装软件便会卡住,停止不前.即使配置搭建了国内源后,执行ceph-dep ...
- 类String 初识
String类概述 java.lang.String 类代表字符串.Java程序中所有的字符串文字(例如 "abc" )都可以被看作是实现此类的实例.类 String 中包括用于检 ...
- codeforces#1139D. Steps to One (概率dp+莫比乌斯反演)
题目链接: http://codeforces.com/contest/1139/problem/D 题意: 在$1$到$m$中选择一个数,加入到一个初始为空的序列中,当序列的$gcd$和为$1$时, ...
- 使用python抓取数据之菜鸟爬虫1
''' Created on 2018-5-27 @author: yaoshuangqi ''' #本代码获取百度乐彩网站上的信息,只获取最近100期的双色球 import urllib.reque ...
- 第二部分之Redis服务器(第十四章)
Redis服务器复制和多个客户端建立网络连接,处理客户端发送的命令请求,在数据库中保存客户端执行命令所产生的数据. 一,命令请求的执行过程 客户端向服务器发送命令请求 set key value 服务 ...
- vscode 安装插件SVN 报vscode SVN not found
1.软件环境 svn客户端安装的是TortoiseSVN: vscode 安装的为SVN的插件: 2. 问题现象 vscode打开文件夹后右下角提示如下报错:SVN not found. Instal ...
- linux ps aux 各列内容说明
[root@zabbix3 ~]# ps auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot ...
- 使用nio遍历文件夹
1.递归方式: private static void print(File f){ if(f!=null){ if(f.isDirectory()){ File[] fileArray=f.list ...
- Appium环境搭建-精简版
Appium自动化环境准备 安装配置JDK 下载Android SDK并配置环境变量 安装模拟器或连接真机 安装appium desktop 安装python和pycharm (开发语言和开发工具) ...