成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

EOS源碼解析 使用多線程從簽名生成對(duì)應(yīng)公鑰

mist14 / 1878人閱讀

摘要:區(qū)塊多線程簽名改動(dòng)同步區(qū)塊時(shí)進(jìn)行多線程簽名,過(guò)程中依然是單線程簽名。代碼解析塊簽名因?yàn)椴贿m用多線程簽名,所以依舊沿用之前的簽名代碼,而同步則使用了新的部分。當(dāng)大家比較關(guān)注的使用并沒有得到改善,因?yàn)槎嗑€程簽名無(wú)法應(yīng)該在生產(chǎn)區(qū)塊上。

昨天早上,EOS 1.5.0 release 版本發(fā)布了。這次比較大改動(dòng)點(diǎn)是在多線程簽名上面。它將同步區(qū)塊時(shí)的 block 簽名驗(yàn)證和 trx 簽名驗(yàn)證都使用多線程簽名驗(yàn)證,來(lái)節(jié)省同步所需要的時(shí)間, 但是生產(chǎn)區(qū)塊所需要的成本是不變的,但為什么生產(chǎn)區(qū)塊成本不變呢。接下來(lái)介紹一下具體的改動(dòng)。

 區(qū)塊多線程簽名改動(dòng):同步區(qū)塊時(shí)進(jìn)行多線程簽名, replay 過(guò)程中依然是單線程簽名。因?yàn)閰^(qū)塊同步時(shí)需要回滾 pending block 的 trx 操作, 這塊時(shí)間剛好可以用來(lái)并行處理簽名, 但 replay 的時(shí)候沒有這一步,即使用多線程簽名也無(wú)法節(jié)省時(shí)間,反而會(huì)讓主線程阻塞等待異步結(jié)果返回。

 trx 多線程簽名改動(dòng):同步區(qū)塊以及 replay 過(guò)程都會(huì)進(jìn)行多線程簽名, 因?yàn)橛卸鄠€(gè) trx 要執(zhí)行,所以執(zhí)行 trx 的時(shí)間可以供其他 trx 的簽名并行進(jìn)行。 但生產(chǎn)區(qū)塊的時(shí)候無(wú)法使用,因?yàn)閳?zhí)行 BP 接受到一個(gè) 廣播的 trx 就立馬去執(zhí)行了,執(zhí)行完之后才回去接受下一個(gè)廣播 trx, 所以無(wú)法使用多線程簽名。


代碼解析: 塊簽名:

因?yàn)?replay 不適用多線程簽名, 所以 replay 依舊沿用之前的簽名代碼, 而同步則使用了新的部分。

// producer_plugin.cpp 接受到廣播塊
void on_incoming_block(const signed_block_ptr& block) {
   // ...

   // start processing of block
   // 調(diào)用一個(gè)線程去對(duì)塊進(jìn)行簽名驗(yàn)證
   auto bsf = chain.create_block_state_future( block );

   // abort the pending block
   // 回滾掉 pending block 的執(zhí)行 trx, 這段時(shí)間剛好可以用來(lái)并發(fā)執(zhí)行區(qū)塊簽名驗(yàn)證
   chain.abort_block();

   // ...
}

// controller.cpp
std::future create_block_state_future( const signed_block_ptr& b ) {

   //驗(yàn)證區(qū)塊是否存在。
   EOS_ASSERT( b, block_validate_exception, "null block" );

   auto id = b->id();

   // no reason for a block_state if fork_db already knows about block
   auto existing = fork_db.get_block( id );
   EOS_ASSERT( !existing, fork_database_exception, "we already know about this block: ${id}", ("id", id) );

   auto prev = fork_db.get_block( b->previous );
   EOS_ASSERT( prev, unlinkable_block_exception, "unlinkable block ${id}", ("id", id)("previous", b->previous) );

   // 進(jìn)行多線程簽名
   return async_thread_pool( [b, prev]() {
      const bool skip_validate_signee = false;
      return std::make_shared( *prev, move( b ), skip_validate_signee );
   } );
}

void push_block( std::future& block_state_future ) {
   controller::block_status s = controller::block_status::complete;
   EOS_ASSERT(!pending, block_validate_exception, "it is not valid to push a block when there is a pending block");

   auto reset_prod_light_validation = fc::make_scoped_exit([old_value=trusted_producer_light_validation, this]() {
      trusted_producer_light_validation = old_value;
   });
   try {
      // 獲取驗(yàn)證結(jié)果, 當(dāng)區(qū)塊驗(yàn)證失敗時(shí)會(huì)拋出異常,中止 push block
      block_state_ptr new_header_state = block_state_future.get();
      auto& b = new_header_state->block;
      emit( self.pre_accepted_block, b );

      fork_db.add( new_header_state, false );

      if (conf.trusted_producers.count(b->producer)) {
         trusted_producer_light_validation = true;
      };
      emit( self.accepted_block_header, new_header_state );

      if ( read_mode != db_read_mode::IRREVERSIBLE ) {
         maybe_switch_forks( s );
      }

   } FC_LOG_AND_RETHROW( )
}
交易簽名

從改動(dòng)得知,apply_block 的時(shí)候才會(huì)啟動(dòng)交易的多線程驗(yàn)證簽名,而 bcast_transaction 則不會(huì),因?yàn)椴]有多余的動(dòng)作可以與驗(yàn)證簽名并行。

void apply_block( const signed_block_ptr& b, controller::block_status s ) { try {
   try {
      EOS_ASSERT( b->block_extensions.size() == 0, block_validate_exception, "no supported extensions" );
      auto producer_block_id = b->id();
      start_block( b->timestamp, b->confirmed, s , producer_block_id);

      // 按順序啟動(dòng)每個(gè) trx 的多線程驗(yàn)證簽名,生產(chǎn)對(duì)應(yīng)公鑰
      std::vector packed_transactions;
      packed_transactions.reserve( b->transactions.size() );
      for( const auto& receipt : b->transactions ) {
         if( receipt.trx.contains()) {
            auto& pt = receipt.trx.get();
            auto mtrx = std::make_shared( pt );
            if( !self.skip_auth_check() ) {
               std::weak_ptr mtrx_wp = mtrx;
               mtrx->signing_keys_future = async_thread_pool( [chain_id = this->chain_id, mtrx_wp]() {
                  auto mtrx = mtrx_wp.lock();
                  return mtrx ?
                         std::make_pair( chain_id, mtrx->trx.get_signature_keys( chain_id ) ) :
                         std::make_pair( chain_id, decltype( mtrx->trx.get_signature_keys( chain_id ) ){} );
               } );
            }
            packed_transactions.emplace_back( std::move( mtrx ) );
         }
      }

      // 執(zhí)行 trx
      // ...

      commit_block(false);
      return;
   } catch ( const fc::exception& e ) {
      edump((e.to_detail_string()));
      abort_block();
      throw;
   }
} FC_CAPTURE_AND_RETHROW() } /// apply_block

// trx 執(zhí)行時(shí)獲取簽名返回的公鑰
const flat_set& recover_keys( const chain_id_type& chain_id ) {
   // Unlikely for more than one chain_id to be used in one nodeos instance
   if( !signing_keys || signing_keys->first != chain_id ) {
      if( signing_keys_future.valid() ) {
         // 獲取公鑰,如果未簽名完則阻塞等待簽名完畢
         signing_keys = signing_keys_future.get();
         if( signing_keys->first == chain_id ) {
            return signing_keys->second;
         }
      }
      // 當(dāng)沒開啟多線程簽名時(shí), 直接驗(yàn)證生成對(duì)應(yīng)公鑰
      signing_keys = std::make_pair( chain_id, trx.get_signature_keys( chain_id ));
   }
   return signing_keys->second;
}
總結(jié)
    從這次的改動(dòng)可以看出主要優(yōu)化的地方是節(jié)點(diǎn)同步區(qū)塊的速度, 因?yàn)殚_啟了多線程簽名,所以在 block 驗(yàn)證以及 apply_block 時(shí)節(jié)省了一定 CPU 時(shí)間, 可供其他地方使用。 例如 EOS 現(xiàn)在是當(dāng)線程的,所以當(dāng)你進(jìn)行 RPC 訪問的時(shí)候,如果涉及到數(shù)據(jù)提取,主線程的同步時(shí)會(huì)暫停的,等待你的操作結(jié)束, 這樣就會(huì)影響節(jié)點(diǎn)的同步,所以 get_table_rows API 才會(huì)限制 10 ms。 現(xiàn)在同步所需時(shí)間減少,降低了節(jié)點(diǎn)既要同步數(shù)據(jù)也要提供 RPC API 的壓力。

當(dāng)大家比較關(guān)注的 CPU 使用并沒有得到改善, 因?yàn)槎嗑€程簽名無(wú)法應(yīng)該在生產(chǎn)區(qū)塊上。所以在生產(chǎn)區(qū)塊時(shí), trx 執(zhí)行所需要的 CPU 時(shí)間并不會(huì)減少,也就是 CPU 資源的使用并沒有得到改善。

EOS 開發(fā)的小伙伴有技術(shù)問題可以進(jìn)群討論喲

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/24469.html

相關(guān)文章

  • EOS入門指南——PART3 如何創(chuàng)建賬戶

    摘要:最后一步付款和比特幣以及以太坊不一樣的是,在創(chuàng)建賬戶是有成本的,這也就是為什么我們需要一個(gè)賬戶才能創(chuàng)建賬戶的原因找個(gè)人來(lái)買單。 之前我們學(xué)習(xí)了如何編譯EOS程序,以及如何連接到EOS主網(wǎng),接下來(lái)我們要談一談大家最關(guān)心的,如何創(chuàng)建自己的EOS賬戶。 摘要 這篇我們會(huì)學(xué)習(xí)如何創(chuàng)建錢包、秘鑰對(duì)、主網(wǎng)賬戶,向大家介紹一些實(shí)用工具。最重要的是,我們會(huì)學(xué)習(xí)到在EOS里,公鑰和賬戶到底有什么區(qū)別。 ...

    oliverhuang 評(píng)論0 收藏0
  • 【劉杰良】使用RPC接口新建EOS賬戶 - 實(shí)戰(zhàn)

    摘要:適用于最新的前言最近在研究的,但是由于官方文檔的不夠詳盡,新建賬號(hào)這一個(gè)操作就折騰了一個(gè)多星期?;侍觳回?fù)有心人,終于調(diào)通了新建賬號(hào),代幣轉(zhuǎn)賬也輕松解決。 適用于最新的 EOS Dawn 4.0/4.1 前言 最近在研究 EOS 的 RPC API,但是由于官方API文檔的不夠詳盡,新建賬號(hào)(new account)這一個(gè)操作就折騰了一個(gè)多星期?;侍觳回?fù)有心人,終于調(diào)通了新建賬號(hào),代幣轉(zhuǎn)...

    Little_XM 評(píng)論0 收藏0
  • EOS】名詞解釋

    摘要:在對(duì)一個(gè)交易進(jìn)行簽名時(shí),與之間會(huì)發(fā)生交互。錢包通過(guò)將鎖定的鍵值本地化存儲(chǔ)的方式,實(shí)現(xiàn)以安全的方式活動(dòng)簽名。表示已解鎖,創(chuàng)建一個(gè)錢包默認(rèn)是解鎖狀態(tài)錢包必須是狀態(tài)。自定義命名權(quán)限這些權(quán)限可用于進(jìn)一步擴(kuò)展帳戶管理。 account 介紹 帳戶是授權(quán)的集合,存儲(chǔ)在區(qū)塊鏈上,用于標(biāo)識(shí)發(fā)送方/接收方。它具有靈活的授權(quán)結(jié)構(gòu),允許根據(jù)權(quán)限的配置方式由個(gè)人或一組個(gè)人擁有。向區(qū)塊鏈發(fā)送或接收有效交易需要一...

    stackvoid 評(píng)論0 收藏0
  • 【許曉笛】EOS 上線前,先搞懂這兩個(gè)基本概念

    摘要:的跟其他區(qū)塊鏈項(xiàng)目是類似的,都是一個(gè)基本功能本地儲(chǔ)存密鑰,僅此而已。公網(wǎng)上線后,一定要將存有密鑰的加密,并且將文件單獨(dú)備份好。字面意思是賬戶,但我覺得有個(gè)概念更適合法人。代幣就是由持有的。對(duì)于權(quán)限,則需要列表里至少兩個(gè)賬戶的授權(quán)才能行使。 如果你曾經(jīng)嘗試在本地運(yùn)行 EOS 測(cè)試節(jié)點(diǎn),會(huì)發(fā)現(xiàn)編譯、運(yùn)行并不是特別復(fù)雜,但官方教程里兩個(gè)概念很容易把人搞暈: Account(賬戶) 和 Wal...

    alogy 評(píng)論0 收藏0
  • 【劉文彬】【源碼解讀】EOS測(cè)試插件:txn_test_gen_plugin.cpp

    摘要:,調(diào)用函數(shù),重置標(biāo)志位為,計(jì)時(shí)器關(guān)閉,打印關(guān)閉提示日志。設(shè)定計(jì)時(shí)器的異步定時(shí)任務(wù),任務(wù)體直接調(diào)用函數(shù),對(duì)函數(shù)的返回值進(jìn)行處理,如果有報(bào)錯(cuò)信息一般是服務(wù)中止則調(diào)用函數(shù)關(guān)閉插件。 原文鏈接:醒者呆的博客園,https://www.cnblogs.com/Evswa... 本文內(nèi)容本屬于《【精解】EOS TPS 多維實(shí)測(cè)》的內(nèi)容,但由于在編寫時(shí)篇幅過(guò)長(zhǎng),所以我決定將這一部分單獨(dú)成文撰寫,以便...

    dinfer 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<