55
66#include " api/make.hpp"
77
8+ #include " blockchain/production/impl/block_producer_impl.hpp"
89#include " vm/actor/builtin/market/actor.hpp"
910#include " vm/actor/builtin/miner/types.hpp"
1011#include " vm/actor/builtin/storage_power/storage_power_actor_state.hpp"
@@ -19,21 +20,24 @@ namespace fc::api {
1920 using vm::actor::builtin::miner::MinerActorState;
2021 using vm::actor::builtin::storage_power::StoragePowerActorState;
2122 using vm::interpreter::InterpreterImpl;
23+ using InterpreterResult = vm::interpreter::Result;
2224 using vm::state::StateTreeImpl;
2325 using MarketActorState = vm::actor::builtin::market::State;
26+ using blockchain::production::BlockProducerImpl;
2427 using crypto::randomness::RandomnessProvider;
2528 using crypto::signature::BlsSignature;
2629 using primitives::block::MsgMeta;
2730 using storage::amt::Amt;
31+ using vm::isVMExitCode;
32+ using vm::normalizeVMExitCode;
2833 using vm::VMExitCode;
2934 using vm::actor::InvokerImpl;
30- using vm::indices::Indices;
3135 using vm::runtime::Env;
3236
3337 struct TipsetContext {
3438 Tipset tipset;
3539 StateTreeImpl state_tree;
36- boost::optional<CID> receipts ;
40+ boost::optional<InterpreterResult> interpreted ;
3741
3842 template <typename T, bool load>
3943 outcome::result<T> actorState (const Address &address) {
@@ -70,10 +74,9 @@ namespace fc::api {
7074 OUTCOME_TRY (tipset, chain_store->loadTipset (tipset_key));
7175 TipsetContext context{tipset, {ipld, tipset.getParentStateRoot ()}, {}};
7276 if (interpret) {
73- // TODO(turuslan): our Indices are not used anywhere
74- OUTCOME_TRY (result, InterpreterImpl{}.interpret (ipld, tipset, nullptr ));
77+ OUTCOME_TRY (result, InterpreterImpl{}.interpret (ipld, tipset));
7578 context.state_tree = {ipld, result.state_root };
76- context.receipts = result. message_receipts ;
79+ context.interpreted = result;
7780 }
7881 return context;
7982 };
@@ -100,59 +103,43 @@ namespace fc::api {
100103 auto height,
101104 auto timestamp) -> outcome::result<BlockMsg> {
102105 OUTCOME_TRY (context, tipsetContext (parent, true ));
106+ BlockProducerImpl producer{
107+ ipld,
108+ nullptr ,
109+ nullptr ,
110+ nullptr ,
111+ weight_calculator,
112+ bls_provider,
113+ std::make_shared<InterpreterImpl>(),
114+ };
115+ OUTCOME_TRY (block,
116+ producer.generate (miner,
117+ context.tipset ,
118+ *context.interpreted ,
119+ proof,
120+ ticket,
121+ messages,
122+ height,
123+ timestamp));
103124
104125 OUTCOME_TRY (miner_state, context.minerState (miner));
105126 OUTCOME_TRY (worker_id,
106127 context.state_tree .lookupId (miner_state.info .worker ));
107- OUTCOME_TRY (state_root, context.state_tree .flush ());
108-
109- BlockMsg block;
110- block.header .miner = miner;
111- block.header .parents = parent.cids ;
112- block.header .ticket = ticket;
113- block.header .height = height;
114- block.header .timestamp = timestamp;
115- block.header .epost_proof = proof;
116- block.header .parent_state_root = state_root;
117- block.header .parent_message_receipts = *context.receipts ;
118- block.header .fork_signaling = 0 ;
119-
120- std::vector<BlsSignature> bls_sigs;
121- Amt amt_bls{ipld}, amt_secp{ipld};
122- uint64_t i_bls{0 }, i_secp{0 };
123- for (auto &message : messages) {
124- if (message.signature .isBls ()) {
125- OUTCOME_TRY (message_cid, ipld->setCbor (message.message ));
126- bls_sigs.emplace_back (
127- boost::get<BlsSignature>(message.signature ));
128- block.bls_messages .emplace_back (std::move (message_cid));
129- OUTCOME_TRY (amt_bls.setCbor (++i_bls, message_cid));
130- } else {
131- OUTCOME_TRY (message_cid, ipld->setCbor (message));
132- block.secp_messages .emplace_back (std::move (message_cid));
133- OUTCOME_TRY (amt_secp.setCbor (++i_secp, message_cid));
134- }
135- }
136-
137- OUTCOME_TRY (amt_bls.flush ());
138- OUTCOME_TRY (amt_secp.flush ());
139- OUTCOME_TRY (msg_meta,
140- ipld->setCbor (MsgMeta{amt_bls.cid (), amt_secp.cid ()}));
141- block.header .messages = msg_meta;
142-
143- OUTCOME_TRY (bls_aggregate,
144- bls_provider->aggregateSignatures (bls_sigs));
145- block.header .bls_aggregate = bls_aggregate;
146-
147- OUTCOME_TRY (parent_weight,
148- weight_calculator->calculateWeight (context.tipset ));
149- block.header .parent_weight = parent_weight;
150-
151128 OUTCOME_TRY (block_signable, codec::cbor::encode (block.header ));
152129 OUTCOME_TRY (block_sig, key_store->sign (worker_id, block_signable));
153130 block.header .block_sig = block_sig;
154131
155- return block;
132+ BlockMsg block2;
133+ block2.header = block.header ;
134+ for (auto &msg : block.bls_messages ) {
135+ OUTCOME_TRY (cid, ipld->setCbor (msg));
136+ block2.bls_messages .emplace_back (std::move (cid));
137+ }
138+ for (auto &msg : block.secp_messages ) {
139+ OUTCOME_TRY (cid, ipld->setCbor (msg));
140+ block2.secp_messages .emplace_back (std::move (cid));
141+ }
142+ return block2;
156143 }},
157144 // TODO(turuslan): FIL-165 implement method
158145 .MpoolPending = {},
@@ -163,20 +150,29 @@ namespace fc::api {
163150 .StateCall = {[&](auto &message,
164151 auto &tipset_key) -> outcome::result<InvocResult> {
165152 OUTCOME_TRY (context, tipsetContext (tipset_key));
166- // TODO(turuslan): our Indices are not used anywhere
167- std::shared_ptr<Indices> indices;
168153 // TODO(turuslan): FIL-146 randomness from tipset
169154 std::shared_ptr<RandomnessProvider> randomness;
170155 Env env{randomness,
171156 std::make_shared<StateTreeImpl>(context.state_tree ),
172- indices,
173157 std::make_shared<InvokerImpl>(),
174- static_cast <ChainEpoch>(context.tipset .height ),
175- Address{}};
176- OUTCOME_TRY (receipt, env.applyMessage (message));
158+ static_cast <ChainEpoch>(context.tipset .height )};
177159 InvocResult result;
178160 result.message = message;
179- result.receipt = receipt;
161+ auto maybe_result = env.applyImplicitMessage (message);
162+ if (maybe_result) {
163+ result.receipt = {
164+ VMExitCode::Ok, maybe_result.value ().return_value , 0 };
165+ } else {
166+ if (isVMExitCode (maybe_result.error ())) {
167+ auto ret_code =
168+ normalizeVMExitCode (VMExitCode{maybe_result.error ().value ()});
169+ BOOST_ASSERT_MSG (ret_code,
170+ " c++ actor code returned unknown error" );
171+ result.receipt = {*ret_code, {}, 0 };
172+ } else {
173+ return maybe_result.error ();
174+ }
175+ }
180176 return result;
181177 }},
182178 .StateGetActor = {[&](auto &address,
0 commit comments