EOS 原始碼解析 區塊回滾對交易的影響

2021-09-13 02:20:37 字數 2303 閱讀 8145

在主網上玩耍的小夥伴們肯定遇到過區塊回滾導致自己的交易沒有上鏈。這種情況讓有些人誤以為區塊回滾會丟棄交易。 其實區塊回滾並不是導致交易沒上鏈的主要原因, 主要原因是交易過期了才導致交易被丟棄。

流程描述:

每個交易是會被廣播到全網每個節點上面的( ps: 當然傳播過程中過期的話,當我沒說哈 ),假如出塊節點 a 打包了 trx a, 但此時出塊節點 b 沒接受到 a 的打包塊,他也開始打包了,那麼他也包含了該 trx a 並會將他打包( ps: 當然也有例外情況,那就是 出塊節點 b 接收到 trx a 時,他就過期了,所以還沒打包就丟棄他,或者還沒傳遞到出塊節點 b, 但會抵達下個節點 c d e, 但情況相似,就不另外說明了 )。但如果 a 的過期時間設定過短,導致出塊節點 b 打包時發現他過期了,就會丟棄他。 這便是交易沒上鏈的原因。
原始碼解析:
我們來看看區塊生產時是如何丟棄過期交易的。區塊生產的流程 區塊的分叉處理可以看下我之前的文章。這裡生產區塊以及回滾的細節就不贅述了。
區塊打包時,會將 pending block 裡已經執行成功了的 trx 另外存起來, 並初始化 pending block。 等到打包的時候會再去執行一次這些 trx , 咦,為什麼要重新執行一遍浪費資源,因為這些 trx 都是在區塊打包之前執行的,鬼知道過期了沒有 =,=。

以下是交易被殘忍丟棄的過程:

if ( read_mode == db_read_mode::speculative ) 

pending.reset();

}

}// producer_plugin.cpp

producer_plugin_impl::start_block_result producer_plugin_impl::start_block(bool &last_block) fc_log_and_drop();

const auto& pbs = chain.pending_block_state();

if (pbs) for producer $ is expiring persisted tx: $",

("block_num", chain.head_block_num() + 1)

("prod", chain.pending_block_state()->header.producer)

("txid", txid));

} else ",

("txid", txid));

}persisted_by_expiry.erase(persisted_by_expiry.begin());

num_expired_persistent++;

}fc_dlog(_log, "processed $ persisted transactions, expired $",

("n", orig_count)

("expired", num_expired_persistent));

} try else else if (persisted_by_id.find(trx->id) != persisted_by_id.end()) else

};auto category = calculate_transaction_category(trx);

if (category == tx_category::expired || (category == tx_category::unexpired_unpersisted && _producers.empty())) ",

("txid", trx->id));

}} else if (category == tx_category::persisted || (category == tx_category::unexpired_unpersisted && _pending_block_mode == pending_block_mode::producing)) }}

// 執行 trx, 成功的 emplace_back 進 pending block}}

// ...

// 執行 deffered transaction

// 和執行 初始化 pending block 時推送進來的 transcation ( 因為初始化時,pending block 不能存 trx, 所以先另外存起來)return start_block_result::failed;

}回滾並不會丟棄 trx, 只會導致 trx 延後打包,以致於 trx 可能過期被丟棄。

設定過期時間時,時間跨度應該足夠 2 個 bp 出完塊,這樣即使 b 沒接收到 a 的區塊,但 trx 不會因為過期而被 b 丟棄,當然還要大致估算你的 trx 廣播到出塊節點的時間。

EOS 原始碼解析 什麼是 read only 模式

大家之前使用 mongodb plugin mysql plugin 或其他資料持久化外掛程式的時候,可能會發現 transaction 和 trace 的資料重複duplicate 多機環境下 在最初的時候只能在持久化的時候做去重處理,但 eos 之後已經推出了 read only 模式,可以避免...

64 原始碼 以太坊交易簽名解析原始碼解讀

上篇文章 以太坊交易簽名過程原始碼解析 從原始碼角度分析了乙個合約呼叫的的簽名過程,簽名後的交易傳送到以太坊節點後,節點需要從簽名交易中還原出公鑰 從公鑰中單向計算出賬號位址 進而將交易放入交易池中。本文從 go ethereum 原始碼的出發,看看如何從簽名交易中還原出公鑰。我們使用上文中最後得到...

EOS原始碼解析 使用多執行緒從簽名生成對應公鑰

昨天早上,eos 1.5.0 release 版本發布了。這次比較大改動點是在多執行緒簽名上面。它將同步區塊時的 block 簽名驗證和 trx 簽名驗證都使用多執行緒簽名驗證,來節省同步所需要的時間,但是生產區塊所需要的成本是不變的,但為什麼生產區塊成本不變呢。接下來介紹一下具體的改動。區塊多執行...