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

資訊專欄INFORMATION COLUMN

【劉文彬】【源碼解讀】EOS測試插件:txn_test_gen_plugin.cpp

dinfer / 3568人閱讀

摘要:,調(diào)用函數(shù),重置標(biāo)志位為,計(jì)時(shí)器關(guān)閉,打印關(guān)閉提示日志。設(shè)定計(jì)時(shí)器的異步定時(shí)任務(wù),任務(wù)體直接調(diào)用函數(shù),對函數(shù)的返回值進(jìn)行處理,如果有報(bào)錯(cuò)信息一般是服務(wù)中止則調(diào)用函數(shù)關(guān)閉插件。

原文鏈接:醒者呆的博客園,https://www.cnblogs.com/Evswa...

本文內(nèi)容本屬于《【精解】EOS TPS 多維實(shí)測》的內(nèi)容,但由于在編寫時(shí)篇幅過長,所以我決定將這一部分多帶帶成文撰寫,以便于理解。

關(guān)鍵字:eos, txn_test_gen_plugin, signed_transaction, ordered_action_result, C++, EOS插件

txn_test_gen_plugin 插件

這個(gè)插件是官方開發(fā)用來測試塊打包交易量的,這種方式由于是直接系統(tǒng)內(nèi)部調(diào)用來模擬transaction,沒有中間通訊的損耗,因此效率是非常高的,官方稱通過這個(gè)插件測試到了8000的tps結(jié)果,而就我的測試結(jié)果來講,沒有這么恐怖,但也能到2000了,熟不知,其他的測試手段,例如cleos,eosjs可能只有百級的量。下面,我們一同來研究一下這個(gè)插件是如何實(shí)現(xiàn)以上功能的,過程中,我們也會(huì)思考EOS插件的架構(gòu)體系,以及實(shí)現(xiàn)方法。通過本文的學(xué)習(xí),如果有好的想法,我們也可以自己開發(fā)一個(gè)功能強(qiáng)大的插件pr給eos,為EOS社區(qū)做出我們自己的貢獻(xiàn)。

關(guān)于txn_test_gen_plugin插件的使用,非常易于上手,本文不做分析,這方面可以直接參考官方文檔。
插件的整體架構(gòu)

插件代碼整體結(jié)構(gòu)中,我們上面介紹的核心功能的實(shí)現(xiàn)函數(shù)都是包含在一個(gè)結(jié)構(gòu)體struct txn_test_gen_plugin_impl中。剩余的其他代碼都是對插件本身的通訊進(jìn)行描述,包括如何調(diào)用,如何響應(yīng)等,以及整個(gè)插件的生命周期的控制:

set_program_options,設(shè)置參數(shù)的階段,是最開始的階段,內(nèi)容只設(shè)置了txn-reference-block-lag的值,默認(rèn)是0,-1代表最新頭區(qū)塊。

plugin_initialize,這一時(shí)期就把包含核心功能的結(jié)構(gòu)體txn_test_gen_plugin_impl加載到程序運(yùn)行時(shí)內(nèi)存中了,同時(shí)初始化標(biāo)志位txn_reference_block_lag為txn-reference-block-lag的值。

plugin_startup,我們通過基礎(chǔ)插件http_plugin的支持獲得了http接口的能力,這一時(shí)期,就暴露出來本插件的對外接口。

plugin_shutdown,調(diào)用stop_generation函數(shù),重置標(biāo)志位running為false,計(jì)時(shí)器關(guān)閉,打印關(guān)閉提示日志。

下面是對外暴露的三個(gè)接口之一的stop_generation函數(shù)的源碼:

void stop_generation() {
    if(!running)
        throw fc::exception(fc::invalid_operation_exception_code);
    timer.cancel();
    running = false;
    ilog("Stopping transaction generation test");
}

接下來,我們主要集中精力在結(jié)構(gòu)體txn_test_gen_plugin_impl上,研究路線是以剩余兩個(gè)接口分別為入口進(jìn)行逐一分析。

create_test_accounts 接口

關(guān)于這個(gè)接口,調(diào)用方法是

curl --data-binary "["eosio", "5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"]" http://localhost:8888/v1/txn_test_gen/create_test_accounts

傳入的參數(shù)是eosio以及其私鑰。我們進(jìn)入到函數(shù)create_test_accounts中去分析源碼。

準(zhǔn)備知識(shí)

首先,整個(gè)函數(shù)涉及到的所有transaction都是打包存入到一個(gè)vector集合std::vector中去。

trxs是一個(gè)事務(wù)集,它包含很多的trx,而其中每一個(gè)trx包含一個(gè)actions集合vector
一、準(zhǔn)備賬戶

trxs的第一個(gè)trx,內(nèi)容為賬戶創(chuàng)建:

定義3個(gè)賬戶:txn.test.a,txn.test.b, txn.test.t

輔助功能:controller& cc = app().get_plugin().chain();,通過cc可以隨時(shí)調(diào)用本地區(qū)塊鏈上的任意信息。

通過fc::crypto::private_key::regenerate函數(shù)分別生成他們的私鑰,要傳入生成秘鑰的seed。

通過私鑰直接調(diào)用get_public_key()即可獲得公鑰

設(shè)置每個(gè)賬戶的owner和active權(quán)限對應(yīng)的公鑰,一般來講他們是相同的

賬戶的創(chuàng)建者均為我們外部調(diào)用create_test_accounts接口時(shí)傳入的賬戶eosio,注意:eosio的私鑰是通過字符串傳入的,要通過fc::crypto::private_key轉(zhuǎn)換成私鑰對象

將每一個(gè)賬戶的創(chuàng)建組裝好成為一個(gè)action,存入trx的actions集合中去。

trx的actions成員已經(jīng)設(shè)置完畢,完成剩余trx的組裝工作,包括

expiration,通過cc獲得當(dāng)前頭區(qū)塊的時(shí)間,加上延遲時(shí)間,這里是30s,fc::seconds(30)

reference_block,值為通過cc獲取當(dāng)前的頭區(qū)塊,意思為本transaction的引用區(qū)塊,所有的信息是引用的這個(gè)區(qū)塊為頭區(qū)塊的環(huán)境

sign,簽名,使用的是創(chuàng)建者eosio的私鑰對象,上面我們已經(jīng)準(zhǔn)備好了,簽名的數(shù)據(jù)是data的摘要

當(dāng)前trx的actions中的元素的data并不是如文首的transaction中的data的加密串的結(jié)構(gòu),而是明文的,這里的加密是數(shù)字摘要技術(shù),感興趣的朋友可以去《應(yīng)用密碼學(xué)初探》進(jìn)行了解。

摘要的源碼函數(shù)是:sig_digest(chain_id, context_free_data),其中參數(shù)使用到了chain_id,而context_free_data就是上面提到的明文data內(nèi)容,所以它是要與鏈id一起做數(shù)字摘要的(這一點(diǎn)我在使用eosjs嘗試自己做摘要的時(shí)候并未想到)

這一部分的源碼展示如下:

name newaccountA("txn.test.a");
name newaccountB("txn.test.b");
name newaccountC("txn.test.t");
name creator(init_name);

abi_def currency_abi_def = fc::json::from_string(eosio_token_abi).as();

controller& cc = app().get_plugin().chain();
auto chainid = app().get_plugin().get_chain_id();

fc::crypto::private_key txn_test_receiver_A_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, "a")));
fc::crypto::private_key txn_test_receiver_B_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, "b")));
fc::crypto::private_key txn_test_receiver_C_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, "c")));
fc::crypto::public_key  txn_text_receiver_A_pub_key = txn_test_receiver_A_priv_key.get_public_key();
fc::crypto::public_key  txn_text_receiver_B_pub_key = txn_test_receiver_B_priv_key.get_public_key();
fc::crypto::public_key  txn_text_receiver_C_pub_key = txn_test_receiver_C_priv_key.get_public_key();
fc::crypto::private_key creator_priv_key = fc::crypto::private_key(init_priv_key);

//create some test accounts
{
    signed_transaction trx;
    
    //create "A" account
    {
        auto owner_auth   = eosio::chain::authority{1, {{txn_text_receiver_A_pub_key, 1}}, {}};
        auto active_auth  = eosio::chain::authority{1, {{txn_text_receiver_A_pub_key, 1}}, {}};
        trx.actions.emplace_back(vector{{creator,"active"}}, newaccount{creator, newaccountA, owner_auth, active_auth});
    }
    //create "B" account
    {
        auto owner_auth   = eosio::chain::authority{1, {{txn_text_receiver_B_pub_key, 1}}, {}};
        auto active_auth  = eosio::chain::authority{1, {{txn_text_receiver_B_pub_key, 1}}, {}};
        trx.actions.emplace_back(vector{{creator,"active"}}, newaccount{creator, newaccountB, owner_auth, active_auth});
    }
    //create "txn.test.t" account
    {
        auto owner_auth   = eosio::chain::authority{1, {{txn_text_receiver_C_pub_key, 1}}, {}};
        auto active_auth  = eosio::chain::authority{1, {{txn_text_receiver_C_pub_key, 1}}, {}};
        trx.actions.emplace_back(vector{{creator,"active"}}, newaccount{creator, newaccountC, owner_auth, active_auth});
    }
    trx.expiration = cc.head_block_time() + fc::seconds(30);
    trx.set_reference_block(cc.head_block_id());
    trx.sign(creator_priv_key, chainid);
    trxs.emplace_back(std::move(trx));
}
二、token相關(guān)

trxs的第二個(gè)trx,內(nèi)容為token創(chuàng)建和issue,為賬戶轉(zhuǎn)賬為之后的測試做準(zhǔn)備

為賬戶txn.test.t設(shè)置eosio.token合約,之前在操作cleos set contract的時(shí)候可以通過打印結(jié)果發(fā)現(xiàn),是有setcode和setabi兩個(gè)步驟的。

setcode handler:

設(shè)置handler的賬戶為txn.test.t

將wasm設(shè)置為handler的code,wasm是通過eosio.token合約的eosio_token_wast文件獲取的,vector wasm = wast_to_wasm(std::string(eosio_token_wast))

將handler加上相關(guān)權(quán)限組裝成action裝入trx的actions集合中。

setabi handler:

設(shè)置handler的賬戶為txn.test.t

設(shè)置handler的abi,將文件eosio_token_abi(json格式的)轉(zhuǎn)成json轉(zhuǎn)儲(chǔ)為abi_def結(jié)構(gòu),然后通過fc::raw::pack操作將結(jié)果賦值給abi

將handler加上相關(guān)權(quán)限組裝成action裝入trx的actions集合中。

使用賬戶txn.test.t創(chuàng)建token,標(biāo)志位CUR,總發(fā)行量十億,裝成action裝入trx的actions集合中。

issue CUR 給txn.test.t 600枚CUR,裝成action裝入trx的actions集合中。

從txn.test.t轉(zhuǎn)賬給txn.test.a 200枚CUR,裝成action裝入trx的actions集合中。

從txn.test.t轉(zhuǎn)賬給txn.test.b 200枚CUR,裝成action裝入trx的actions集合中。

trx的actions成員已經(jīng)設(shè)置完畢,完成剩余trx的組裝工作(同上),這里只介紹不同的部分

max_net_usage_words,指定了網(wǎng)絡(luò)資源的最大使用限制為5000個(gè)詞。

這一部分的源碼展示如下:

//set txn.test.t contract to eosio.token & initialize it
{
    signed_transaction trx;
    vector wasm = wast_to_wasm(std::string(eosio_token_wast));
    setcode handler;
    handler.account = newaccountC;
    handler.code.assign(wasm.begin(), wasm.end());
    trx.actions.emplace_back( vector{{newaccountC,"active"}}, handler);
    
    {
        setabi handler;
        handler.account = newaccountC;
        handler.abi = fc::raw::pack(json::from_string(eosio_token_abi).as());
        trx.actions.emplace_back( vector{{newaccountC,"active"}}, handler);
    }
    {
        action act;
        act.account = N(txn.test.t);
        act.name = N(create);
        act.authorization = vector{{newaccountC,config::active_name}};
        act.data = eosio_token_serializer.variant_to_binary("create", fc::json::from_string("{"issuer":"txn.test.t","maximum_supply":"1000000000.0000 CUR"}}"));
        trx.actions.push_back(act);
    }
    {
        action act;
        act.account = N(txn.test.t);
        act.name = N(issue);
        act.authorization = vector{{newaccountC,config::active_name}};
        act.data = eosio_token_serializer.variant_to_binary("issue", fc::json::from_string("{"to":"txn.test.t","quantity":"600.0000 CUR","memo":""}"));
        trx.actions.push_back(act);
    }
    {
        action act;
        act.account = N(txn.test.t);
        act.name = N(transfer);
        act.authorization = vector{{newaccountC,config::active_name}};
        act.data = eosio_token_serializer.variant_to_binary("transfer", fc::json::from_string("{"from":"txn.test.t","to":"txn.test.a","quantity":"200.0000 CUR","memo":""}"));
        trx.actions.push_back(act);
    }
    {
        action act;
        act.account = N(txn.test.t);
        act.name = N(transfer);
        act.authorization = vector{{newaccountC,config::active_name}};
        act.data = eosio_token_serializer.variant_to_binary("transfer", fc::json::from_string("{"from":"txn.test.t","to":"txn.test.b","quantity":"200.0000 CUR","memo":""}"));
        trx.actions.push_back(act);
    }
    
    trx.expiration = cc.head_block_time() + fc::seconds(30);
    trx.set_reference_block(cc.head_block_id());
    trx.max_net_usage_words = 5000;
    trx.sign(txn_test_receiver_C_priv_key, chainid);
    trxs.emplace_back(std::move(trx));
}
發(fā)起請求

目前trxs集合已經(jīng)包含了兩個(gè)trx元素,其中每個(gè)trx包含了多個(gè)action。下面要將trxs推送到鏈上執(zhí)行

push_transactions函數(shù),遍歷trxs元素,每個(gè)trx多帶帶發(fā)送push_next_transaction

push_next_transaction函數(shù),首先將trx取出通過packed_transaction函數(shù)進(jìn)行組裝成post的結(jié)構(gòu)

packed_transaction函數(shù),通過set_transaction函數(shù)對trx進(jìn)行摘撿,使用pack_transaction函數(shù)進(jìn)行組裝

pack_transaction函數(shù),就是調(diào)用了一下上面提過的fc::raw::pack操作,然后通過accept_transaction函數(shù)向鏈發(fā)起請求

accept_transaction函數(shù),是chain_plugin的一個(gè)函數(shù),它內(nèi)部調(diào)用了incoming_transaction_async_method異步發(fā)起交易請求。

這部分代碼比較雜,分為幾個(gè)部分:

push_transactions函數(shù):

void push_transactions( std::vector&& trxs, const std::function& next ) {
    auto trxs_copy = std::make_shared>(std::move(trxs));
    push_next_transaction(trxs_copy, 0, next);
}

push_next_transaction函數(shù):

static void push_next_transaction(const std::shared_ptr>& trxs, size_t index, const std::function& next ) {
      chain_plugin& cp = app().get_plugin();
      cp.accept_transaction( packed_transaction(trxs->at(index)), [=](const fc::static_variant& result){
         if (result.contains()) {
            next(result.get());
         } else {
            if (index + 1 < trxs->size()) {
               push_next_transaction(trxs, index + 1, next);
            } else {
               next(nullptr);
            }
         }
      });
   }

packed_transaction函數(shù),set_transaction函數(shù)以及pack_transaction函數(shù)的代碼都屬于本插件源碼之外的EOS庫源碼,由于本身代碼量也較少,含義在上面已經(jīng)完全解釋過了,這里不再粘貼源碼。

accept_transaction函數(shù)也是EOS的庫源碼

void chain_plugin::accept_transaction(const chain::packed_transaction& trx, next_function next) {
    my->incoming_transaction_async_method(std::make_shared(trx), false, std::forward(next));
}

incoming_transaction_async_method(app().get_method())
start_generation 接口

該接口的調(diào)用方法是:

curl --data-binary "["", 20, 20]" http://localhost:8888/v1/txn_test_gen/start_generation

參數(shù)列表為:

第一個(gè)參數(shù)為 salt,一般用于“加鹽”加密算法的值,這里我們可以留空。

第二個(gè)參數(shù)為 period,發(fā)送交易的間隔時(shí)間,單位為ms,這里是20。

第三個(gè)參數(shù)為 batch_size,每個(gè)發(fā)送間隔周期內(nèi)打包交易的數(shù)量,這里也是20。

翻譯過來就是:每20ms提交20筆交易。

接下來,以start_generation 函數(shù)為入口進(jìn)行源碼分析。

start_generation 函數(shù)

校驗(yàn):

period的取值范圍為(1, 2500)

batch_size的取值范圍為(1, 250)

batch_size必須是2的倍數(shù),batch_size & 1結(jié)果為假0才可以,這是一個(gè)位運(yùn)算,與&,所以batch_size的值轉(zhuǎn)為二進(jìn)制時(shí)末位不能為1,所以就是2的倍數(shù)即可。

對標(biāo)志位running的控制。

這部分代碼展示如下:

if(running)
    throw fc::exception(fc::invalid_operation_exception_code);
if(period < 1 || period > 2500)
    throw fc::exception(fc::invalid_operation_exception_code);
if(batch_size < 1 || batch_size > 250)
    throw fc::exception(fc::invalid_operation_exception_code);
if(batch_size & 1)
    throw fc::exception(fc::invalid_operation_exception_code);

running = true;

定義兩個(gè)action,分別是:

賬戶txn.test.a給txn.test.b轉(zhuǎn)賬1000枚CUR

txn.test.b轉(zhuǎn)給txn.test.a同樣1000枚CUR

這部分代碼展示如下:

//create the actions here
act_a_to_b.account = N(txn.test.t);
act_a_to_b.name = N(transfer);
act_a_to_b.authorization = vector{{name("txn.test.a"),config::active_name}};
act_a_to_b.data = eosio_token_serializer.variant_to_binary("transfer", fc::json::from_string(fc::format_string("{"from":"txn.test.a","to":"txn.test.b","quantity":"1.0000 CUR","memo":"${l}"}", fc::mutable_variant_object()("l", salt))));

act_b_to_a.account = N(txn.test.t);
act_b_to_a.name = N(transfer);
act_b_to_a.authorization = vector{{name("txn.test.b"),config::active_name}};
act_b_to_a.data = eosio_token_serializer.variant_to_binary("transfer", fc::json::from_string(fc::format_string("{"from":"txn.test.b","to":"txn.test.a","quantity":"1.0000 CUR","memo":"${l}"}", fc::mutable_variant_object()("l", salt))));

接下來,是對參數(shù)period和batch_size的儲(chǔ)存為結(jié)構(gòu)體作用域的變量以供結(jié)構(gòu)體內(nèi)其他函數(shù)調(diào)用,然后打印日志,最后調(diào)用arm_timer函數(shù)。

timer_timeout = period; // timer_timeout是結(jié)構(gòu)體的成員變量
batch = batch_size/2; // batch是結(jié)構(gòu)體的成員變量
ilog("Started transaction test plugin; performing ${p} transactions every ${m}ms", ("p", batch_size)("m", period));
arm_timer(boost::asio::high_resolution_timer::clock_type::now());
arm_timer 函數(shù)

從start_generation 函數(shù)過來,傳入的參數(shù)是當(dāng)前時(shí)間now,該函數(shù)主要功能是對計(jì)時(shí)器的初始化操作(計(jì)時(shí)器與文首的stop_generation函數(shù)中的關(guān)閉計(jì)時(shí)器呼應(yīng))。具體內(nèi)容可分為兩部分:

設(shè)定計(jì)時(shí)器的過期時(shí)間,值為start_generation 接口的參數(shù)period與now相加的值,即從現(xiàn)在開始,過period這么久,當(dāng)前計(jì)時(shí)器對象timer就過期。

設(shè)定計(jì)時(shí)器的異步定時(shí)任務(wù),任務(wù)體直接調(diào)用send_transaction函數(shù),對函數(shù)的返回值進(jìn)行處理,如果有報(bào)錯(cuò)信息(一般是服務(wù)中止)則調(diào)用stop_generation函數(shù)關(guān)閉插件。

注意stop_generation函數(shù)關(guān)閉的是定時(shí)任務(wù)的無限遞歸,中止定時(shí)任務(wù),停止發(fā)送測試交易。但它并沒有停止插件服務(wù),我們?nèi)耘f可以通過再次請求插件接口啟動(dòng)無限測試交易。

這部分代碼如下:

void arm_timer(boost::asio::high_resolution_timer::time_point s) {
    timer.expires_at(s + std::chrono::milliseconds(timer_timeout));
    timer.async_wait([this](const boost::system::error_code& ec) {
        if(!running || ec)
            return;
        
        send_transaction([this](const fc::exception_ptr& e){
            if (e) {
                elog("pushing transaction failed: ${e}", ("e", e->to_detail_string()));
                stop_generation();
            } else { // 如果沒有終止報(bào)錯(cuò),則無限遞歸調(diào)用arm_timer函數(shù),遞歸時(shí)傳入的參數(shù)代替上面的now是當(dāng)前timer對象的過期時(shí)間,這樣在新的遞歸調(diào)用中,timer的創(chuàng)建會(huì)以這個(gè)時(shí)間再加上period,無間隔繼續(xù)執(zhí)行。
                arm_timer(timer.expires_at());
            }
        });
    });
}
send_transaction 函數(shù)

這個(gè)函數(shù)是本插件的核心功能部分,主要是發(fā)送測試交易,對transaction的處理,將我們上面start_generation 函數(shù)中設(shè)置的兩個(gè)action打包到transaction中去,以及對transaction各項(xiàng)屬性的設(shè)置。具體步驟為:

聲明trxs,并為其設(shè)置大小為start_generation 接口中batch_size的值。

std::vector trxs;
trxs.reserve(2*batch);

接下來,與上面介紹的create_test_accounts 接口的賬戶準(zhǔn)備過程相同,準(zhǔn)備私鑰公鑰,不多介紹。繼續(xù)準(zhǔn)備trx的參數(shù):

nonce,是用來賦值context_free_actions的

context_free_actions:官方介紹一大堆,總之就是正常action是需要代價(jià)的,要確權(quán),要占用主網(wǎng)資源什么的,所以搞了一個(gè)context_free_actions,字面意思就是上下文免費(fèi)的action,這里權(quán)當(dāng)測試用,填入的數(shù)據(jù)也是隨機(jī)nonce組裝的。

abi_serializer,用來序列化abi的,傳入的system_account_name的abi值,它是在這里被賦值,然而是在結(jié)構(gòu)體的作用域中被調(diào)用的。

reference_block_num的處理,引用區(qū)塊,上面我們也提到過,而這里面增加了一層判斷,是根據(jù)標(biāo)志位txn_reference_block_lag的值來比較,也就是說reference_block_num最后的值是最新區(qū)塊號減去txn_reference_block_lag的值,但是最小值為0,不可為負(fù)數(shù)。

通過reference_block_num獲得reference_block_id

這部分代碼如下:

controller& cc = app().get_plugin().chain();
auto chainid = app().get_plugin().get_chain_id();

fc::crypto::private_key a_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, "a")));
fc::crypto::private_key b_priv_key = fc::crypto::private_key::regenerate(fc::sha256(std::string(64, "b")));

static uint64_t nonce = static_cast(fc::time_point::now().sec_since_epoch()) << 32;
abi_serializer eosio_serializer(cc.db().find(config::system_account_name)->get_abi());

uint32_t reference_block_num = cc.last_irreversible_block_num();
if (txn_reference_block_lag >= 0) {
    reference_block_num = cc.head_block_num();
    if (reference_block_num <= (uint32_t)txn_reference_block_lag) {
        reference_block_num = 0;
    } else {
        reference_block_num -= (uint32_t)txn_reference_block_lag;
    }
}

block_id_type reference_block_id = cc.get_block_id_for_num(reference_block_num);

接下來,就是循環(huán)打包trx,我們設(shè)置的batch_size好比是20,現(xiàn)在我們已有兩個(gè)action,每個(gè)action對應(yīng)一個(gè)trx,則循環(huán)只需要執(zhí)行10次,每次執(zhí)行兩個(gè)trx即可實(shí)現(xiàn),每個(gè)trx相關(guān)的屬性在上一階段都已準(zhǔn)備好。直接看代碼吧。

for(unsigned int i = 0; i < batch; ++i) {
    {
        signed_transaction trx;
        trx.actions.push_back(act_a_to_b);
        trx.context_free_actions.emplace_back(action({}, config::null_account_name, "nonce", fc::raw::pack(nonce++)));
        trx.set_reference_block(reference_block_id);
        trx.expiration = cc.head_block_time() + fc::seconds(30);
        trx.max_net_usage_words = 100;
        trx.sign(a_priv_key, chainid);
        trxs.emplace_back(std::move(trx));
    }
    {
        signed_transaction trx;
        trx.actions.push_back(act_b_to_a);
        trx.context_free_actions.emplace_back(action({}, config::null_account_name, "nonce", fc::raw::pack(nonce++)));
        trx.set_reference_block(reference_block_id);
        trx.expiration = cc.head_block_time() + fc::seconds(30);
        trx.max_net_usage_words = 100;
        trx.sign(b_priv_key, chainid);
        trxs.emplace_back(std::move(trx));
    }
}

最后,執(zhí)行

push_transactions(std::move(trxs), next);

這個(gè)部分與create_test_accounts 接口發(fā)起請求的部分一致,這里不再重復(fù)展示。

總結(jié)

到這里為止,我們已經(jīng)完全分析透了txn_test_gen_plugin 插件的內(nèi)容。本文首先從大體上介紹了插件的架構(gòu),生命周期,通訊請求與返回。接著介紹了核心結(jié)構(gòu)體的內(nèi)容,然后以對外接口為入口,沿著一條線將每個(gè)功能的實(shí)現(xiàn)完整地研究清楚。通過本文的學(xué)習(xí),我們對于EOS插件的體系有了初步深刻的理解,同時(shí)我們也完全搞清楚了txn_test_gen_plugin 插件的功能,以及它為什么會(huì)達(dá)到一個(gè)比較高的tps的表現(xiàn)。

參考資料

EOSIO/eos

eos官方文檔


相關(guān)文章和視頻推薦

圓方圓學(xué)院匯集大批區(qū)塊鏈名師,打造精品的區(qū)塊鏈技術(shù)課程。 在各大平臺(tái)都長期有優(yōu)質(zhì)免費(fèi)公開課,歡迎報(bào)名收看。

公開課地址:https://ke.qq.com/course/345101

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

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

相關(guān)文章

  • EOS DApp開發(fā)入門(二): 智能合約探究

    摘要:在看啟動(dòng)腳本輸出的時(shí)候,發(fā)現(xiàn)了這兩樣輸出設(shè)置和智能合約,以及安裝合約開發(fā)工具。合約開發(fā)工具是的工具鏈和一組工具,用于促進(jìn)平臺(tái)的合同編寫。系統(tǒng)智能合約,可以進(jìn)行很多系統(tǒng)級別的操作,比如用戶投票將用戶注冊成為生產(chǎn)者。 Previously 在EOS DApp開發(fā)入門(一)中,通過docker image的方式架起了本地的eos區(qū)塊鏈,使Note chain DApp與本地區(qū)塊鏈進(jìn)行交互,成...

    Honwhy 評論0 收藏0
  • 【許曉笛】聽說你買了EOS ,連代碼什么樣都不知道?

    摘要:說點(diǎn)題外話如果你想提高英語的話,持有一點(diǎn)代幣吧,你會(huì)急于搞清楚白皮書在講什么,要是想短時(shí)間快速提高英語,持有大量代幣吧,別問我是怎么知道的。 最近發(fā)現(xiàn)很多人投資了EOS,卻并不關(guān)心 EOS 目前的開發(fā)進(jìn)度和技術(shù)細(xì)節(jié),如果你投資了 EOS, 還有一定的技術(shù)基礎(chǔ),那就更應(yīng)該關(guān)心 EOS 的開發(fā)情況了,下面我們就從 EOS 的源代碼說起: Github 是目前最流行的源碼管理網(wǎng)站,無數(shù)明星項(xiàng)...

    imccl 評論0 收藏0
  • 開發(fā)零成本 :En-Tan-Mo黃皮書解讀之開發(fā)者篇

    摘要:項(xiàng)目黃皮書一經(jīng)發(fā)布,區(qū)塊鏈垂直媒體星球日報(bào)就對這本書作了專題式的解讀。在接受星球日報(bào)采訪中,開發(fā)者們表示,擔(dān)心節(jié)點(diǎn)集中化帶來的安全風(fēng)險(xiǎn)。本文,星球日報(bào)將通過解讀黃皮書,解答開發(fā)者關(guān)心的問題。 showImg(https://segmentfault.com/img/bVbt2EX?w=800&h=534); 由ETM科學(xué)院歷時(shí)半年打磨的黃皮書,從科學(xué)和技術(shù)兩方面全方位解讀了ETM的理論...

    pakolagij 評論0 收藏0
  • 開發(fā)零成本 :En-Tan-Mo黃皮書解讀之開發(fā)者篇

    摘要:項(xiàng)目黃皮書一經(jīng)發(fā)布,區(qū)塊鏈垂直媒體星球日報(bào)就對這本書作了專題式的解讀。在接受星球日報(bào)采訪中,開發(fā)者們表示,擔(dān)心節(jié)點(diǎn)集中化帶來的安全風(fēng)險(xiǎn)。本文,星球日報(bào)將通過解讀黃皮書,解答開發(fā)者關(guān)心的問題。 showImg(https://segmentfault.com/img/bVbt2EX?w=800&h=534); 由ETM科學(xué)院歷時(shí)半年打磨的黃皮書,從科學(xué)和技術(shù)兩方面全方位解讀了ETM的理論...

    plus2047 評論0 收藏0
  • 【許曉笛】EOS 系統(tǒng)架構(gòu)圖解

    摘要:了解系統(tǒng)架構(gòu)之前我們先看看目前系統(tǒng)的主要組成部分系統(tǒng)的核心進(jìn)程,也就是所謂的節(jié)點(diǎn)。 其實(shí)沒有那么復(fù)雜 相信關(guān)心 EOS 系統(tǒng)的同學(xué)肯定見過下面這張藍(lán)圖。對,目前只是一個(gè)藍(lán)圖,而且以 BM 的尿性,肯定在心理已經(jīng)把這張圖改的面目全非了(比如圖中的 eosd 早就改名了)。所以這張圖只能作為未來 EOS 發(fā)展方向的參考而已,目前的 EOS 還遠(yuǎn)沒有這么復(fù)雜和完善。 showImg(http...

    vibiu 評論0 收藏0

發(fā)表評論

0條評論

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