Skip to content

Commit e9938ae

Browse files
author
Yura Zarudniy
authored
refactor chain randomness (#109)
* implement feature Signed-off-by: Yura Zarudniy <[email protected]> * refactor chainstore Signed-off-by: Yura Zarudniy <[email protected]> * try fix under ref Signed-off-by: Yura Zarudniy <[email protected]> * fix review issues Signed-off-by: Yura Zarudniy <[email protected]>
1 parent 117a058 commit e9938ae

File tree

10 files changed

+301
-162
lines changed

10 files changed

+301
-162
lines changed

core/crypto/randomness/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,13 @@ target_link_libraries(randomness_provider
1010
buffer
1111
p2p::p2p_sha
1212
)
13+
14+
add_library(chain_randomness_provider
15+
impl/chain_randomness_provider_impl.cpp
16+
)
17+
target_link_libraries(chain_randomness_provider
18+
Boost::boost
19+
blob
20+
buffer
21+
p2p::p2p_sha
22+
)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef CPP_FILECOIN_CORE_CRYPTO_RANDOMNESS_CHAIN_RANDOMNESS_PROVIDER_HPP
7+
#define CPP_FILECOIN_CORE_CRYPTO_RANDOMNESS_CHAIN_RANDOMNESS_PROVIDER_HPP
8+
9+
#include "crypto/randomness/randomness_types.hpp"
10+
#include "primitives/cid/cid.hpp"
11+
12+
namespace fc::crypto::randomness {
13+
14+
/**
15+
* @class ChainRandomnessProvider provides method for calculating chain
16+
* randomness
17+
*/
18+
class ChainRandomnessProvider {
19+
public:
20+
virtual ~ChainRandomnessProvider() = default;
21+
22+
/** @brief calculate randomness */
23+
virtual outcome::result<Randomness> sampleRandomness(
24+
const std::vector<CID> &block_cids, uint64_t round) = 0;
25+
};
26+
} // namespace fc::crypto::randomness
27+
28+
#endif // CPP_FILECOIN_CORE_CRYPTO_RANDOMNESS_CHAIN_RANDOMNESS_PROVIDER_HPP
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "crypto/randomness/impl/chain_randomness_provider_impl.hpp"
7+
8+
#include <boost/assert.hpp>
9+
#include <libp2p/crypto/sha/sha256.hpp>
10+
#include "common/le_encoder.hpp"
11+
#include "primitives/ticket/ticket.hpp"
12+
#include "primitives/tipset/tipset_key.hpp"
13+
#include "storage/chain/chain_store.hpp"
14+
15+
namespace fc::crypto::randomness {
16+
17+
using crypto::randomness::Randomness;
18+
using primitives::ticket::Ticket;
19+
using primitives::tipset::TipsetKey;
20+
21+
namespace {
22+
/**
23+
* @brief ChainStore needs its own randomnes calculation function
24+
* @return randomness value
25+
*/
26+
crypto::randomness::Randomness drawRandomness(const Ticket &ticket,
27+
uint64_t round) {
28+
common::Buffer buffer{};
29+
const size_t bytes_required = sizeof(round) + ticket.bytes.size();
30+
buffer.reserve(bytes_required);
31+
32+
buffer.put(ticket.bytes);
33+
common::encodeLebInteger(round, buffer);
34+
35+
auto hash = libp2p::crypto::sha256(buffer);
36+
37+
return crypto::randomness::Randomness(hash);
38+
}
39+
} // namespace
40+
41+
ChainRandomnessProviderImpl::ChainRandomnessProviderImpl(
42+
std::shared_ptr<storage::blockchain::ChainStore> chain_store)
43+
: chain_store_(std::move(chain_store)) {
44+
BOOST_ASSERT_MSG(chain_store_ != nullptr,
45+
"chain_store argument == nullptr");
46+
}
47+
48+
outcome::result<Randomness> ChainRandomnessProviderImpl::sampleRandomness(
49+
const std::vector<CID> &block_cids, uint64_t round) {
50+
std::reference_wrapper<const std::vector<CID>> cids{block_cids};
51+
52+
while (true) {
53+
OUTCOME_TRY(tipset, chain_store_->loadTipset(TipsetKey{cids.get()}));
54+
OUTCOME_TRY(min_ticket_block, tipset.getMinTicketBlock());
55+
56+
if (tipset.height <= round) {
57+
BOOST_ASSERT_MSG(min_ticket_block.get().ticket.has_value(),
58+
"min ticket block has no value, internal error");
59+
60+
return drawRandomness(*min_ticket_block.get().ticket, round);
61+
}
62+
63+
// special case for lookback behind genesis block
64+
if (min_ticket_block.get().height == 0) {
65+
// round is negative
66+
auto &&negative_hash =
67+
drawRandomness(*min_ticket_block.get().ticket, round - 1);
68+
// for negative lookbacks, just use the hash of the positive ticket hash
69+
// value
70+
auto &&positive_hash = libp2p::crypto::sha256(negative_hash);
71+
return Randomness{positive_hash};
72+
}
73+
74+
// TODO (yuraz) I know it's very ugly, and needs to be refactored
75+
// I translated it directly from go to C++
76+
cids = min_ticket_block.get().parents;
77+
}
78+
}
79+
80+
} // namespace fc::crypto::randomness
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef CPP_FILECOIN_CORE_CRYPTO_RANDOMNESS_IMPL_CHAIN_RANDOMNESS_PROVIDER_IMPL_HPP
7+
#define CPP_FILECOIN_CORE_CRYPTO_RANDOMNESS_IMPL_CHAIN_RANDOMNESS_PROVIDER_IMPL_HPP
8+
9+
#include "crypto/randomness/chain_randomness_provider.hpp"
10+
#include "storage/chain/chain_store.hpp"
11+
12+
namespace fc::crypto::randomness {
13+
class ChainRandomnessProviderImpl : public ChainRandomnessProvider {
14+
public:
15+
~ChainRandomnessProviderImpl() override = default;
16+
17+
explicit ChainRandomnessProviderImpl(
18+
std::shared_ptr<storage::blockchain::ChainStore> chain_store);
19+
20+
outcome::result<Randomness> sampleRandomness(
21+
const std::vector<CID> &block_cids, uint64_t round) override;
22+
23+
private:
24+
std::shared_ptr<storage::blockchain::ChainStore> chain_store_;
25+
};
26+
} // namespace fc::crypto::randomness
27+
28+
#endif // CPP_FILECOIN_CORE_CRYPTO_RANDOMNESS_IMPL_CHAIN_RANDOMNESS_PROVIDER_IMPL_HPP

core/storage/chain/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22
# SPDX-License-Identifier: Apache-2.0
33

44
add_library(chain_store
5-
chain_store.cpp
5+
impl/chain_store_impl.cpp
66
)
77
target_link_libraries(chain_store
8+
chain_randomness_provider
89
datastore_key
910
ipfs_blockservice
1011
logger

core/storage/chain/chain_store.hpp

Lines changed: 13 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,8 @@
66
#ifndef CPP_FILECOIN_CORE_STORAGE_CHAIN_CHAIN_STORE_HPP
77
#define CPP_FILECOIN_CORE_STORAGE_CHAIN_CHAIN_STORE_HPP
88

9-
#include <map>
10-
11-
#include "blockchain/block_validator.hpp"
12-
#include "blockchain/weight_calculator.hpp"
13-
#include "common/logger.hpp"
14-
#include "common/outcome.hpp"
15-
#include "crypto/randomness/randomness_types.hpp"
16-
#include "primitives/cid/cid.hpp"
9+
#include "primitives/block/block.hpp"
1710
#include "primitives/tipset/tipset.hpp"
18-
#include "storage/chain/chain_data_store.hpp"
19-
#include "storage/ipfs/impl/ipfs_block_service.hpp"
2011

2112
namespace fc::storage::blockchain {
2213

@@ -33,90 +24,36 @@ namespace fc::storage::blockchain {
3324
primitives::tipset::Tipset value;
3425
};
3526

36-
/**
37-
* @struct MmCids is a struct for using in mmCache cache
38-
*/
39-
struct MmCids {
40-
std::vector<CID> bls;
41-
std::vector<CID> secpk;
42-
};
43-
44-
enum class ChainStoreError : int { NO_MIN_TICKET_BLOCK = 1 };
45-
4627
/**
4728
* @class ChainStore keeps track of blocks
4829
*/
4930
class ChainStore {
5031
public:
51-
using BlockValidator = ::fc::blockchain::block_validator::BlockValidator;
32+
using BlockHeader = primitives::block::BlockHeader;
33+
using ChainRandomnessProvider = crypto::randomness::ChainRandomnessProvider;
34+
using Randomness = crypto::randomness::Randomness;
5235
using Tipset = primitives::tipset::Tipset;
5336
using TipsetKey = primitives::tipset::TipsetKey;
54-
using Randomness = crypto::randomness::Randomness;
55-
using BlockHeader = primitives::block::BlockHeader;
56-
using WeightCalculator = ::fc::blockchain::weight::WeightCalculator;
5737

58-
/* @brief creates new ChainStore instance */
59-
static outcome::result<std::shared_ptr<ChainStore>> create(
60-
std::shared_ptr<ipfs::IpfsBlockService> block_service,
61-
std::shared_ptr<ChainDataStore> data_store,
62-
std::shared_ptr<BlockValidator> block_validator,
63-
std::shared_ptr<WeightCalculator> weight_calculator);
64-
65-
/** @brief stores head tipset */
66-
outcome::result<void> writeHead(const Tipset &tipset);
67-
68-
/** @brief loads data from block storage and initializes storage */
69-
outcome::result<void> load();
38+
virtual ~ChainStore() = default;
7039

7140
/**
7241
* @brief loads tipset from store
7342
* @param key tipset key
7443
*/
75-
outcome::result<Tipset> loadTipset(const TipsetKey &key);
76-
77-
// TODO(yuraz): FIL-151 add notifications
78-
// TODO(yuraz): FIL-151 implement items caching to avoid refetching them
44+
virtual outcome::result<Tipset> loadTipset(const TipsetKey &key) = 0;
7945

80-
/** @brief draws randomness */
81-
outcome::result<Randomness> sampleRandomness(const std::vector<CID> &blks,
82-
uint64_t round);
83-
84-
/** @brief finds block by its cid */
85-
outcome::result<BlockHeader> getBlock(const CID &cid) const;
46+
/** @brief creates chain randomness provider */
47+
virtual std::shared_ptr<ChainRandomnessProvider>
48+
createRandomnessProvider() = 0;
8649

8750
/** @brief adds block to store */
88-
outcome::result<void> addBlock(const BlockHeader &block);
89-
90-
private:
91-
ChainStore(std::shared_ptr<ipfs::IpfsBlockService> block_service,
92-
std::shared_ptr<ChainDataStore> data_store,
93-
std::shared_ptr<BlockValidator> block_validator,
94-
std::shared_ptr<WeightCalculator> weight_calculator);
95-
96-
ChainStore(ChainStore &&other) = default;
97-
98-
outcome::result<void> takeHeaviestTipset(const Tipset &tipset);
99-
100-
outcome::result<void> persistBlockHeaders(
101-
const std::vector<std::reference_wrapper<const BlockHeader>>
102-
&block_headers);
103-
104-
outcome::result<Tipset> expandTipset(const BlockHeader &block_header);
51+
virtual outcome::result<void> addBlock(const BlockHeader &block) = 0;
10552

106-
outcome::result<void> updateHeavierTipset(const Tipset &tipset);
107-
108-
std::shared_ptr<ipfs::IpfsBlockService> block_service_;
109-
std::shared_ptr<ChainDataStore> data_store_;
110-
std::shared_ptr<BlockValidator> block_validator_;
111-
std::shared_ptr<WeightCalculator> weight_calculator_;
112-
113-
boost::optional<Tipset> heaviest_tipset_;
114-
std::map<uint64_t, std::vector<CID>> tipsets_;
115-
116-
common::Logger logger_;
53+
/** @brief finds block by its cid */
54+
virtual outcome::result<BlockHeader> getBlock(const CID &cid) const = 0;
11755
};
118-
} // namespace fc::storage::blockchain
11956

120-
OUTCOME_HPP_DECLARE_ERROR(fc::storage::blockchain, ChainStoreError);
57+
} // namespace fc::storage::blockchain
12158

12259
#endif // CPP_FILECOIN_CORE_STORAGE_CHAIN_CHAIN_STORE_HPP

0 commit comments

Comments
 (0)