33// Created by Ruslan Gilvanov on 12.02.2022.
44
55#pragma once
6+ #include < inttypes.h>
67#include " cli/node/node.hpp"
8+ #include " markets/storage/mk_protocol.hpp"
9+ #include " primitives/chain_epoch/chain_epoch.hpp"
10+ #include " primitives/piece/piece.hpp"
711#include " storage/car/car.hpp"
12+ #include " storage/ipfs/api_ipfs_datastore/api_ipfs_datastore.hpp"
813#include " storage/ipld/memory_indexed_car.hpp"
914#include " storage/unixfs/unixfs.hpp"
15+ #include " vm/actor/actor.hpp"
16+ #include " vm/actor/builtin/states/verified_registry/verified_registry_actor_state.hpp"
17+ #include " vm/actor/builtin/v0/verified_registry/verified_registry_actor.hpp"
1018
1119namespace fc ::cli::_node {
1220 using api::FileRef;
21+ using api::FullNodeApi;
1322 using api::ImportRes;
1423 using api::RetrievalOrder;
24+ using boost::lexical_cast;
1525 using ::fc::storage::car::makeCar;
1626 using ::fc::storage::unixfs::wrapFile;
27+ using markets::storage::DataRef;
28+ using primitives::ChainEpoch;
29+ using primitives::StoragePower;
1730 using primitives::address::Address;
31+ using primitives::address::encodeToString;
32+ using primitives::piece::UnpaddedPieceSize;
1833 using proofs::padPiece;
34+ using storage::ipfs::ApiIpfsDatastore;
35+ using vm::actor::kVerifiedRegistryAddress ;
36+ using vm::actor::builtin::states::VerifiedRegistryActorStatePtr;
37+ using vm::VMExitCode;
38+
39+ const ChainEpoch kLoopback = 100 ; // TODO: lookback
40+
41+
42+ StoragePower checkNotary (std::shared_ptr<FullNodeApi> api,
43+ const Address &vaddr) {
44+ auto vid =
45+ cliTry (api->StateLookupID (vaddr, TipsetKey ()),
46+ " Getting IPLD id of data associated with provided address..." );
47+ auto actor =
48+ cliTry (api->StateGetActor (kVerifiedRegistryAddress , TipsetKey ()),
49+ " Getting VerifierActor" );
50+ auto ipfs = std::make_shared<ApiIpfsDatastore>(api);
51+ auto version = cliTry (api->StateNetworkVersion (TipsetKey ()),
52+ " Getting Chain Version..." );
53+ auto state =
54+ cliTry (getCbor<VerifiedRegistryActorStatePtr>(ipfs, actor.head ));
55+ auto res = cliTry (cliTry (state->getVerifiedClientDataCap (vid)),
56+ " Client {} isn't in notary tables" ,
57+ vaddr);
58+ return res;
59+ }
1960
2061 struct clientRetrieve {
2162 struct Args {
@@ -97,6 +138,7 @@ namespace fc::cli::_node {
97138 };
98139
99140<<<<<<< HEAD
141+ <<<<<<< HEAD
100142
101143<<<<<<< HEAD
102144 struct clientGenerateCar {
@@ -112,6 +154,90 @@ namespace fc::cli::_node {
112154=======
113155 struct Node_client_generateCar : Empty{
114156=======
157+ =======
158+ struct Node_client_deal {
159+ struct Args {
160+ CLI_OPTIONAL (" manual-piece-cid" ,
161+ " manually specify piece commitment for data (dataCid must "
162+ " be to a car file)" ,
163+ CID)
164+ man_piece_cid;
165+ CLI_DEFAULT (" manual-piece-size" ,
166+ " if manually specifying piece cid, used to specify size "
167+ " (dataCid must be to a car file)" ,
168+ uint64_t ,
169+ {0 })
170+ man_piece_size;
171+ CLI_BOOL (" manual-stateless-deal" ,
172+ " instructs the node to send an offline deal without registering "
173+ " it with the deallist/fsm" )
174+ man_stateless;
175+ CLI_OPTIONAL (" from" , " specify address to fund the deal with" , Address)
176+ from;
177+ CLI_DEFAULT (" start-epoch" ,
178+ " specify the epoch that the deal should start at" ,
179+ ChainEpoch,
180+ {-1 })
181+ start_epoch;
182+ CLI_DEFAULT (" cid-base" ,
183+ " Multibase encoding used for version 1 CIDs in output." ,
184+ std::string,
185+ {" base-32" })
186+ cid_base;
187+ CLI_BOOL (" fast-retrieval" ,
188+ " indicates that data should be available for fast retrieval" )
189+ fast_ret;
190+ CLI_BOOL (" verified-deal" ,
191+ " indicate that the deal counts towards verified client tota" )
192+ verified_deal;
193+ CLI_DEFAULT (
194+ " provider-collateral" ,
195+ " specify the requested provider collateral the miner should put up" ,
196+ TokenAmount,
197+ {0 })
198+ collateral;
199+
200+ CLI_OPTS () {
201+ Opts opts;
202+ man_piece_cid (opts);
203+ man_piece_size (opts);
204+ man_stateless (opts);
205+ from (opts);
206+ start_epoch (opts);
207+ cid_base (opts);
208+ fast_ret (opts);
209+ verified_deal (opts);
210+ collateral (opts);
211+ return opts;
212+ }
213+ };
214+
215+ CLI_RUN () {
216+ ChainEpoch kMinDealDuration {60 }; // TODO: read from config;
217+ ChainEpoch kMaxDealDuration {160 };
218+ auto data_cid{cliArgv<CID>(
219+ argv, 0 , " dataCid comes from running 'lotus client import" )};
220+ auto miner{cliArgv<Address>(
221+ argv, 1 , " address of the miner you wish to make a deal with" )};
222+ auto price{
223+ cliArgv<TokenAmount>(argv, 2 , " price calculated in FIL/Epoch" )};
224+ auto duration{cliArgv<ChainEpoch>(
225+ argv, 3 , " is a period of storing the data for, in blocks" )};
226+ Node::Api api{argm};
227+ if (duration < kMinDealDuration ) throw CliError (" Minimal deal duration is {}" , kMinDealDuration );
228+ if (duration < kMaxDealDuration ) throw CliError (" Max deal duration is {}" , kMaxDealDuration );
229+
230+ Address address_from =
231+ args.from ? *args.from : cliTry (api._ ->WalletDefaultAddress ());
232+ UnpaddedPieceSize piece_size{*args.man_piece_size };
233+ DataRef data_ref = {.transfer_type = " graphsync" ,
234+ .root = data_cid,
235+ .piece_cid = *args.man_piece_cid ,
236+ .piece_size = piece_size};
237+ }
238+ };
239+
240+ >>>>>>> 3d9435d6 (FFi+ and client updates)
115241 struct Node_client_generateCar : Empty {
116242>>>>>>> f1466404 (client updates)
117243 CLI_RUN() {
@@ -152,6 +278,7 @@ namespace fc::cli::_node {
152278 }
153279 };
154280
281+ <<<<<<< HEAD
155282<<<<<<< HEAD
156283<<<<<<< HEAD
157284 struct clientFind {
@@ -161,8 +288,42 @@ namespace fc::cli::_node {
161288=======
162289 struct Node_client_find {};
163290>>>>>>> f1466404 (client updates)
291+ =======
292+ struct Node_client_find {
293+ struct Args {
294+ CLI_OPTIONAL (" piece-cid" ,
295+ " require data to be retrieved from a specific Piece CID" ,
296+ CID)
297+ piece_cid;
298+ CLI_OPTS () {
299+ Opts opts;
300+ piece_cid (opts);
301+ }
302+ };
303+ CLI_RUN () {
304+ auto data_cid{cliArgv<CID>(argv, 0 , " data-cid" )};
305+ Node::Api api{argm};
306+ auto querry_offers =
307+ cliTry (api._ ->ClientFindData (data_cid, *args.piece_cid ));
308+ for (const auto &offer : querry_offers) {
309+ if (offer.error == " " ) {
310+ fmt::print (" ERROR: {}@{}: {}\n " ,
311+ encodeToString (offer.miner ),
312+ offer.peer .peer_id .toHex (),
313+ offer.error );
314+ } else {
315+ fmt::print (" RETRIEVAL: {}@{}-{}-{}\n " ,
316+ encodeToString (offer.miner ),
317+ offer.peer .peer_id .toHex (),
318+ offer.min_price ,
319+ offer.size );
320+ }
321+ }
322+ }
323+ };
324+ >>>>>>> 3d9435d6 (FFi+ and client updates)
164325
165- struct Node_client_listRetrieval {
326+ struct Node_client_listRetrievals { // TODO: Done
166327 struct Args {
167328<<<<<<< HEAD
168329 CLI_BOOL (" verbose" , " print verbose deal details" )verbose;
@@ -202,6 +363,7 @@ namespace fc::cli::_node {
202363 };
203364
204365<<<<<<< HEAD
366+ <<<<<<< HEAD
205367
206368
207369<<<<<<< HEAD
@@ -296,6 +458,9 @@ namespace fc::cli::_node {
296458=======
297459 struct Node_client_inspectDeal {
298460>>>>>>> f1466404 (client updates)
461+ =======
462+ struct Node_client_inspectDeal { // TODO: continue
463+ >>>>>>> 3d9435d6 (FFi+ and client updates)
299464 struct Args {
300465 CLI_OPTIONAL (" proposal-cid" , " proposal cid of deal to be inspected" , CID)
301466 proposal_cid;
@@ -311,6 +476,29 @@ namespace fc::cli::_node {
311476 Node::Api api{argm};
312477 }
313478 };
479+
480+ struct Node_client_dealStats {
481+ struct Args {
482+ CLI_DEFAULT (" newer-than" ,
483+ " list all deals stas that was made after given period" ,
484+ ChainEpoch,
485+ {0 })newer;
486+ CLI_OPTS (){
487+ Opts opts;
488+ newer (opts);
489+ return opts;
490+ }
491+ };
492+ CLI_RUN (){
493+ Node::Api api{argm};
494+ auto deals = cliTry (api._ ->ClientListDeals ());
495+ for (const auto deal: deals){
496+
497+ }// TODO: Continue
498+
499+ }
500+ };
501+
314502 struct Node_client_list_deals {
315503 struct Args {
316504 CLI_BOOL (" show-failed" , " show failed/failing deals" ) failed_show;
@@ -348,9 +536,12 @@ namespace fc::cli::_node {
348536 " Getting address of default wallet..." ));
349537 auto balance = cliTry (api._ ->StateMarketBalance (addr, TipsetKey ()));
350538
351- fmt::print (" Escrowed Funds: {}\n " , AttoFil{balance.escrow });
352- fmt::print (" Locked Funds: {}\n " , AttoFil{balance.locked });
353- // TODO: Reserved and Avaliable
539+ fmt::print (" Escrowed Funds: {}\n " ,
540+ lexical_cast<std::string>(balance.escrow ));
541+ fmt::print (" Locked Funds: {}\n " ,
542+ lexical_cast<std::string>(balance.locked ));
543+ fmt::print (" Avaliable: {}\n " ,
544+ lexical_cast<std::string>(balance.escrow - balance.locked ));
354545 }
355546 };
356547
@@ -418,7 +609,91 @@ namespace fc::cli::_node {
418609
419610 CLI_RUN () {
420611 auto target{cliArgv<Address>(argv, 0 , " target address" )};
421- auto allowness{cliArgv<AttoFil>(argv, 1 , " amount" )};
612+ auto allowness{cliArgv<TokenAmount>(argv, 1 , " amount" )};
613+ Node::Api api{argm};
614+ auto dcap = checkNotary (api._ , *args.from );
615+ if (dcap < allowness)
616+ throw CliError (
617+ " cannot allot more allowance than notary data cap: {} < {}" ,
618+ dcap,
619+ allowness);
620+ auto encoded_params = cliTry (codec::cbor::encode (
621+ vm::actor::builtin::v0::verified_registry::AddVerifiedClient::Params{
622+ target, allowness}));
623+ auto signed_message = cliTry (api._ ->MpoolPushMessage (
624+ {kVerifiedRegistryAddress ,
625+ *args.from ,
626+ {},
627+ 0 ,
628+ 0 ,
629+ 0 ,
630+ vm::actor::builtin::v0::verified_registry::AddVerifiedClient::Number,
631+ encoded_params},
632+ api::kPushNoSpec ));
633+
634+ fmt::print (" message sent, now waiting on cid: {}" , signed_message.getCid ());
635+ auto mwait = cliTry (api._ ->StateWaitMsg (signed_message.getCid (), kMessageConfidence , kLoopback , false ));
636+ if (mwait.receipt .exit_code != VMExitCode::kOk ) throw CliError (" failed to add verified client" );
637+ fmt::print (" Client {} was added successfully!" , target);
638+ }
639+ };
640+
641+ struct Node_client_checkClientDataCap : Empty {
642+ CLI_RUN () {
643+ auto address{cliArgv<Address>(argv, 0 , " address of client" )};
644+ Node::Api api{argm};
645+ auto res = cliTry (api._ ->StateVerifiedClientStatus (address, TipsetKey ()),
646+ " Getting Verified Client info..." );
647+ fmt::print (" Client {} info: {}" , encodeToString (address), res);
648+ }
649+ };
650+
651+ struct Node_client_listNotaries : Empty{
652+ CLI_RUN (){
653+ Node::Api api{argm};
654+ auto actor =
655+ cliTry (api._ ->StateGetActor (kVerifiedRegistryAddress , TipsetKey ()),
656+ " Getting VerifierActor" );
657+ auto ipfs = std::make_shared<ApiIpfsDatastore>(api._ );
658+ auto version = cliTry (api._ ->StateNetworkVersion (TipsetKey ()),
659+ " Getting Chain Version..." );
660+ auto state =
661+ cliTry (getCbor<VerifiedRegistryActorStatePtr>(ipfs, actor.head ));
662+
663+ cliTry (state->verifiers .visit ([=](auto &key, auto &value)->outcome ::result<void >{
664+ fmt::print (" {}: {}" , key, value);
665+ return outcome::success ();
666+ }));
667+ }
668+ };
669+
670+
671+ struct Node_client_listClients : Empty{
672+ CLI_RUN (){
673+ Node::Api api{argm};
674+ auto actor =
675+ cliTry (api._ ->StateGetActor (kVerifiedRegistryAddress , TipsetKey ()),
676+ " Getting VerifierActor" );
677+ auto ipfs = std::make_shared<ApiIpfsDatastore>(api._ );
678+ auto version = cliTry (api._ ->StateNetworkVersion (TipsetKey ()),
679+ " Getting Chain Version..." );
680+ auto state =
681+ cliTry (getCbor<VerifiedRegistryActorStatePtr>(ipfs, actor.head ));
682+
683+ cliTry (state->verified_clients .visit ([=](auto &key, auto &value)->outcome ::result<void >{
684+ fmt::print (" {}: {}" , key, value);
685+ return outcome::success ();
686+ }));
687+ }
688+ };
689+
690+
691+ struct Node_client_checkNotaryDataCap : Empty{
692+ CLI_RUN (){
693+ auto address{cliArgv<Address>(argv, 0 , " address" )};
694+ Node::Api api{argm};
695+ auto dcap = checkNotary (api._ , address);
696+ fmt::print (" DataCap amount: {}" , dcap);
422697 }
423698 };
424699
0 commit comments