eos代码阅读笔记06- 从cleos到 nodeos 请求/响应流程

用cleos get info 为例子,看看从cleos 客户端发送请求到 nodeos 全流程,共三步骤:

1.cleos使用接口

2.nodeos接口定义

3.nodeos接口实现


cleos使用接口

eos/programs/cleos/main.cpp

定义url,返回结果 eosio::chain_apis::read_only::get_info_results定义在plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp

string url = "http://localhost:8888/";
eosio::chain_apis::read_only::get_info_results get_info() {
   return call(url, get_info_func).as<eosio::chain_apis::read_only::get_info_results>();
}
get_info_func的定义

eos/programs/cleos/httpc.hpp

const string chain_func_base = "/v1/chain";
const string get_info_func = chain_func_base + "/get_info";

nodeos接口定义

plugins/chain_api_plugin/chain_api_plugin.cpp

void chain_api_plugin::plugin_startup() {
   ilog( "starting chain_api_plugin" );
   my.reset(new chain_api_plugin_impl(app().get_plugin<chain_plugin>().chain()));
   auto ro_api = app().get_plugin<chain_plugin>().get_read_only_api();
   auto rw_api = app().get_plugin<chain_plugin>().get_read_write_api();

   app().get_plugin<http_plugin>().add_api({
      CHAIN_RO_CALL(get_info, 200l),
      CHAIN_RO_CALL(get_block, 200),
      CHAIN_RO_CALL(get_block_header_state, 200),
      CHAIN_RO_CALL(get_account, 200),
      CHAIN_RO_CALL(get_code, 200),
      CHAIN_RO_CALL(get_abi, 200),
      CHAIN_RO_CALL(get_table_rows, 200),
      CHAIN_RO_CALL(get_currency_balance, 200),
      CHAIN_RO_CALL(get_currency_stats, 200),
      CHAIN_RO_CALL(get_producers, 200),
      CHAIN_RO_CALL(abi_json_to_bin, 200),
      CHAIN_RO_CALL(abi_bin_to_json, 200),
      CHAIN_RO_CALL(get_required_keys, 200),
      CHAIN_RW_CALL_ASYNC(push_block, chain_apis::read_write::push_block_results, 202),
      CHAIN_RW_CALL_ASYNC(push_transaction, chain_apis::read_write::push_transaction_results, 202),
      CHAIN_RW_CALL_ASYNC(push_transactions, chain_apis::read_write::push_transactions_results, 202)
   });
}

plugins/chain_plugin/include/eosio/chain_plugin/chain_plugin.hpp

定义 get_info 方法

class read_only {
   const controller& db;

public:
   static const string KEYi64;

   read_only(const controller& db)
      : db(db) {}

   using get_info_params = empty;

   struct get_info_results {
      string                  server_version;
      chain::chain_id_type    chain_id;
      uint32_t                head_block_num = 0;
      uint32_t                last_irreversible_block_num = 0;
      chain::block_id_type    last_irreversible_block_id;
      chain::block_id_type    head_block_id;
      fc::time_point          head_block_time;
      account_name            head_block_producer;

      uint64_t                virtual_block_cpu_limit = 0;
      uint64_t                virtual_block_net_limit = 0;

      uint64_t                block_cpu_limit = 0;
      uint64_t                block_net_limit = 0;
      //string                  recent_slots;
      //double                  participation_rate = 0;
   };
   get_info_results get_info(const get_info_params&) const;
nodeos接口实现:

plugins/chain_plugin/chain_plugin.hpp 实现get_info

namespace chain_apis {
const string read_only::KEYi64 = "i64";
read_only::get_info_results read_only::get_info(const read_only::get_info_params&) const {
   const auto& rm = db.get_resource_limits_manager();
   return {
      eosio::utilities::common::itoh(static_cast<uint32_t>(app().version())),
      db.get_chain_id(),
      db.head_block_num(),
      db.last_irreversible_block_num(),
      db.last_irreversible_block_id(),
      db.head_block_id(),
      db.head_block_time(),
      db.head_block_producer(),
      rm.get_virtual_block_cpu_limit(),
      rm.get_virtual_block_net_limit(),
      rm.get_block_cpu_limit(),
      rm.get_block_net_limit()
      //std::bitset<64>(db.get_dynamic_global_properties().recent_slots_filled).to_string(),
      //__builtin_popcountll(db.get_dynamic_global_properties().recent_slots_filled) / 64.0
   };
}

再看看wallet方面的接口流程

cleos使用接口

httpc.hpp

const string wallet_func_base = "/v1/wallet";
const string wallet_sign_trx = wallet_func_base + "/sign_transaction";

main.cpp

void sign_transaction(signed_transaction& trx, fc::variant& required_keys, const chain_id_type& chain_id) {
   fc::variants sign_args = {fc::variant(trx), required_keys, fc::variant(chain_id)};
   const auto& signed_trx = call(wallet_url, wallet_sign_trx, sign_args);
   trx = signed_trx.as<signed_transaction>();
}
nodeos接口定义:wallet_api_plugin.cpp
app().get_plugin<http_plugin>().add_api({

       CALL(wallet, wallet_mgr, sign_transaction,
            INVOKE_R_R_R_R(wallet_mgr, sign_transaction, chain::signed_transaction, flat_set<public_key_type>, chain::chain_id_type), 201),

nodeos接口实现

wallet_plugin.cpp实现插件功能,具体功能在 wallet_manager.hpp实现

/// Sign transaction with the private keys specified via their public keys. 通过其公钥指定的私钥签署事务
   /// Use chain_controller::get_required_keys to determine which keys are needed for txn.
   /// @param txn the transaction to sign.要签署的事务
   /// @param keys the public keys of the corresponding private keys to sign the transaction with
   /// @param id the chain_id to sign transaction with. 
   /// @return txn signed 返回签名
   /// @throws fc::exception if corresponding private keys not found in unlocked wallets 如果未解锁的钱包中没有找到相应的私钥,则将出现异常
   chain::signed_transaction sign_transaction(const chain::signed_transaction& txn, const flat_set<public_key_type>& keys,
                                             const chain::chain_id_type& id);

wallet_manager.cpp

chain::signed_transaction
wallet_manager::sign_transaction(const chain::signed_transaction& txn, const flat_set<public_key_type>& keys, const chain::chain_id_type& id) {
   check_timeout();
   chain::signed_transaction stxn(txn);

   for (const auto& pk : keys) {
      bool found = false;
      for (const auto& i : wallets) {
         if (!i.second->is_locked()) {
            optional<signature_type> sig = i.second->try_sign_digest(stxn.sig_digest(id, stxn.context_free_data), pk);
            if (sig) {
               stxn.signatures.push_back(*sig);
               found = true;
               break; // inner for
            }
         }
      }
      if (!found) {
         EOS_THROW(chain::wallet_missing_pub_key_exception, "Public key not found in unlocked wallets ${k}", ("k", pk));
      }
   }

   return stxn;
}









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值