Skip to content

Commit 1d2851c

Browse files
strong types for runtime (#70)
Signed-off-by: Alexey-N-Chernyshov <[email protected]>
1 parent 0629e12 commit 1d2851c

File tree

6 files changed

+113
-38
lines changed

6 files changed

+113
-38
lines changed

core/vm/actor/actor.cpp

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ namespace fc::vm::actor {
1616
&& lhs.nonce == rhs.nonce && lhs.balance == rhs.balance;
1717
}
1818

19-
bool isBuiltinActor(const CID &code) {
19+
bool isBuiltinActor(const CodeId &code) {
2020
return code == kStorageMarketCodeCid || code == kStoragePowerCodeCid
2121
|| code == kStorageMinerCodeCid || code == kAccountCodeCid
2222
|| code == kInitCodeCid || code == kMultisigCodeCid
2323
|| code == kPaymentChannelCodeCid;
2424
}
2525

26-
bool isSingletonActor(const CID &code) {
26+
bool isSingletonActor(const CodeId &code) {
2727
return code == kStoragePowerCodeCid || code == kStorageMarketCodeCid
2828
|| code == kInitCodeCid || code == kCronCodeCid;
2929
}
@@ -44,12 +44,15 @@ namespace fc::vm::actor {
4444
.value()};
4545
}
4646

47-
const CID kAccountCodeCid = makeRawIdentityCid("fil/1/account");
48-
const CID kCronCodeCid = makeRawIdentityCid("fil/1/cron");
49-
const CID kStoragePowerCodeCid = makeRawIdentityCid("fil/1/power");
50-
const CID kStorageMarketCodeCid = makeRawIdentityCid("fil/1/market");
51-
const CID kStorageMinerCodeCid = makeRawIdentityCid("fil/1/miner");
52-
const CID kMultisigCodeCid = makeRawIdentityCid("fil/1/multisig");
53-
const CID kInitCodeCid = makeRawIdentityCid("fil/1/init");
54-
const CID kPaymentChannelCodeCid = makeRawIdentityCid("fil/1/paych");
47+
const CodeId kAccountCodeCid = CodeId(makeRawIdentityCid("fil/1/account"));
48+
const CodeId kCronCodeCid = CodeId(makeRawIdentityCid("fil/1/cron"));
49+
const CodeId kStoragePowerCodeCid = CodeId(makeRawIdentityCid("fil/1/power"));
50+
const CodeId kStorageMarketCodeCid =
51+
CodeId(makeRawIdentityCid("fil/1/market"));
52+
const CodeId kStorageMinerCodeCid = CodeId(makeRawIdentityCid("fil/1/miner"));
53+
const CodeId kMultisigCodeCid = CodeId(makeRawIdentityCid("fil/1/multisig"));
54+
const CodeId kInitCodeCid = CodeId(makeRawIdentityCid("fil/1/init"));
55+
const CodeId kPaymentChannelCodeCid =
56+
CodeId(makeRawIdentityCid("fil/1/paych"));
57+
5558
} // namespace fc::vm::actor

core/vm/actor/actor.hpp

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,63 @@
66
#ifndef CPP_FILECOIN_CORE_VM_ACTOR_ACTOR_HPP
77
#define CPP_FILECOIN_CORE_VM_ACTOR_ACTOR_HPP
88

9-
#include <libp2p/multi/content_identifier_codec.hpp>
10-
9+
#include "common/buffer.hpp"
1110
#include "primitives/address/address.hpp"
1211
#include "primitives/big_int.hpp"
1312
#include "primitives/cid/cid.hpp"
1413

1514
namespace fc::vm::actor {
16-
using primitives::address::Address;
15+
16+
using fc::common::Buffer;
1717
using primitives::BigInt;
18+
using primitives::address::Address;
19+
20+
/**
21+
* Consider MethodNum numbers to be similar in concerns as for offsets in
22+
* function tables (in programming languages), and for tags in ProtocolBuffer
23+
* fields. Tags in ProtocolBuffers recommend assigning a unique tag to a field
24+
* and never reusing that tag. If a field is no longer used, the field name
25+
* may change but should still remain defined in the code to ensure the tag
26+
* number is not reused accidentally. The same should apply to the MethodNum
27+
* associated with methods in Filecoin VM Actors.
28+
*/
29+
struct MethodNumber {
30+
uint64_t method_number;
31+
};
32+
33+
/**
34+
* MethodParams is serialized parameters to the method call
35+
*/
36+
class MethodParams : public Buffer {};
37+
38+
/**
39+
* CodeID identifies an actor's code (either one of the builtin actors, or, in
40+
* the future, potentially a CID of VM code for a custom actor)
41+
*/
42+
class CodeId : public CID {
43+
public:
44+
CodeId() = default;
45+
explicit CodeId(CID cid) : CID{std::move(cid)} {}
46+
};
47+
48+
class ActorSubstateCID : public CID {
49+
public:
50+
ActorSubstateCID() = default;
51+
explicit ActorSubstateCID(CID cid) : CID{std::move(cid)} {}
52+
};
1853

19-
/** Common actor state interface */
54+
/**
55+
* Common actor state interface represents the on-chain storage all actors
56+
* keep
57+
*/
2058
struct Actor {
21-
CID code{};
22-
CID head{};
59+
/// Identifies the code this actor executes
60+
CodeId code{};
61+
/// CID of the root of optional actor-specific sub-state
62+
ActorSubstateCID head{};
63+
/// Expected sequence number of the next message sent by this actor
2364
uint64_t nonce{};
65+
/// Balance of tokens held by this actor
2466
BigInt balance{};
2567
};
2668

@@ -30,7 +72,8 @@ namespace fc::vm::actor {
3072
typename = std::enable_if_t<
3173
std::remove_reference_t<Stream>::is_cbor_encoder_stream>>
3274
Stream &operator<<(Stream &&s, const Actor &actor) {
33-
return s << (s.list() << actor.code << actor.head << actor.nonce << actor.balance);
75+
return s << (s.list() << actor.code << actor.head << actor.nonce
76+
<< actor.balance);
3477
}
3578

3679
template <class Stream,
@@ -42,14 +85,14 @@ namespace fc::vm::actor {
4285
}
4386

4487
/** Check if code specifies builtin actor implementation */
45-
bool isBuiltinActor(const CID &code);
88+
bool isBuiltinActor(const CodeId &code);
4689

4790
/** Check if only one instance of actor should exists */
48-
bool isSingletonActor(const CID &code);
91+
bool isSingletonActor(const CodeId &code);
4992

5093
extern const CID kEmptyObjectCid;
5194

52-
extern const CID kAccountCodeCid, kCronCodeCid, kStoragePowerCodeCid,
95+
extern const CodeId kAccountCodeCid, kCronCodeCid, kStoragePowerCodeCid,
5396
kStorageMarketCodeCid, kStorageMinerCodeCid, kMultisigCodeCid,
5497
kInitCodeCid, kPaymentChannelCodeCid;
5598

core/vm/state/state_tree.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "vm/actor/init_actor.hpp"
1111

1212
namespace fc::vm::state {
13+
using actor::ActorSubstateCID;
1314
using codec::cbor::decode;
1415
using primitives::address::encodeToString;
1516

@@ -50,7 +51,7 @@ namespace fc::vm::state {
5051
store_->getCbor<actor::InitActorState>(init_actor.head));
5152
OUTCOME_TRY(address_id, init_actor_state.addActor(store_, address));
5253
OUTCOME_TRY(init_actor_state_cid, store_->setCbor(init_actor_state));
53-
init_actor.head = init_actor_state_cid;
54+
init_actor.head = ActorSubstateCID{init_actor_state_cid};
5455
OUTCOME_TRY(set(actor::kInitAddress, init_actor));
5556
OUTCOME_TRY(set(address_id, actor));
5657
return std::move(address_id);

test/core/vm/actor/actor_test.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,34 @@
1414
* @then Equal
1515
*/
1616
TEST(ActorTest, CidGoCompatibility) {
17-
EXPECT_EQ(fc::vm::actor::kAccountCodeCid, "0155000d66696c2f312f6163636f756e74"_cid);
17+
EXPECT_EQ(fc::vm::actor::kAccountCodeCid,
18+
"0155000d66696c2f312f6163636f756e74"_cid);
1819
EXPECT_EQ(fc::vm::actor::kCronCodeCid, "0155000a66696c2f312f63726f6e"_cid);
19-
EXPECT_EQ(fc::vm::actor::kStoragePowerCodeCid, "0155000b66696c2f312f706f776572"_cid);
20-
EXPECT_EQ(fc::vm::actor::kStorageMarketCodeCid, "0155000c66696c2f312f6d61726b6574"_cid);
21-
EXPECT_EQ(fc::vm::actor::kStorageMinerCodeCid, "0155000b66696c2f312f6d696e6572"_cid);
22-
EXPECT_EQ(fc::vm::actor::kMultisigCodeCid, "0155000e66696c2f312f6d756c7469736967"_cid);
20+
EXPECT_EQ(fc::vm::actor::kStoragePowerCodeCid,
21+
"0155000b66696c2f312f706f776572"_cid);
22+
EXPECT_EQ(fc::vm::actor::kStorageMarketCodeCid,
23+
"0155000c66696c2f312f6d61726b6574"_cid);
24+
EXPECT_EQ(fc::vm::actor::kStorageMinerCodeCid,
25+
"0155000b66696c2f312f6d696e6572"_cid);
26+
EXPECT_EQ(fc::vm::actor::kMultisigCodeCid,
27+
"0155000e66696c2f312f6d756c7469736967"_cid);
2328
EXPECT_EQ(fc::vm::actor::kInitCodeCid, "0155000a66696c2f312f696e6974"_cid);
24-
EXPECT_EQ(fc::vm::actor::kPaymentChannelCodeCid, "0155000b66696c2f312f7061796368"_cid);
29+
EXPECT_EQ(fc::vm::actor::kPaymentChannelCodeCid,
30+
"0155000b66696c2f312f7061796368"_cid);
2531

26-
EXPECT_EQ(fc::vm::actor::kEmptyObjectCid, "01711220c19a797fa1fd590cd2e5b42d1cf5f246e29b91684e2f87404b81dc345c7a56a0"_cid);
32+
EXPECT_EQ(
33+
fc::vm::actor::kEmptyObjectCid,
34+
"01711220c19a797fa1fd590cd2e5b42d1cf5f246e29b91684e2f87404b81dc345c7a56a0"_cid);
2735
}
2836

2937
/** Actor CBOR encoding and decoding */
3038
TEST(ActorTest, ActorCbor) {
31-
fc::vm::actor::Actor actor{fc::vm::actor::kAccountCodeCid, fc::vm::actor::kCronCodeCid, 3, 5};
32-
expectEncodeAndReencode(actor, "84d82a52000155000d66696c2f312f6163636f756e74d82a4f000155000a66696c2f312f63726f6e03420005"_unhex);
39+
fc::vm::actor::Actor actor{
40+
fc::vm::actor::kAccountCodeCid,
41+
fc::vm::actor::ActorSubstateCID{fc::vm::actor::kCronCodeCid},
42+
3,
43+
5};
44+
expectEncodeAndReencode(
45+
actor,
46+
"84d82a52000155000d66696c2f312f6163636f756e74d82a4f000155000a66696c2f312f63726f6e03420005"_unhex);
3347
}

test/core/vm/actor/invoker_test.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,28 +20,34 @@ TEST(InvokerTest, InvokeCron) {
2020
Invoker invoker;
2121
fc::vm::MockVMContext vmc;
2222

23-
EXPECT_OUTCOME_ERROR(Invoker::CANT_INVOKE_ACCOUNT_ACTOR, invoker.invoke({kAccountCodeCid}, vmc, 0, {}));
24-
EXPECT_OUTCOME_ERROR(Invoker::NO_CODE_OR_METHOD, invoker.invoke({kEmptyObjectCid}, vmc, 0, {}));
25-
EXPECT_OUTCOME_ERROR(Invoker::NO_CODE_OR_METHOD, invoker.invoke({kCronCodeCid}, vmc, 1000, {}));
23+
EXPECT_OUTCOME_ERROR(Invoker::CANT_INVOKE_ACCOUNT_ACTOR,
24+
invoker.invoke({kAccountCodeCid}, vmc, 0, {}));
25+
EXPECT_OUTCOME_ERROR(Invoker::NO_CODE_OR_METHOD,
26+
invoker.invoke({CodeId{kEmptyObjectCid}}, vmc, 0, {}));
27+
EXPECT_OUTCOME_ERROR(Invoker::NO_CODE_OR_METHOD,
28+
invoker.invoke({kCronCodeCid}, vmc, 1000, {}));
2629

2730
EXPECT_CALL(vmc, message())
2831
.WillRepeatedly(testing::Return(fc::vm::Message{kInitAddress}));
29-
EXPECT_OUTCOME_ERROR(CronActor::WRONG_CALL, invoker.invoke({kCronCodeCid}, vmc, 2, {}));
32+
EXPECT_OUTCOME_ERROR(CronActor::WRONG_CALL,
33+
invoker.invoke({kCronCodeCid}, vmc, 2, {}));
3034
}
3135

3236
/// decodeActorParams returns error or decoded params
3337
TEST(InvokerTest, DecodeActorParams) {
3438
using fc::vm::actor::decodeActorParams;
3539

3640
// 80 is cbor empty list, not int
37-
EXPECT_OUTCOME_ERROR(fc::vm::actor::DECODE_ACTOR_PARAMS_ERROR, decodeActorParams<int>("80"_unhex));
41+
EXPECT_OUTCOME_ERROR(fc::vm::actor::DECODE_ACTOR_PARAMS_ERROR,
42+
decodeActorParams<int>("80"_unhex));
3843
EXPECT_OUTCOME_EQ(decodeActorParams<int>("03"_unhex), 3);
3944
}
4045

4146
/// encodeActorParams returns error or encoded params
4247
TEST(InvokerTest, EncodeActorParams) {
4348
using fc::vm::actor::encodeActorParams;
4449

45-
EXPECT_OUTCOME_ERROR(fc::vm::actor::ENCODE_ACTOR_PARAMS_ERROR, encodeActorParams(fc::CID()));
50+
EXPECT_OUTCOME_ERROR(fc::vm::actor::ENCODE_ACTOR_PARAMS_ERROR,
51+
encodeActorParams(fc::CID()));
4652
EXPECT_OUTCOME_EQ(encodeActorParams(3), "03"_unhex);
4753
}

test/core/vm/state/state_tree_test.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ using fc::primitives::address::Address;
1717
using fc::storage::hamt::Hamt;
1818
using fc::storage::hamt::HamtError;
1919
using fc::vm::actor::Actor;
20+
using fc::vm::actor::ActorSubstateCID;
21+
using fc::vm::actor::CodeId;
2022
using fc::vm::state::StateTree;
2123

2224
auto kAddressId = Address::makeFromId(13);
23-
const Actor kActor{"010001020001"_cid, "010001020002"_cid, 3, BigInt(5)};
25+
const Actor kActor{CodeId{"010001020001"_cid},
26+
ActorSubstateCID{"010001020002"_cid},
27+
3,
28+
BigInt(5)};
2429

2530
class StateTreeTest : public ::testing::Test {
2631
public:
@@ -74,7 +79,10 @@ TEST_F(StateTreeTest, RegisterNewAddressLookupId) {
7479
EXPECT_OUTCOME_TRUE(empty_map, Hamt(store_).flush());
7580
InitActorState init_actor_state{empty_map, 13};
7681
EXPECT_OUTCOME_TRUE(init_actor_state_cid, store_->setCbor(init_actor_state));
77-
Actor init_actor{"010001020000"_cid, init_actor_state_cid, {}, {}};
82+
Actor init_actor{CodeId{"010001020000"_cid},
83+
ActorSubstateCID{init_actor_state_cid},
84+
{},
85+
{}};
7886
EXPECT_OUTCOME_TRUE_1(tree_.set(kInitAddress, init_actor));
7987
Address address{fc::primitives::address::TESTNET,
8088
fc::primitives::address::ActorExecHash{}};

0 commit comments

Comments
 (0)