Skip to content

Commit fc9ad76

Browse files
authored
Typed actor method (#124)
Signed-off-by: turuslan <[email protected]>
1 parent 7e4a291 commit fc9ad76

33 files changed

+979
-1406
lines changed

core/vm/actor/actor_encoding.hpp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef CPP_FILECOIN_CORE_VM_ACTOR_ACTOR_ENCODING_HPP
7+
#define CPP_FILECOIN_CORE_VM_ACTOR_ACTOR_ENCODING_HPP
8+
9+
#include "codec/cbor/cbor.hpp"
10+
#include "common/outcome.hpp"
11+
#include "vm/actor/actor.hpp"
12+
#include "vm/exit_code/exit_code.hpp"
13+
#include "vm/runtime/runtime_types.hpp"
14+
15+
namespace fc::vm::actor {
16+
using runtime::InvocationOutput;
17+
18+
/// Type for empty params and result
19+
struct None {};
20+
CBOR_ENCODE(None, none) {
21+
return s;
22+
}
23+
CBOR_DECODE(None, none) {
24+
return s;
25+
}
26+
27+
/// Decode actor params, raises appropriate error
28+
template <typename T>
29+
outcome::result<T> decodeActorParams(MethodParams params_bytes) {
30+
if constexpr (std::is_same_v<T, None>) {
31+
return T{};
32+
}
33+
auto maybe_params = codec::cbor::decode<T>(params_bytes);
34+
if (!maybe_params) {
35+
return VMExitCode::DECODE_ACTOR_PARAMS_ERROR;
36+
}
37+
return maybe_params;
38+
}
39+
40+
/// Encode actor params, raises appropriate error
41+
template <typename T>
42+
outcome::result<MethodParams> encodeActorParams(const T &params) {
43+
auto maybe_bytes = codec::cbor::encode(params);
44+
if (!maybe_bytes) {
45+
return VMExitCode::ENCODE_ACTOR_PARAMS_ERROR;
46+
}
47+
return MethodParams{maybe_bytes.value()};
48+
}
49+
50+
template <typename T>
51+
outcome::result<T> decodeActorReturn(const InvocationOutput &result) {
52+
if constexpr (std::is_same_v<T, None>) {
53+
return T{};
54+
}
55+
return codec::cbor::decode<T>(result.return_value);
56+
}
57+
58+
template <typename T>
59+
outcome::result<InvocationOutput> encodeActorReturn(const T &result) {
60+
OUTCOME_TRY(encoded, codec::cbor::encode(result));
61+
return InvocationOutput{Buffer{encoded}};
62+
}
63+
} // namespace fc::vm::actor
64+
65+
#endif // CPP_FILECOIN_CORE_VM_ACTOR_ACTOR_ENCODING_HPP

core/vm/actor/actor_method.hpp

Lines changed: 26 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@
99
#include "codec/cbor/cbor.hpp"
1010
#include "common/outcome.hpp"
1111
#include "vm/actor/actor.hpp"
12+
#include "vm/actor/actor_encoding.hpp"
1213
#include "vm/exit_code/exit_code.hpp"
1314
#include "vm/runtime/runtime.hpp"
1415

15-
#define ACTOR_METHOD(name) \
16-
outcome::result<InvocationOutput> name(Runtime &runtime, \
17-
const MethodParams &params)
16+
/// Declare actor method function
17+
#define ACTOR_METHOD_DECL() \
18+
static outcome::result<Result> call(Runtime &, const Params &);
1819

19-
namespace fc::vm::actor {
20+
/// Define actor method function
21+
#define ACTOR_METHOD_IMPL(M) \
22+
outcome::result<M::Result> M::call(Runtime &runtime, const Params &params)
2023

24+
namespace fc::vm::actor {
2125
using common::Buffer;
2226
using runtime::InvocationOutput;
2327
using runtime::Runtime;
@@ -35,31 +39,26 @@ namespace fc::vm::actor {
3539
/// Actor methods exported by number
3640
using ActorExports = std::map<MethodNumber, ActorMethod>;
3741

38-
/// Decode actor params, raises appropriate error
39-
template <typename T>
40-
outcome::result<T> decodeActorParams(MethodParams params_bytes) {
41-
auto maybe_params = codec::cbor::decode<T>(params_bytes);
42-
if (!maybe_params) {
43-
return VMExitCode::DECODE_ACTOR_PARAMS_ERROR;
44-
}
45-
return maybe_params;
46-
}
47-
48-
using runtime::encodeActorParams;
42+
/// Actor method base class
43+
template <uint64_t number>
44+
struct ActorMethodBase {
45+
using Params = None;
46+
using Result = None;
47+
static constexpr MethodNumber Number{number};
48+
};
4949

50-
template <typename T>
51-
outcome::result<T> decodeActorReturn(const InvocationOutput &result) {
52-
OUTCOME_TRY(decoded,
53-
codec::cbor::decode<T>(result.return_value.toVector()));
54-
return std::move(decoded);
50+
/// Generate export table entry
51+
template <typename M>
52+
auto exportMethod() {
53+
return std::make_pair(
54+
M::Number,
55+
ActorMethod{[](auto &runtime,
56+
auto &params) -> outcome::result<InvocationOutput> {
57+
OUTCOME_TRY(params2, decodeActorParams<typename M::Params>(params));
58+
OUTCOME_TRY(result, M::call(runtime, params2));
59+
return encodeActorReturn(result);
60+
}});
5561
}
56-
57-
template <typename T>
58-
outcome::result<InvocationOutput> encodeActorReturn(const T &result) {
59-
OUTCOME_TRY(encoded, codec::cbor::encode(result));
60-
return InvocationOutput{Buffer{encoded}};
61-
}
62-
6362
} // namespace fc::vm::actor
6463

6564
#endif // CPP_FILECOIN_CORE_VM_ACTOR_ACTOR_METHOD_HPP

core/vm/actor/builtin/account/account_actor.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,12 @@ namespace fc::vm::actor::builtin::account {
4242
return account_actor_state.address;
4343
}
4444

45-
ACTOR_METHOD(pubkeyAddress) {
45+
ACTOR_METHOD_IMPL(PubkeyAddress) {
4646
OUTCOME_TRY(state, runtime.getCurrentActorStateCbor<AccountActorState>());
47-
OUTCOME_TRY(result, codec::cbor::encode(state.address));
48-
return InvocationOutput{Buffer{result}};
47+
return state.address;
4948
}
5049

5150
const ActorExports exports = {
52-
{kPubkeyAddressMethodNumber, ActorMethod(pubkeyAddress)},
51+
exportMethod<PubkeyAddress>(),
5352
};
5453
} // namespace fc::vm::actor::builtin::account

core/vm/actor/builtin/account/account_actor.hpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,10 @@ namespace fc::vm::actor::builtin::account {
1717
using primitives::address::Protocol;
1818
using state::StateTree;
1919

20-
constexpr MethodNumber kPubkeyAddressMethodNumber{2};
21-
2220
struct AccountActorState {
2321
Address address;
2422
};
23+
CBOR_TUPLE(AccountActorState, address)
2524

2625
/// Account actors represent actors without code
2726
struct AccountActor {
@@ -38,9 +37,10 @@ namespace fc::vm::actor::builtin::account {
3837
const std::shared_ptr<StateTree> &state_tree, const Address &address);
3938
};
4039

41-
CBOR_TUPLE(AccountActorState, address)
42-
43-
ACTOR_METHOD(pubkeyAddress);
40+
struct PubkeyAddress : ActorMethodBase<2> {
41+
using Result = Address;
42+
ACTOR_METHOD_DECL();
43+
};
4444

4545
extern const ActorExports exports;
4646
} // namespace fc::vm::actor::builtin::account

core/vm/actor/builtin/cron/cron_actor.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ namespace fc::vm::actor::builtin::cron {
1212
* EpochTick
1313
*/
1414
std::vector<CronTableEntry> entries = {
15-
{kStoragePowerAddress, {storage_power::kOnEpochTickEndMethodNumber}}};
15+
{kStoragePowerAddress, {storage_power::OnEpochTickEnd::Number}}};
1616

17-
ACTOR_METHOD(epochTick) {
17+
ACTOR_METHOD_IMPL(EpochTick) {
1818
if ((runtime.getMessage().get().from != kCronAddress)) {
1919
return VMExitCode::CRON_ACTOR_WRONG_CALL;
2020
}
@@ -26,6 +26,6 @@ namespace fc::vm::actor::builtin::cron {
2626
}
2727

2828
const ActorExports exports = {
29-
{kEpochTickMethodNumber, ActorMethod(epochTick)},
29+
exportMethod<EpochTick>(),
3030
};
3131
} // namespace fc::vm::actor::builtin::cron

core/vm/actor/builtin/cron/cron_actor.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,16 @@ namespace fc::vm::actor::builtin::cron {
1515
MethodNumber method_num{};
1616
};
1717

18-
constexpr MethodNumber kEpochTickMethodNumber{2};
19-
2018
/**
2119
* @brief EpochTick executes built-in periodic actions, run at every Epoch.
2220
* @param actor from Lotus(doesn't use)
2321
* @param runtime is virtual machine context
2422
* @param params from Lotus(doesn't use)
2523
* @return success or error
2624
*/
27-
ACTOR_METHOD(epochTick);
25+
struct EpochTick : ActorMethodBase<2> {
26+
ACTOR_METHOD_DECL();
27+
};
2828

2929
extern const ActorExports exports;
3030

core/vm/actor/builtin/init/init_actor.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,11 @@ namespace fc::vm::actor::builtin::init {
2222
return Address::makeFromId(id);
2323
}
2424

25-
ACTOR_METHOD(exec) {
26-
OUTCOME_TRY(exec_params, decodeActorParams<ExecParams>(params));
27-
if (!isBuiltinActor(exec_params.code)) {
25+
ACTOR_METHOD_IMPL(Exec) {
26+
if (!isBuiltinActor(params.code)) {
2827
return VMExitCode::INIT_ACTOR_NOT_BUILTIN_ACTOR;
2928
}
30-
if (isSingletonActor(exec_params.code)) {
29+
if (isSingletonActor(params.code)) {
3130
return VMExitCode::INIT_ACTOR_SINGLETON_ACTOR;
3231
}
3332
OUTCOME_TRY(runtime.chargeGas(runtime::kInitActorExecCost));
@@ -40,16 +39,14 @@ namespace fc::vm::actor::builtin::init {
4039
OUTCOME_TRY(id_address, init_actor.addActor(store, actor_address));
4140
OUTCOME_TRY(runtime.createActor(
4241
id_address,
43-
Actor{exec_params.code, ActorSubstateCID{kEmptyObjectCid}, 0, 0}));
44-
OUTCOME_TRY(runtime.send(id_address,
45-
kConstructorMethodNumber,
46-
exec_params.params,
47-
message.value));
48-
ExecReturn exec_return{id_address, actor_address};
49-
OUTCOME_TRY(output, encodeActorReturn(exec_return));
42+
Actor{params.code, ActorSubstateCID{kEmptyObjectCid}, 0, 0}));
43+
OUTCOME_TRY(runtime.send(
44+
id_address, kConstructorMethodNumber, params.params, message.value));
5045
OUTCOME_TRY(runtime.commitState(init_actor));
51-
return std::move(output);
46+
return Result{id_address, actor_address};
5247
}
5348

54-
const ActorExports exports{{kExecMethodNumber, ActorMethod(exec)}};
49+
const ActorExports exports{
50+
exportMethod<Exec>(),
51+
};
5552
} // namespace fc::vm::actor::builtin::init

core/vm/actor/builtin/init/init_actor.hpp

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,30 +23,30 @@ namespace fc::vm::actor::builtin::init {
2323
CID address_map{};
2424
uint64_t next_id{};
2525
};
26-
2726
CBOR_TUPLE(InitActorState, address_map, next_id)
2827

29-
constexpr MethodNumber kExecMethodNumber{2};
30-
31-
struct ExecParams {
32-
CodeId code;
33-
MethodParams params;
34-
};
35-
36-
struct ExecReturn {
37-
Address id_address; // The canonical ID-based address for the actor
38-
Address robust_address; // A more expensive but re-org-safe address for the
39-
// newly created actor
28+
struct Exec : ActorMethodBase<2> {
29+
struct Params {
30+
CodeId code;
31+
MethodParams params;
32+
};
33+
struct Result {
34+
Address id_address; // The canonical ID-based address for the actor
35+
Address robust_address; // A more expensive but re-org-safe address for
36+
// the newly created actor
37+
};
38+
ACTOR_METHOD_DECL();
4039
};
40+
CBOR_TUPLE(Exec::Params, code, params)
41+
CBOR_TUPLE(Exec::Result, id_address, robust_address)
4142

42-
ACTOR_METHOD(exec);
43+
inline bool operator==(const Exec::Result &lhs, const Exec::Result &rhs) {
44+
return lhs.id_address == rhs.id_address
45+
&& lhs.robust_address == rhs.robust_address;
46+
}
4347

4448
extern const ActorExports exports;
4549

46-
CBOR_TUPLE(ExecParams, code, params)
47-
48-
CBOR_TUPLE(ExecReturn, id_address, robust_address)
49-
5050
} // namespace fc::vm::actor::builtin::init
5151

5252
#endif // CPP_FILECOIN_CORE_VM_ACTOR_INIT_ACTOR_HPP

core/vm/actor/builtin/market/actor.hpp

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,36 @@
1313
namespace fc::vm::actor::builtin::market {
1414
using primitives::ChainEpoch;
1515
using primitives::DealId;
16+
using primitives::DealWeight;
1617
using primitives::SectorSize;
1718

18-
constexpr MethodNumber kVerifyDealsOnSectorProveCommitMethodNumber{6};
19-
constexpr MethodNumber kOnMinerSectorsTerminateMethodNumber{7};
20-
constexpr MethodNumber kComputeDataCommitmentMethodNumber{8};
21-
22-
struct VerifyDealsOnSectorProveCommitParams {
23-
std::vector<DealId> deals;
24-
ChainEpoch sector_expiry;
19+
struct VerifyDealsOnSectorProveCommit : ActorMethodBase<6> {
20+
struct Params {
21+
std::vector<DealId> deals;
22+
ChainEpoch sector_expiry;
23+
};
24+
using Result = DealWeight;
25+
ACTOR_METHOD_DECL();
2526
};
27+
CBOR_TUPLE(VerifyDealsOnSectorProveCommit::Params, deals, sector_expiry)
2628

27-
struct OnMinerSectorsTerminateParams {
28-
std::vector<DealId> deals;
29+
struct OnMinerSectorsTerminate : ActorMethodBase<7> {
30+
struct Params {
31+
std::vector<DealId> deals;
32+
};
33+
ACTOR_METHOD_DECL();
2934
};
30-
31-
struct ComputeDataCommitmentParams {
32-
std::vector<DealId> deals;
33-
SectorSize sector_size;
35+
CBOR_TUPLE(OnMinerSectorsTerminate::Params, deals)
36+
37+
struct ComputeDataCommitment : ActorMethodBase<8> {
38+
struct Params {
39+
std::vector<DealId> deals;
40+
SectorSize sector_size;
41+
};
42+
using Result = CID;
43+
ACTOR_METHOD_DECL();
3444
};
35-
36-
CBOR_TUPLE(VerifyDealsOnSectorProveCommitParams, deals, sector_expiry)
37-
38-
CBOR_TUPLE(OnMinerSectorsTerminateParams, deals)
39-
40-
CBOR_TUPLE(ComputeDataCommitmentParams, deals, sector_size)
45+
CBOR_TUPLE(ComputeDataCommitment::Params, deals, sector_size)
4146
} // namespace fc::vm::actor::builtin::market
4247

4348
#endif // CPP_FILECOIN_CORE_VM_ACTOR_BUILTIN_MARKET_ACTOR_HPP

0 commit comments

Comments
 (0)