Skip to content

Commit c990990

Browse files
authored
Miner fix (#475)
* Miner fix Signed-off-by: ortyomka <[email protected]> * Update test Signed-off-by: ortyomka <[email protected]>
1 parent c281cf1 commit c990990

37 files changed

+639
-434
lines changed

core/api/full_node/make.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,8 +351,11 @@ namespace fc::api {
351351
return ts_load->load(tipset_key);
352352
};
353353
api->ChainGetTipSetByHeight =
354-
[=](auto height, auto &tipset_key) -> outcome::result<TipsetCPtr> {
354+
[=](auto height, auto tipset_key) -> outcome::result<TipsetCPtr> {
355355
std::shared_lock ts_lock{*env_context.ts_branches_mutex};
356+
if (tipset_key.cids().empty()) {
357+
tipset_key = chain_store->heaviestTipset()->key;
358+
}
356359
OUTCOME_TRY(ts_branch, TsBranch::make(ts_load, tipset_key, ts_main));
357360
OUTCOME_TRY(it, find(ts_branch, height));
358361
return ts_load->lazyLoad(it.second->second);

core/api/rpc/json.hpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "api/worker_api.hpp"
1616
#include "common/enum.hpp"
1717
#include "common/libp2p/peer/cbor_peer_info.hpp"
18+
#include "miner/main/type.hpp"
1819
#include "payment_channel_manager/payment_channel_manager.hpp"
1920
#include "primitives/address/address_codec.hpp"
2021
#include "primitives/cid/cid_of_cbor.hpp"
@@ -40,12 +41,15 @@ namespace fc::codec::cbor {
4041
} // namespace fc::codec::cbor
4142

4243
namespace fc::api {
44+
using api::ApiSectorInfo;
4345
using codec::cbor::CborDecodeStream;
4446
using common::Blob;
4547
using crypto::signature::BlsSignature;
4648
using crypto::signature::Secp256k1Signature;
4749
using crypto::signature::Signature;
4850
using markets::storage::StorageAsk;
51+
using miner::types::PreSealSector;
52+
using mining::SealingState;
4953
using primitives::BigInt;
5054
using primitives::FsStat;
5155
using primitives::kChainEpochUndefined;
@@ -245,6 +249,14 @@ namespace fc::api {
245249
decodeEnum(v, j);
246250
}
247251

252+
ENCODE(SealingState) {
253+
return encode(common::to_int(v));
254+
}
255+
256+
DECODE(SealingState) {
257+
decodeEnum(v, j);
258+
}
259+
248260
ENCODE(PathType) {
249261
return encode(common::to_int(v));
250262
}
@@ -1012,6 +1024,16 @@ namespace fc::api {
10121024
Get(j, "SealedCID", v.sealed_cid);
10131025
}
10141026

1027+
ENCODE(ApiSectorInfo) {
1028+
Value j{rapidjson::kObjectType};
1029+
Set(j, "State", v.state);
1030+
return j;
1031+
}
1032+
1033+
DECODE(ApiSectorInfo) {
1034+
Get(j, "State", v.state);
1035+
}
1036+
10151037
ENCODE(PowerPair) {
10161038
Value j{rapidjson::kObjectType};
10171039
Set(j, "Raw", v.raw);
@@ -1414,6 +1436,48 @@ namespace fc::api {
14141436
decode(v.verified_deal, Get(j, "VerifiedDeal"));
14151437
}
14161438

1439+
ENCODE(PreSealSector) {
1440+
Value j{rapidjson::kObjectType};
1441+
Set(j, "CommR", v.comm_r);
1442+
Set(j, "CommD", v.comm_d);
1443+
Set(j, "SectorID", v.sector_id);
1444+
Set(j, "Deal", v.deal);
1445+
Set(j, "ProofType", v.proof_type);
1446+
return j;
1447+
}
1448+
1449+
DECODE(PreSealSector) {
1450+
decode(v.comm_r, Get(j, "CommR"));
1451+
decode(v.comm_d, Get(j, "CommD"));
1452+
decode(v.sector_id, Get(j, "SectorID"));
1453+
decode(v.deal, Get(j, "Deal"));
1454+
decode(v.proof_type, Get(j, "ProofType"));
1455+
}
1456+
1457+
ENCODE(miner::types::Miner) {
1458+
Value j{rapidjson::kObjectType};
1459+
Set(j, "ID", v.id);
1460+
Set(j, "Owner", v.owner);
1461+
Set(j, "Worker", v.worker);
1462+
Set(j, "PeerId", v.peer_id);
1463+
Set(j, "MarketBalance", v.market_balance);
1464+
Set(j, "PowerBalance", v.power_balance);
1465+
Set(j, "SectorSize", v.sector_size);
1466+
Set(j, "Sectors", v.sectors);
1467+
return j;
1468+
}
1469+
1470+
DECODE(miner::types::Miner) {
1471+
decode(v.id, Get(j, "ID"));
1472+
decode(v.owner, Get(j, "Owner"));
1473+
decode(v.worker, Get(j, "Worker"));
1474+
decode(v.peer_id, Get(j, "PeerId"));
1475+
decode(v.market_balance, Get(j, "MarketBalance"));
1476+
decode(v.power_balance, Get(j, "PowerBalance"));
1477+
decode(v.sector_size, Get(j, "SectorSize"));
1478+
decode(v.sectors, Get(j, "Sectors"));
1479+
}
1480+
14171481
template <typename T>
14181482
ENCODE(Chan<T>) {
14191483
return encode(v.id);

core/api/rpc/wsc.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,8 @@ namespace fc::api::rpc {
136136
}
137137
if (id) {
138138
boost::asio::post(
139-
io2, [this, close, id{*id}, value{std::move(value)}]() mutable {
139+
*thread_chan.io,
140+
[this, close, id{*id}, value{std::move(value)}]() mutable {
140141
std::unique_lock lock{mutex};
141142
auto it{chans.find(id)};
142143
if (it != chans.end()) {

core/api/rpc/wsc.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "api/rpc/json.hpp"
1919
#include "api/rpc/rpc.hpp"
2020
#include "api/visit.hpp"
21+
#include "common/io_thread.hpp"
2122
#include "common/logger.hpp"
2223

2324
namespace fc::api::rpc {
@@ -53,6 +54,7 @@ namespace fc::api::rpc {
5354

5455
private:
5556
std::thread thread;
57+
IoThread thread_chan;
5658
io_context io;
5759
io_context &io2;
5860
boost::asio::executor_work_guard<io_context::executor_type> work_guard;

core/api/storage_miner/storage_api.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,24 @@ namespace fc::api {
6868
return outcome::success();
6969
};
7070

71+
api->SectorsList = [=]() -> outcome::result<std::vector<SectorNumber>> {
72+
std::vector<SectorNumber> result;
73+
for (const auto &sector : miner->getSealing()->getListSectors()) {
74+
if (sector->state != mining::SealingState::kStateUnknown) {
75+
result.push_back(sector->sector_number);
76+
}
77+
}
78+
79+
return result;
80+
};
81+
82+
api->SectorsStatus = [=](SectorNumber id,
83+
bool) -> outcome::result<ApiSectorInfo> {
84+
// TODO(ortyomka): [FIL-421] implement it
85+
OUTCOME_TRY(sector_info, miner->getSealing()->getSectorInfo(id));
86+
return ApiSectorInfo{.state = sector_info->state};
87+
};
88+
7189
api->StorageAttach = [=](const StorageInfo_ &storage_info,
7290
const FsStat &stat) {
7391
return sector_index->storageAttach(storage_info, stat);

core/api/storage_miner/storage_api.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ namespace fc::api {
5959
PaddedPieceSize length;
6060
};
6161

62+
// TODO(ortyomka): [FIL-421] implement it
63+
struct ApiSectorInfo {
64+
mining::SealingState state = mining::SealingState::kStateUnknown;
65+
};
66+
6267
inline bool operator==(const PieceLocation &lhs, const PieceLocation &rhs) {
6368
return lhs.sector_number == rhs.sector_number && lhs.offset == rhs.offset
6469
&& lhs.length == rhs.length;
@@ -106,6 +111,11 @@ namespace fc::api {
106111
void,
107112
const RetrievalAsk &)
108113

114+
API_METHOD(SectorsList, jwt::kReadPermission, std::vector<SectorNumber>)
115+
116+
API_METHOD(
117+
SectorsStatus, jwt::kReadPermission, ApiSectorInfo, SectorNumber, bool)
118+
109119
API_METHOD(StorageAttach,
110120
jwt::kAdminPermission,
111121
void,
@@ -233,6 +243,8 @@ namespace fc::api {
233243
f(a.MarketGetRetrievalAsk);
234244
f(a.MarketSetAsk);
235245
f(a.MarketSetRetrievalAsk);
246+
f(a.SectorsList);
247+
f(a.SectorsStatus);
236248
f(a.StorageAttach);
237249
f(a.StorageInfo);
238250
f(a.StorageReportHealth);

core/miner/main/main.cpp

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "markets/storage/chain_events/impl/chain_events_impl.hpp"
3333
#include "markets/storage/provider/impl/provider_impl.hpp"
3434
#include "miner/impl/miner_impl.hpp"
35+
#include "miner/main/type.hpp"
3536
#include "miner/mining.hpp"
3637
#include "miner/windowpost.hpp"
3738
#include "primitives/address/config.hpp"
@@ -61,13 +62,16 @@ namespace fc {
6162
using libp2p::multi::Multiaddress;
6263
using libp2p::peer::PeerId;
6364
using markets::storage::chain_events::ChainEventsImpl;
65+
using primitives::StoredCounter;
6466
using primitives::address::Address;
6567
using primitives::jwt::kAllPermission;
6668
using primitives::sector::RegisteredSealProof;
6769
using storage::BufferMap;
6870
namespace uuids = boost::uuids;
6971

7072
static const Buffer kActor{cbytes("actor")};
73+
static const std::string kSectorCounterKey = "sector_counter";
74+
constexpr size_t kApiThreadPoolSize = 4;
7175

7276
auto log() {
7377
static common::Logger logger = common::createLogger("miner");
@@ -85,12 +89,42 @@ namespace fc {
8589

8690
/** Path to presealed sectors */
8791
boost::optional<boost::filesystem::path> preseal_path;
92+
boost::optional<boost::filesystem::path> preseal_meta_path;
8893

8994
auto join(const std::string &path) const {
9095
return (repo_path / path).string();
9196
}
9297
};
9398

99+
outcome::result<void> migratePreSealMeta(
100+
const std::string &path,
101+
const Address &maddr,
102+
const std::shared_ptr<storage::PersistentBufferMap> &ds) {
103+
OUTCOME_TRY(file, common::readFile(path));
104+
OUTCOME_TRY(j_file, codec::json::parse(gsl::make_span(file)));
105+
OUTCOME_TRY(
106+
psm, api::decode<std::map<std::string, miner::types::Miner>>(j_file));
107+
108+
const auto it_psm = psm.find(encodeToString(maddr));
109+
if (it_psm == psm.end()) {
110+
return ERROR_TEXT("Miner not found");
111+
}
112+
const auto &meta{it_psm->second};
113+
114+
StoredCounter sc(ds, kSectorCounterKey);
115+
OUTCOME_TRY(max_sector, sc.getNumber());
116+
for (const auto &elem : meta.sectors) {
117+
// TODO(ortyomka): migrate sealing info
118+
119+
if (max_sector < elem.sector_id) {
120+
max_sector = elem.sector_id;
121+
}
122+
}
123+
OUTCOME_TRY(sc.setNumber(max_sector));
124+
125+
return outcome::success();
126+
}
127+
94128
outcome::result<Config> readConfig(int argc, char **argv) {
95129
namespace po = boost::program_options;
96130
Config config;
@@ -112,6 +146,9 @@ namespace fc {
112146
option("pre-sealed-sectors",
113147
po::value(&config.preseal_path),
114148
"Path to presealed sectors");
149+
option("pre-sealed-metadata",
150+
po::value(&config.preseal_meta_path),
151+
"Path to presealed metadata");
115152
desc.add(configProfile());
116153
primitives::address::configCurrentNetwork(option);
117154

@@ -301,9 +338,20 @@ namespace fc {
301338
IoThread sealing_thread;
302339

303340
OUTCOME_TRY(setupMiner(config, *leveldb, host->getId()));
341+
if (config.preseal_meta_path) {
342+
log()->info("Importing pre-sealed sector metadata");
343+
OUTCOME_TRY(migratePreSealMeta(config.preseal_meta_path.value().string(),
344+
*config.actor,
345+
prefixed("/metadata")));
346+
}
304347

305348
auto napi{std::make_shared<api::FullNodeApi>()};
306-
api::rpc::Client wsc{*io};
349+
IoThread io_thread;
350+
std::vector<std::thread> pool;
351+
for (size_t i{0}; i < kApiThreadPoolSize; ++i) {
352+
pool.emplace_back(std::thread{[&] { io_thread.io->run(); }});
353+
}
354+
api::rpc::Client wsc{*io_thread.io};
307355
wsc.setup(*napi);
308356
OUTCOME_TRY(
309357
wsc.connect(config.node_api.first, "/rpc/v0", config.node_api.second));
@@ -352,32 +400,34 @@ namespace fc {
352400
auto remote_store{std::make_shared<sector_storage::stores::RemoteStoreImpl>(
353401
local_store, std::move(auth_headers))};
354402

403+
IoThread io_thread2;
404+
OUTCOME_TRY(wscheduler,
405+
sector_storage::SchedulerImpl::newScheduler(
406+
io_thread2.io, prefixed("scheduler_works/")));
407+
IoThread io_thread3;
355408
OUTCOME_TRY(
356-
wscheduler,
357-
sector_storage::SchedulerImpl::newScheduler(
358-
io, prefixed("scheduler_works/"))); // maybe use another io_context
359-
OUTCOME_TRY(manager,
360-
sector_storage::ManagerImpl::newManager(
361-
io, remote_store, wscheduler, {true, true, true, true}));
409+
manager,
410+
sector_storage::ManagerImpl::newManager(
411+
io_thread3.io, remote_store, wscheduler, {true, true, true, true}));
362412

363413
// TODO(ortyomka): make param
364414
mining::Config default_config{.max_wait_deals_sectors = 2,
365415
.max_sealing_sectors = 0,
366416
.max_sealing_sectors_for_deals = 0,
367417
.wait_deals_delay = std::chrono::hours(6)};
368-
OUTCOME_TRY(
369-
miner,
370-
miner::MinerImpl::newMiner(napi,
371-
*config.actor,
372-
*config.worker,
373-
std::make_shared<primitives::StoredCounter>(
374-
leveldb, "sector_counter"),
375-
prefixed("sealing_fsm/"),
376-
manager,
377-
scheduler,
378-
sealing_thread.io,
379-
default_config,
380-
config.precommit_control));
418+
OUTCOME_TRY(miner,
419+
miner::MinerImpl::newMiner(
420+
napi,
421+
*config.actor,
422+
*config.worker,
423+
std::make_shared<primitives::StoredCounter>(
424+
prefixed("/metadata"), kSectorCounterKey),
425+
prefixed("sealing_fsm/"),
426+
manager,
427+
scheduler,
428+
sealing_thread.io,
429+
default_config,
430+
config.precommit_control));
381431
auto sealing{miner->getSealing()};
382432

383433
OUTCOME_TRY(

core/miner/main/type.hpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#pragma once
7+
8+
#include "primitives/address/address.hpp"
9+
#include "primitives/sector/sector.hpp"
10+
11+
#include <libp2p/peer/peer_id.hpp>
12+
13+
namespace fc::miner::types {
14+
using libp2p::peer::PeerId;
15+
using primitives::RegisteredSealProof;
16+
using primitives::SectorNumber;
17+
using primitives::SectorSize;
18+
using primitives::TokenAmount;
19+
using primitives::address::Address;
20+
using vm::actor::builtin::types::market::DealProposal;
21+
22+
struct PreSealSector {
23+
CID comm_r;
24+
CID comm_d;
25+
SectorNumber sector_id;
26+
DealProposal deal;
27+
RegisteredSealProof proof_type;
28+
};
29+
30+
struct Miner {
31+
Address id;
32+
Address owner;
33+
Address worker;
34+
PeerId peer_id = codec::cbor::kDefaultT<PeerId>();
35+
36+
TokenAmount market_balance;
37+
TokenAmount power_balance;
38+
39+
SectorSize sector_size{};
40+
41+
std::vector<PreSealSector> sectors;
42+
};
43+
} // namespace fc::miner::types

0 commit comments

Comments
 (0)