VM解釋器從tipset(基于上tipset的父狀態(tài))上編排消息的執(zhí)行,從而生成一個新的狀態(tài)和消息收據(jù)的序列.這個新狀態(tài)和收據(jù)集合的CID被包含在后續(xù)epoch的塊中犁钟,這些epoch必須就這些CID達成一致才能形成新的tipset。
每個狀態(tài)的更改都有一條消息來驅(qū)動喳魏,tipset中所有塊中得消息都必須全部執(zhí)行才能產(chǎn)生下一個狀態(tài)卖毁。來自第一個塊得所有消息均在tipset中得第二個和后續(xù)塊得消息之前執(zhí)行。對于每個塊贩毕,首先執(zhí)行BLS聚合得消息悯许,然后執(zhí)行SECP簽名的消息。
隱式消息
除了顯式包含在每個塊中的消息外辉阶,隱含消息還會在每個epoch進行一些狀態(tài)更改先壕,隱式消息不在節(jié)點之間傳輸,而是由解釋器在評估時構(gòu)成谆甜。
對于tipset中的每個塊垃僚,都有一個條隱式消息:
- 選舉礦工角色成為區(qū)塊生產(chǎn)者,作為區(qū)塊中的第一條消息规辱。
- 調(diào)用獎勵角色將區(qū)塊獎勵支付給礦工 的 owner賬戶谆棺,作為區(qū)塊中的最后一條消息。
對于每個tipset罕袋, 都已以下一個隱式消息:
- 調(diào)用 cron角色來處理自動檢查和付款改淑,作為tipset的最后一條消息
所有隱式消息的構(gòu)造都使用一個區(qū)別于系統(tǒng)賬戶的角色的From
地址。他們的Gas費用位0浴讯,但是他們必須被計算朵夏。為了計算新狀態(tài),他們必須成功(推出代碼為0)兰珍。隱式消息的收據(jù)不包括在收據(jù)列表中,只用顯式的消息才有明確的收據(jù)侍郭。
Gas 支付
在大多數(shù)情況下,消息的發(fā)送者向產(chǎn)生包含該消息的塊的礦工支付執(zhí)行該消息所需的gas費掠河。執(zhí)行該消息后亮元,每次執(zhí)行該消息所產(chǎn)生的gas費將立即支付給礦工的owner賬戶。獲得塊獎勵和gas費用沒有任何阻礙唠摹,他們都是立即支付的爆捞。
重復(fù)消息
由于不同礦工在同一時期產(chǎn)生區(qū)塊,因此勾拉,單個tips中的多個區(qū)塊可能包含相同的消息(由CID標(biāo)識)煮甥。發(fā)生這種情況時,在tipset的規(guī)范順序中第一次遇到它是才會處理該消息藕赞,消息的后續(xù)實例將會被忽略成肘,不會導(dǎo)致任何狀態(tài)變化,也不會產(chǎn)生收據(jù)和向區(qū)塊生產(chǎn)者支付費用
因此斧蜕,tipset的執(zhí)行順序是:
- 支付第一塊的獎勵
- 選舉第一個區(qū)塊的生產(chǎn)者
- 處理第一個區(qū)塊的消息(首先處理BLS双霍,其次處理SECP)
- 支付第二個區(qū)塊的獎勵
- 選舉第二個區(qū)塊的生產(chǎn)者
- 處理第二個塊的消息(首先處理BLS,其次處理SECP,跳過任何已經(jīng)遇到的消息)
- [...隨后的塊處理同上....]
- cron角色標(biāo)記
正確和失敗的消息
有效塊中的每一條消息都可以被處理并產(chǎn)生收據(jù)(注意,塊的有效性表示所有消息在語法上均有效且正確簽名)洒闸。但是染坯,執(zhí)行的成功與否取決于消息的執(zhí)行狀態(tài)。如果消息執(zhí)行失敗丘逸,則相應(yīng)的收據(jù)將攜帶非零的退出代碼单鹿。
如過一條消息由于礦工打包在父狀態(tài)就不可能成功消息的原因而失敗,或者由于發(fā)送者缺乏資金來支付最大消息成本深纲,則礦工將通過消耗Gas的方式支付罰款(而不是發(fā)送者向礦工支付費用)仲锄。
消息失敗導(dǎo)致的唯一狀態(tài)變更是:
- 增加發(fā)送者的
CallSeqNum
,并且發(fā)送者向創(chuàng)造包含該消息的塊的礦工的onwer支付Gas費囤萤,或者 - 礦工通過支付等同于失敗消息的Gas費的罰款(發(fā)送者的
CallSeqNum
不改變)
如果發(fā)生以下情況昼窗,消息將會失斒桥俊:
-
From
的角色在狀態(tài)中不存在(礦工罰款) -
From
的角色不是賬號角色(礦工罰款) - 消息的
CallSeqNum
和From
的角色的CallSeqNum
不匹配(礦工罰款) -
From
的角色沒有足夠的資金來支付整個消息消耗的Gas成本GasLimit * GasPrice
(礦工罰款) -
To
的角色不存在并且To
的地址不是一個公鑰類型的地址 -
To
的角色存在(或者作為隱式賬戶創(chuàng)建)但是沒有對應(yīng)于非零的方法MethodNum
涛舍。 - 反序列化的
Params
長度不匹配To
的MethodNum
方法的長度的數(shù)組 - 反序列化的
Params
對于To
角色的MethodNum
方法執(zhí)行的類型無效 - 所調(diào)用的方法消耗的Gas多于
GasLimit
允許的量。 - 調(diào)用的方法以非零代碼(通過
Runtime.Abort()
)推出 - 由于以上任何原因唆途,接收方發(fā)送的任何內(nèi)部消息都會失敗富雅。
如果To
賬戶在狀態(tài)中不存在,并且該地址是有效的H(pubkey)地址肛搬,則會為其創(chuàng)建賬戶角色
翻譯自https://spec.filecoin.io/#section-systems.filecoin_vm.interpreter