Skip to content

Commit 4cc3b53

Browse files
IPLD block refactor (#146)
1 parent 1906380 commit 4cc3b53

File tree

11 files changed

+153
-196
lines changed

11 files changed

+153
-196
lines changed

core/blockchain/block_validator/impl/block_validator_impl.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "blockchain/block_validator/impl/syntax_rules.hpp"
1010
#include "codec/cbor/cbor.hpp"
1111
#include "storage/amt/amt.hpp"
12+
#include "storage/ipld/ipld_block.hpp"
1213

1314
namespace fc::blockchain::block_validator {
1415
using primitives::address::Protocol;
@@ -20,6 +21,7 @@ namespace fc::blockchain::block_validator {
2021
using BlsCryptoPubKey = crypto::bls::PublicKey;
2122
using SecpCryptoSignature = crypto::secp256k1::Signature;
2223
using SecpCryptoPubKey = crypto::secp256k1::PublicKey;
24+
using IPLDBlock = storage::ipld::IPLDBlock;
2325

2426
const std::map<scenarios::Stage, BlockValidatorImpl::StageExecutor>
2527
BlockValidatorImpl::stage_executors_{
@@ -151,8 +153,9 @@ namespace fc::blockchain::block_validator {
151153

152154
outcome::result<std::reference_wrapper<BlockValidatorImpl::Tipset>>
153155
BlockValidatorImpl::getParentTipset(const BlockHeader &block) const {
156+
IPLDBlock ipld_block = IPLDBlock::create(block);
154157
if (parent_tipset_cache_
155-
&& parent_tipset_cache_.value().first == block.getCID()) {
158+
&& parent_tipset_cache_.value().first == ipld_block.cid) {
156159
return parent_tipset_cache_.value().second;
157160
}
158161
std::vector<BlockHeader> parent_blocks;
@@ -171,7 +174,7 @@ namespace fc::blockchain::block_validator {
171174
}
172175
}
173176
OUTCOME_TRY(tipset, Tipset::create(parent_blocks));
174-
parent_tipset_cache_ = std::make_pair(block.getCID(), std::move(tipset));
177+
parent_tipset_cache_ = std::make_pair(std::move(ipld_block.cid), std::move(tipset));
175178
return parent_tipset_cache_.value().second;
176179
}
177180

core/blockchain/production/impl/block_producer_impl.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "primitives/cid/cid_of_cbor.hpp"
1515
#include "storage/amt/amt.hpp"
1616
#include "storage/ipfs/impl/in_memory_datastore.hpp"
17+
#include "storage/ipld/ipld_block.hpp"
1718

1819
namespace fc::blockchain::production {
1920
using clock::Time;
@@ -24,6 +25,7 @@ namespace fc::blockchain::production {
2425
using storage::amt::Amt;
2526
using storage::amt::Root;
2627
using storage::ipfs::InMemoryDatastore;
28+
using storage::ipld::IPLDBlock;
2729
using vm::message::SignedMessage;
2830
using vm::message::UnsignedMessage;
2931

@@ -58,8 +60,8 @@ namespace fc::blockchain::production {
5860
std::vector<SignedMessage> messages =
5961
message_storage_->getTopScored(config::kBlockMaxMessagesCount);
6062
OUTCOME_TRY(msg_meta, getMessagesMeta(messages));
61-
OUTCOME_TRY(data_storage_->set(msg_meta.getCID(),
62-
msg_meta.getRawBytes()));
63+
IPLDBlock msg_meta_block = IPLDBlock::create(msg_meta);
64+
OUTCOME_TRY(data_storage_->set(msg_meta_block.cid, msg_meta_block.bytes));
6365
std::vector<UnsignedMessage> bls_messages;
6466
std::vector<SignedMessage> secp_messages;
6567
std::vector<crypto::bls::Signature> bls_signatures;
@@ -88,7 +90,7 @@ namespace fc::blockchain::production {
8890
header.height = static_cast<uint64_t>(current_epoch);
8991
header.parent_state_root = std::move(vm_result.state_root);
9092
header.parent_message_receipts = std::move(vm_result.message_receipts);
91-
header.messages = msg_meta.getCID();
93+
header.messages = msg_meta_block.cid;
9294
header.bls_aggregate = std::move(bls_aggregate_sign);
9395
header.timestamp = static_cast<uint64_t>(now.unixTime().count());
9496
header.block_sig = {}; // Block must be signed be Actor Miner

core/primitives/block/block.hpp

Lines changed: 2 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "primitives/ticket/epost_ticket_codec.hpp"
2020
#include "primitives/ticket/ticket.hpp"
2121
#include "primitives/ticket/ticket_codec.hpp"
22-
#include "storage/ipld/ipld_block_common.hpp"
2322
#include "vm/message/message.hpp"
2423

2524
namespace fc::primitives::block {
@@ -28,14 +27,10 @@ namespace fc::primitives::block {
2827
using primitives::address::Address;
2928
using primitives::ticket::EPostProof;
3029
using primitives::ticket::Ticket;
31-
using storage::ipld::IPLDBlockCommon;
3230
using vm::message::SignedMessage;
3331
using vm::message::UnsignedMessage;
3432

35-
struct BlockHeader
36-
: public IPLDBlockCommon<CID::Version::V1,
37-
storage::ipld::HashType::blake2b_256,
38-
storage::ipld::ContentType::DAG_CBOR> {
33+
struct BlockHeader {
3934
Address miner;
4035
boost::optional<Ticket> ticket;
4136
EPostProof epost_proof;
@@ -49,51 +44,11 @@ namespace fc::primitives::block {
4944
uint64_t timestamp;
5045
boost::optional<Signature> block_sig;
5146
uint64_t fork_signaling;
52-
53-
BlockHeader() = default;
54-
55-
BlockHeader(Address miner,
56-
boost::optional<Ticket> ticket,
57-
EPostProof epost_proof,
58-
std::vector<CID> parents,
59-
BigInt parent_weight,
60-
uint64_t height,
61-
CID parent_state_root,
62-
CID parent_message_receipts,
63-
CID messages,
64-
Signature bls_aggregate,
65-
uint64_t timestamp,
66-
boost::optional<Signature> block_sig,
67-
uint64_t fork_signaling)
68-
: miner{std::move(miner)},
69-
ticket{std::move(ticket)},
70-
epost_proof{std::move(epost_proof)},
71-
parents{std::move(parents)},
72-
parent_weight{parent_weight},
73-
height{height},
74-
parent_state_root{parent_state_root},
75-
parent_message_receipts{parent_message_receipts},
76-
messages{messages},
77-
bls_aggregate{bls_aggregate},
78-
timestamp{timestamp},
79-
block_sig{block_sig},
80-
fork_signaling{fork_signaling} {}
81-
82-
outcome::result<std::vector<uint8_t>> getBlockContent() const override {
83-
return codec::cbor::encode<BlockHeader>(*this);
84-
}
8547
};
8648

87-
struct MsgMeta
88-
: public IPLDBlockCommon<CID::Version::V1,
89-
storage::ipld::HashType::blake2b_256,
90-
storage::ipld::ContentType::DAG_CBOR> {
49+
struct MsgMeta {
9150
CID bls_messages;
9251
CID secpk_messages;
93-
94-
outcome::result<std::vector<uint8_t>> getBlockContent() const override {
95-
return codec::cbor::encode<MsgMeta>(*this);
96-
}
9752
};
9853

9954
struct Block {

core/storage/amt/amt.hpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "common/which.hpp"
1515
#include "primitives/cid/cid.hpp"
1616
#include "storage/ipfs/datastore.hpp"
17-
#include "storage/ipld/ipld_block_common.hpp"
1817

1918
namespace fc::storage::amt {
2019
enum class AmtError {
@@ -33,7 +32,6 @@ namespace fc::storage::amt {
3332

3433
using common::which;
3534
using Value = ipfs::IpfsDatastore::Value;
36-
using ipld::IPLDBlockCommon;
3735

3836
struct Node {
3937
using Ptr = std::shared_ptr<Node>;
@@ -119,16 +117,10 @@ namespace fc::storage::amt {
119117
return s;
120118
}
121119

122-
struct Root : public IPLDBlockCommon<CID::Version::V1,
123-
storage::ipld::HashType::blake2b_256,
124-
storage::ipld::ContentType::DAG_CBOR> {
120+
struct Root {
125121
uint64_t height{};
126122
uint64_t count{};
127123
Node node;
128-
129-
outcome::result<std::vector<uint8_t>> getBlockContent() const override {
130-
return codec::cbor::encode<Root>(*this);
131-
}
132124
};
133125

134126
CBOR_TUPLE(Root, height, count, node)

core/storage/ipld/impl/ipld_node_impl.cpp

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
#include <libp2p/crypto/sha/sha256.hpp>
99
#include <libp2p/multi/content_identifier_codec.hpp>
1010
#include <libp2p/multi/multibase_codec/codecs/base58.hpp>
11-
#include <libp2p/multi/multihash.hpp>
1211
#include "ipld_node.pb.h"
1312
#include "storage/ipld/impl/ipld_node_decoder_pb.hpp"
1413

@@ -23,13 +22,22 @@ using Version = libp2p::multi::ContentIdentifier::Version;
2322

2423
namespace fc::storage::ipld {
2524

25+
const CID &IPLDNodeImpl::getCID() const {
26+
return getIPLDBlock().cid;
27+
}
28+
29+
const IPLDNode::Buffer &IPLDNodeImpl::getRawBytes() const {
30+
return getIPLDBlock().bytes;
31+
}
32+
2633
size_t IPLDNodeImpl::size() const {
2734
return getRawBytes().size() + child_nodes_size_;
2835
}
2936

3037
void IPLDNodeImpl::assign(common::Buffer input) {
3138
content_ = std::move(input);
32-
clearCache();
39+
ipld_block_ =
40+
boost::none; // Need to recalculate CID after changing Node content
3341
}
3442

3543
const common::Buffer &IPLDNodeImpl::content() const {
@@ -40,7 +48,8 @@ namespace fc::storage::ipld {
4048
const std::string &name, std::shared_ptr<const IPLDNode> node) {
4149
IPLDLinkImpl link{node->getCID(), name, node->size()};
4250
links_.emplace(name, std::move(link));
43-
clearCache();
51+
ipld_block_ =
52+
boost::none; // Need to recalculate CID after adding link to child node
4453
child_nodes_size_ += node->size();
4554
return outcome::success();
4655
}
@@ -74,6 +83,10 @@ namespace fc::storage::ipld {
7483
return link_refs;
7584
}
7685

86+
IPLDNode::Buffer IPLDNodeImpl::serialize() const {
87+
return Buffer{IPLDNodeEncoderPB::encode(content_, links_)};
88+
}
89+
7790
std::shared_ptr<IPLDNode> IPLDNodeImpl::createFromString(
7891
const std::string &content) {
7992
std::vector<uint8_t> data{content.begin(), content.end()};
@@ -100,8 +113,11 @@ namespace fc::storage::ipld {
100113
return node;
101114
}
102115

103-
outcome::result<std::vector<uint8_t>> IPLDNodeImpl::getBlockContent() const {
104-
return IPLDNodeEncoderPB::encode(content_, links_);
116+
const IPLDBlock &IPLDNodeImpl::getIPLDBlock() const {
117+
if (!ipld_block_) {
118+
ipld_block_ = IPLDBlock::create(*this);
119+
}
120+
return ipld_block_.value();
105121
}
106122
} // namespace fc::storage::ipld
107123

core/storage/ipld/impl/ipld_node_impl.hpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@
1414
#include <boost/optional.hpp>
1515
#include "storage/ipld/impl/ipld_link_impl.hpp"
1616
#include "storage/ipld/impl/ipld_node_encoder_pb.hpp"
17-
#include "storage/ipld/ipld_block_common.hpp"
1817
#include "storage/ipld/ipld_node.hpp"
1918

2019
namespace fc::storage::ipld {
21-
class IPLDNodeImpl : public IPLDNode,
22-
IPLDBlockCommon<CID::Version::V0,
23-
HashType::sha256,
24-
ContentType::DAG_PB> {
20+
class IPLDNodeImpl : public IPLDNode {
2521
public:
22+
const CID &getCID() const override;
23+
24+
const Buffer &getRawBytes() const override;
25+
2626
size_t size() const override;
2727

2828
void assign(common::Buffer input) override;
@@ -42,20 +42,36 @@ namespace fc::storage::ipld {
4242
std::vector<std::reference_wrapper<const IPLDLink>> getLinks()
4343
const override;
4444

45+
Buffer serialize() const override;
46+
4547
static std::shared_ptr<IPLDNode> createFromString(
4648
const std::string &content);
4749

4850
static outcome::result<std::shared_ptr<IPLDNode>> createFromRawBytes(
4951
gsl::span<const uint8_t> input);
5052

53+
const IPLDBlock &getIPLDBlock() const;
54+
5155
private:
5256
common::Buffer content_;
5357
std::map<std::string, IPLDLinkImpl> links_;
5458
IPLDNodeEncoderPB pb_node_codec_;
5559
size_t child_nodes_size_{};
56-
57-
outcome::result<std::vector<uint8_t>> getBlockContent() const override;
60+
mutable boost::optional<IPLDBlock> ipld_block_;
5861
};
62+
63+
template <>
64+
inline IPLDType IPLDBlock::getType<IPLDNodeImpl>() {
65+
return {IPLDType::Version::V0,
66+
IPLDType::Content::DAG_PB,
67+
IPLDType::Hash::sha256};
68+
}
69+
70+
template <>
71+
inline common::Buffer IPLDBlock::serialize<IPLDNodeImpl>(
72+
const IPLDNodeImpl &entity) {
73+
return entity.serialize();
74+
}
5975
} // namespace fc::storage::ipld
6076

6177
#endif

core/storage/ipld/ipld_block.hpp

Lines changed: 56 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,76 @@
88

99
#include <vector>
1010

11+
#include "codec/cbor/cbor.hpp"
1112
#include "common/buffer.hpp"
13+
#include "crypto/hasher/hasher.hpp"
1214
#include "primitives/cid/cid.hpp"
1315

1416
namespace fc::storage::ipld {
17+
18+
/**
19+
* @struct IPLD block CID and content properties
20+
*/
21+
struct IPLDType {
22+
using Version = CID::Version;
23+
using Content = libp2p::multi::MulticodecType::Code;
24+
using Hash = libp2p::multi::HashType;
25+
26+
Version cid_version;
27+
Content content_type;
28+
Hash hash_type;
29+
};
30+
1531
/**
16-
* @class Interface for various data structure, linked with CID
32+
* @struct IPLD block: CID and serialized bytes
1733
*/
18-
class IPLDBlock {
19-
public:
34+
struct IPLDBlock {
35+
CID cid;
36+
common::Buffer bytes;
37+
2038
/**
21-
* @brief Destructor
39+
* @brief Create IPLD block from supported entity
40+
* @tparam T - type of entity
41+
* @param entity - source object
42+
* @return constructed block
2243
*/
23-
virtual ~IPLDBlock() = default;
44+
template <class T>
45+
static IPLDBlock create(const T &entity) {
46+
IPLDType params = IPLDBlock::getType<T>();
47+
common::Buffer bytes = IPLDBlock::serialize(entity);
48+
auto multihash = crypto::Hasher::calculate(params.hash_type, bytes);
49+
return IPLDBlock{CID{params.cid_version, params.content_type, multihash},
50+
bytes};
51+
}
2452

2553
/**
26-
* @brief Get CID of the data structure
27-
* @return IPLD identificator
54+
* @brief Get default IPLD block params:
55+
* @note This method should be specialized for each IPLD entity,
56+
* which uses another types
57+
* @tparam T - type of IPLD entity
58+
* @return IPLD block params
2859
*/
29-
virtual const CID &getCID() const = 0;
60+
template <class T>
61+
static IPLDType getType() {
62+
return {IPLDType::Version::V1,
63+
IPLDType::Content::DAG_CBOR,
64+
IPLDType::Hash::blake2b_256};
65+
}
3066

3167
/**
32-
* @brief Get data structure bytes from cache or generate new
33-
* @return Serialized value
68+
* @brief CBOR serialize IPLD entity
69+
* @note This method should be specialized for each IPLD entity,
70+
* which uses another serialization codec
71+
* @tparam T - type of the entity
72+
* @param entity - object to serialize
73+
* @return serialized bytes
3474
*/
35-
virtual const common::Buffer &getRawBytes() const = 0;
36-
75+
template <class T>
76+
static common::Buffer serialize(const T &entity) {
77+
auto data = codec::cbor::encode(entity);
78+
BOOST_ASSERT(data.has_value());
79+
return common::Buffer{std::move(data.value())};
80+
}
3781
};
3882
} // namespace fc::storage::ipld
3983

0 commit comments

Comments
 (0)