5
5
6
6
#include " api/make.hpp"
7
7
8
+ #include " blockchain/production/impl/block_producer_impl.hpp"
8
9
#include " vm/actor/builtin/market/actor.hpp"
9
10
#include " vm/actor/builtin/miner/types.hpp"
10
11
#include " vm/actor/builtin/storage_power/storage_power_actor_state.hpp"
@@ -19,21 +20,24 @@ namespace fc::api {
19
20
using vm::actor::builtin::miner::MinerActorState;
20
21
using vm::actor::builtin::storage_power::StoragePowerActorState;
21
22
using vm::interpreter::InterpreterImpl;
23
+ using InterpreterResult = vm::interpreter::Result;
22
24
using vm::state::StateTreeImpl;
23
25
using MarketActorState = vm::actor::builtin::market::State;
26
+ using blockchain::production::BlockProducerImpl;
24
27
using crypto::randomness::RandomnessProvider;
25
28
using crypto::signature::BlsSignature;
26
29
using primitives::block::MsgMeta;
27
30
using storage::amt::Amt;
31
+ using vm::isVMExitCode;
32
+ using vm::normalizeVMExitCode;
28
33
using vm::VMExitCode;
29
34
using vm::actor::InvokerImpl;
30
- using vm::indices::Indices;
31
35
using vm::runtime::Env;
32
36
33
37
struct TipsetContext {
34
38
Tipset tipset;
35
39
StateTreeImpl state_tree;
36
- boost::optional<CID> receipts ;
40
+ boost::optional<InterpreterResult> interpreted ;
37
41
38
42
template <typename T, bool load>
39
43
outcome::result<T> actorState (const Address &address) {
@@ -70,10 +74,9 @@ namespace fc::api {
70
74
OUTCOME_TRY (tipset, chain_store->loadTipset (tipset_key));
71
75
TipsetContext context{tipset, {ipld, tipset.getParentStateRoot ()}, {}};
72
76
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));
75
78
context.state_tree = {ipld, result.state_root };
76
- context.receipts = result. message_receipts ;
79
+ context.interpreted = result;
77
80
}
78
81
return context;
79
82
};
@@ -100,59 +103,43 @@ namespace fc::api {
100
103
auto height,
101
104
auto timestamp) -> outcome::result<BlockMsg> {
102
105
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));
103
124
104
125
OUTCOME_TRY (miner_state, context.minerState (miner));
105
126
OUTCOME_TRY (worker_id,
106
127
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
-
151
128
OUTCOME_TRY (block_signable, codec::cbor::encode (block.header ));
152
129
OUTCOME_TRY (block_sig, key_store->sign (worker_id, block_signable));
153
130
block.header .block_sig = block_sig;
154
131
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;
156
143
}},
157
144
// TODO(turuslan): FIL-165 implement method
158
145
.MpoolPending = {},
@@ -163,20 +150,29 @@ namespace fc::api {
163
150
.StateCall = {[&](auto &message,
164
151
auto &tipset_key) -> outcome::result<InvocResult> {
165
152
OUTCOME_TRY (context, tipsetContext (tipset_key));
166
- // TODO(turuslan): our Indices are not used anywhere
167
- std::shared_ptr<Indices> indices;
168
153
// TODO(turuslan): FIL-146 randomness from tipset
169
154
std::shared_ptr<RandomnessProvider> randomness;
170
155
Env env{randomness,
171
156
std::make_shared<StateTreeImpl>(context.state_tree ),
172
- indices,
173
157
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 )};
177
159
InvocResult result;
178
160
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
+ }
180
176
return result;
181
177
}},
182
178
.StateGetActor = {[&](auto &address,
0 commit comments