您正在查看: EOS 分类下的文章

基于Bancor 算法两种资源互换的算法讲解

场景

BCS Token 购买 FF 资源

算法文字描述

FF Bancor 算法过程中,并不是将 BCS 和 FF 直接用价格曲线进行兑换,而是引入了中间 token——FFCORE,对应于 Bancor 中的 Smart Token。

BCS 到 FF 的兑换过程就涉及了两个公式,所以上文中用一个公式来举例就很不严谨,只是为了定性的说明价格特性。

从代码中可看到BCS与FFCORE的兑换公式为:

其中,E为BCS到FFCORE所能兑换的数量,R是FFCORE的初始发行总量,C1为当前BCS余量,T1为用于购买的FF数量,F为常量参数

将上述公式的进行反向整理设计,即可得到FFCORE与交易额的兑换公式为:

其中,T2是准备购入的FF数量;C2为可分配的FF余量。将中间变量E代入即可得出用于购买的BCS数量(T1)与可兑换到的FF数量(T2)之间的关系。

为方便直观的理解,可以对公式进行简化,得到:

可以看到随着可买FF余量(C2)的降低或者BCS数量(C1)的增多,FF的价格会加速增长(即同样付出T1的BCS下,可换取到的FF数量T2变少了)

cleos get table name,无法精准定位

当get table索引是name 时,无法精准查询
因为cleos 传入的参数默认是字符串,需要对应的转换参数
--key-type name

例如

cleos -u https://api.eosnewyork.io:443 get table eosio eosio voters --key-type name -L 111111111122 -l 1

参考

https://github.com/EOSIO/eos/issues/5019

EOS dump 以及 ubuntu设置coredump

EOS 编译Debug

./scripts/eosio_build.sh -o Debug

ubuntu设置coredump

sudo sysctl -w kernel.core_pattern=/corefiles/core.%p.%e
sudo mkdir /corefiles
sudo chmod -R 777 /corefiles
ulimit -c unlimited

nodeos异常退出时,就会在/corefiles/生成dump文件

EOS account下的ram_quota与ram_bytes有什么关系

查看插件返回(github)

 rm.get_account_limits( result.account_name, result.ram_quota, result.net_weight, result.cpu_weight );

查看资源设置(github)

set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, net, cpu );

结论

ram_bytes是实际买的RAM 大小,ram_quota 是加上了 赠送的ram_gift_bytes(等于1400)(github)

验证

cleos -u https://api.eoslaomao.com get account bcskillsurou

返回

memory:
     quota:     4.348 KiB    used:      3.49 KiB

查看账户资源表

cleos -u https://api.eoslaomao.com get table eosio bcskillsurou userres

返回

{
  "rows": [{
      "owner": "bcskillsurou",
      "net_weight": "0.0046 EOS",
      "cpu_weight": "0.0147 EOS",
      "ram_bytes": 3052
    }
  ],
  "more": false,
  "next_key": ""
}

计算
quota 与 ram_bytes差值等于 1400,与ram_gift_bytes值一致。

Transaction exceeded the current CPU usage limit imposed on the transaction

最近链发送交易过大时容易发生一下错误

{
    "message": "Internal Service Error",
    "code": "500",
    "error": {
        "code": "3080004",
        "name": "tx_cpu_usage_exceeded",
        "what": "Transaction exceeded the current CPU usage limit imposed on the transaction",
        "details": [{
            "message": "transaction was executing for too long",
            "file": "transaction_context.cpp",
            "line_number": 488,
            "method": "checktime"
        }, {
            "message": "pending console output: ",
            "file": "apply_context.cpp",
            "line_number": 113,
            "method": "exec_one"
        }]
    }
}

根据错误信息,定位源代码位置 (github

由于now > _deadline并且 deadline_exception_code == tx_cpu_usage_exceeded::code_value 走到此断言逻辑
倒推到函数调用位置(github

checktime(); // Fail early if deadline has already been exceeded

提示信息为:如果已超过截止日期,则提早失败
继续反推代码
由于(github)交易组装时trx.max_cpu_usage_ms固定设置的0。所以,判断逻辑出自(github

// Possibly lower objective_duration_limit to the maximum cpu usage a transaction is allowed to be billed
if( cfg.max_transaction_cpu_usage <= objective_duration_limit.count() ) {
    objective_duration_limit = fc::microseconds(cfg.max_transaction_cpu_usage);
    billing_timer_exception_code = tx_cpu_usage_exceeded::code_value;
    _deadline = start + objective_duration_limit;
}
auto& rl = control.get_mutable_resource_limits_manager();
objective_duration_limit = fc::microseconds( rl.get_block_cpu_limit() );
_deadline = start + objective_duration_limit;
if(now > _deadline) {
    // 报异常
}

get_mutable_resource_limits_manager(github

resource_limits_manager&         controller::get_mutable_resource_limits_manager()
{
   return my->resource_limits;
}

get_block_cpu_limit(github

uint64_t resource_limits_manager::get_block_cpu_limit() const {
   const auto& state = _db.get<resource_limits_state_object>();
   const auto& config = _db.get<resource_limits_config_object>();
   return config.cpu_limit_parameters.max - state.pending_cpu_usage;
}

跟进停止

发现是由于合约中使用了std::vector<std::string> 持续存储大量数据,导致单次CPU运算执行耗时持续增长。

结论

当合约中Table单条记录中,如果使用vector不要存储过多数据,以及数据结构过于复杂的struct
如有对应需求,可以拆分子表,然后使用子表记录id索引对应。