Skip to content

Commit 85cd7ad

Browse files
author
Mikhail Tagirov
authored
Wallet (#565)
Signed-off-by: Mikhail Tagirov <[email protected]>
1 parent f48a0cc commit 85cd7ad

File tree

16 files changed

+383
-230
lines changed

16 files changed

+383
-230
lines changed

core/api/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
add_subdirectory(full_node)
77
add_subdirectory(rpc)
88
add_subdirectory(storage_miner)
9+
add_subdirectory(wallet)

core/api/full_node/make.cpp

Lines changed: 35 additions & 185 deletions
Large diffs are not rendered by default.

core/api/full_node/make.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#pragma once
77

88
#include "api/full_node/node_api.hpp"
9+
#include "api/types/tipset_context.hpp"
910
#include "blockchain/weight_calculator.hpp"
1011
#include "common/logger.hpp"
1112
#include "fwd.hpp"
@@ -56,5 +57,6 @@ namespace fc::api {
5657
const std::shared_ptr<KeyStore> &key_store,
5758
const std::shared_ptr<Discovery> &market_discovery,
5859
const std::shared_ptr<RetrievalClient> &retrieval_market_client,
59-
const std::shared_ptr<OneKey> &wallet_default_address);
60+
const std::function<outcome::result<TipsetContext>(
61+
const TipsetKey &tipset_key, bool interpret)> &tipsetContext);
6062
} // namespace fc::api

core/api/full_node/node_api.hpp

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
#include "api/common_api.hpp"
99
#include "api/network/network_api.hpp"
10+
#include "api/types/key_info.hpp"
11+
#include "api/wallet/wallet_api.hpp"
1012
#include "common/libp2p/peer/cbor_peer_id.hpp"
1113
#include "const.hpp"
1214
#include "data_transfer/types.hpp"
@@ -76,7 +78,6 @@ namespace fc::api {
7678
using vm::message::UnsignedMessage;
7779
using vm::runtime::MessageReceipt;
7880
using vm::version::NetworkVersion;
79-
using SignatureType = crypto::signature::Type;
8081

8182
struct InvocResult {
8283
UnsignedMessage message;
@@ -190,11 +191,6 @@ namespace fc::api {
190191
CID channel_message; // message cid
191192
};
192193

193-
struct KeyInfo {
194-
SignatureType type = SignatureType::kUndefined;
195-
common::Blob<32> private_key;
196-
};
197-
198194
struct Partition {
199195
RleBitset all;
200196
RleBitset faulty;
@@ -295,7 +291,7 @@ namespace fc::api {
295291
* FullNode API is a low-level interface to the Filecoin network full node.
296292
* Provides the latest node API v2.0.0
297293
*/
298-
struct FullNodeApi : public CommonApi, public NetworkApi {
294+
struct FullNodeApi : public CommonApi, public NetworkApi, public WalletApi {
299295
/**
300296
* @note long operation
301297
*/
@@ -783,35 +779,13 @@ namespace fc::api {
783779
jwt::kWritePermission,
784780
void,
785781
const BlockWithCids &)
786-
787-
/** Wallet */
788-
API_METHOD(WalletBalance,
789-
jwt::kReadPermission,
790-
TokenAmount,
791-
const Address &)
792-
API_METHOD(WalletDefaultAddress, jwt::kWritePermission, Address)
793-
API_METHOD(WalletHas, jwt::kWritePermission, bool, const Address &)
794-
API_METHOD(WalletImport, jwt::kAdminPermission, Address, const KeyInfo &)
795-
API_METHOD(WalletNew, jwt::kWritePermission, Address, const std::string &)
796-
API_METHOD(WalletSetDefault, jwt::kWritePermission, void, const Address &)
797-
API_METHOD(WalletSign,
798-
jwt::kSignPermission,
799-
Signature,
800-
const Address &,
801-
const Bytes &)
802-
/** Verify signature by address (may be id or key address) */
803-
API_METHOD(WalletVerify,
804-
jwt::kReadPermission,
805-
bool,
806-
const Address &,
807-
const Bytes &,
808-
const Signature &)
809782
};
810783

811784
template <typename A, typename F>
812785
void visit(const FullNodeApi &, A &&a, const F &f) {
813786
visitCommon(a, f);
814787
visitNet(a, f);
788+
visitWallet(a, f);
815789
f(a.BeaconGetEntry);
816790
f(a.ChainGetBlock);
817791
f(a.ChainGetBlockMessages);
@@ -891,13 +865,5 @@ namespace fc::api {
891865
f(a.StateSectorPreCommitInfo);
892866
f(a.StateWaitMsg);
893867
f(a.SyncSubmitBlock);
894-
f(a.WalletBalance);
895-
f(a.WalletDefaultAddress);
896-
f(a.WalletHas);
897-
f(a.WalletImport);
898-
f(a.WalletNew);
899-
f(a.WalletSetDefault);
900-
f(a.WalletSign);
901-
f(a.WalletVerify);
902868
}
903869
} // namespace fc::api

core/api/network/network_api.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55

66
#pragma once
77

8-
#include "api/common_api.hpp"
8+
#include "api/utils.hpp"
99

1010
namespace fc::api {
11-
class NetworkApi{
11+
namespace jwt = primitives::jwt;
12+
13+
class NetworkApi {
1214
public:
1315
/**
1416
* Returns listen addresses.

core/api/rpc/json.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "api/rpc/json_errors.hpp"
1313
#include "api/rpc/rpc.hpp"
1414
#include "api/storage_miner/storage_api.hpp"
15+
#include "api/types/key_info.hpp"
1516
#include "api/worker_api.hpp"
1617
#include "common/enum.hpp"
1718
#include "common/libp2p/peer/cbor_peer_info.hpp"
@@ -40,7 +41,6 @@ namespace fc::codec::cbor {
4041
} // namespace fc::codec::cbor
4142

4243
namespace fc::api {
43-
using api::ApiSectorInfo;
4444
using codec::cbor::CborDecodeStream;
4545
using common::Blob;
4646
using crypto::signature::BlsSignature;

core/api/types/key_info.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#pragma once
7+
8+
#include "common/blob.hpp"
9+
#include "crypto/signature/signature.hpp"
10+
11+
namespace fc::api {
12+
using SignatureType = crypto::signature::Type;
13+
using common::Blob;
14+
15+
struct KeyInfo {
16+
SignatureType type = SignatureType::kUndefined;
17+
common::Blob<32> private_key;
18+
};
19+
20+
} // namespace fc::api

core/api/types/tipset_context.hpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#pragma once
7+
8+
#include <boost/optional.hpp>
9+
#include "common/outcome.hpp"
10+
#include "primitives/address/address.hpp"
11+
#include "primitives/tipset/tipset.hpp"
12+
#include "vm/actor/actor.hpp"
13+
#include "vm/actor/builtin/states/account/account_actor_state.hpp"
14+
#include "vm/actor/builtin/states/init/init_actor_state.hpp"
15+
#include "vm/actor/builtin/states/market/market_actor_state.hpp"
16+
#include "vm/actor/builtin/states/miner/miner_actor_state.hpp"
17+
#include "vm/actor/builtin/states/reward/reward_actor_state.hpp"
18+
#include "vm/actor/builtin/states/storage_power/storage_power_actor_state.hpp"
19+
#include "vm/actor/builtin/states/verified_registry/verified_registry_actor_state.hpp"
20+
#include "vm/interpreter/interpreter.hpp"
21+
#include "vm/state/impl/state_tree_impl.hpp"
22+
#include "vm/state/resolve_key.hpp"
23+
24+
namespace fc::api {
25+
using primitives::tipset::TipsetCPtr;
26+
using vm::state::StateTreeImpl;
27+
using InterpreterResult = vm::interpreter::Result;
28+
using primitives::address::Address;
29+
using vm::actor::kInitAddress;
30+
using vm::actor::kStorageMarketAddress;
31+
using vm::actor::kStoragePowerAddress;
32+
using vm::actor::kVerifiedRegistryAddress;
33+
using vm::actor::builtin::states::AccountActorStatePtr;
34+
using vm::actor::builtin::states::InitActorStatePtr;
35+
using vm::actor::builtin::states::MarketActorStatePtr;
36+
using vm::actor::builtin::states::MinerActorStatePtr;
37+
using vm::actor::builtin::states::PowerActorStatePtr;
38+
using vm::actor::builtin::states::RewardActorStatePtr;
39+
using vm::actor::builtin::states::VerifiedRegistryActorStatePtr;
40+
41+
struct TipsetContext {
42+
TipsetCPtr tipset;
43+
StateTreeImpl state_tree;
44+
boost::optional<InterpreterResult> interpreted;
45+
46+
auto marketState() const -> outcome::result<MarketActorStatePtr> {
47+
OUTCOME_TRY(actor, state_tree.get(kStorageMarketAddress));
48+
return getCbor<MarketActorStatePtr>(state_tree.getStore(), actor.head);
49+
}
50+
51+
auto minerState(const Address &address) const
52+
-> outcome::result<MinerActorStatePtr> {
53+
OUTCOME_TRY(actor, state_tree.get(address));
54+
return getCbor<MinerActorStatePtr>(state_tree.getStore(), actor.head);
55+
}
56+
57+
auto powerState() const -> outcome::result<PowerActorStatePtr> {
58+
OUTCOME_TRY(actor, state_tree.get(kStoragePowerAddress));
59+
return getCbor<PowerActorStatePtr>(state_tree.getStore(), actor.head);
60+
}
61+
62+
auto rewardState() const -> outcome::result<RewardActorStatePtr> {
63+
OUTCOME_TRY(actor, state_tree.get(vm::actor::kRewardAddress));
64+
return getCbor<RewardActorStatePtr>(state_tree.getStore(), actor.head);
65+
}
66+
67+
auto initState() const -> outcome::result<InitActorStatePtr> {
68+
OUTCOME_TRY(actor, state_tree.get(kInitAddress));
69+
return getCbor<InitActorStatePtr>(state_tree.getStore(), actor.head);
70+
}
71+
72+
auto verifiedRegistryState() const
73+
-> outcome::result<VerifiedRegistryActorStatePtr> {
74+
OUTCOME_TRY(actor, state_tree.get(kVerifiedRegistryAddress));
75+
return getCbor<VerifiedRegistryActorStatePtr>(state_tree.getStore(),
76+
actor.head);
77+
}
78+
79+
outcome::result<Address> accountKey(const Address &id) const {
80+
return resolveKey(state_tree, id);
81+
}
82+
83+
// TODO (a.chernyshov) make explicit
84+
// NOLINTNEXTLINE(google-explicit-constructor)
85+
operator IpldPtr() const {
86+
return state_tree.getStore();
87+
}
88+
};
89+
90+
} // namespace fc::api

core/api/wallet/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#
2+
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
#
5+
6+
add_library(wallet
7+
local_wallet.cpp
8+
)
9+
target_link_libraries(wallet
10+
address
11+
)

core/api/wallet/local_wallet.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "api/wallet/local_wallet.hpp"
7+
8+
#include "common/error_text.hpp"
9+
#include "crypto/bls/impl/bls_provider_impl.hpp"
10+
#include "crypto/secp256k1/impl/secp256k1_provider_impl.hpp"
11+
12+
namespace fc::api {
13+
14+
void LocalWallet::fillLocalWalletApi(
15+
const std::shared_ptr<WalletApi> &api,
16+
const std::shared_ptr<KeyStore> &key_store,
17+
const std::function<outcome::result<TipsetContext>(
18+
const TipsetKey &tipset_key, bool interpret)> &ts_ctx,
19+
const std::shared_ptr<OneKey> &wallet_default_address) {
20+
api->WalletBalance = [=](auto &address) -> outcome::result<TokenAmount> {
21+
OUTCOME_TRY(context, ts_ctx({}, false));
22+
OUTCOME_TRY(actor, context.state_tree.tryGet(address));
23+
if (actor) {
24+
return actor->balance;
25+
}
26+
return 0;
27+
};
28+
api->WalletDefaultAddress = [=]() -> outcome::result<Address> {
29+
if (!wallet_default_address->has())
30+
return ERROR_TEXT("WalletDefaultAddress: default wallet is not set");
31+
return wallet_default_address->getCbor<Address>();
32+
};
33+
api->WalletHas = [=](auto address) -> outcome::result<bool> {
34+
if (!address.isKeyType()) {
35+
OUTCOME_TRY(context, ts_ctx({}, false));
36+
OUTCOME_TRYA(address, context.accountKey(address));
37+
}
38+
return key_store->has(address);
39+
};
40+
api->WalletImport = {[=](auto &info) {
41+
return key_store->put(info.type, info.private_key);
42+
}};
43+
api->WalletNew = {[=](auto &type) -> outcome::result<Address> {
44+
Address address;
45+
if (type == "bls") {
46+
OUTCOME_TRYA(address,
47+
key_store->put(crypto::signature::Type::kBls,
48+
crypto::bls::BlsProviderImpl{}
49+
.generateKeyPair()
50+
.value()
51+
.private_key));
52+
} else if (type == "secp256k1") {
53+
OUTCOME_TRYA(address,
54+
key_store->put(crypto::signature::Type::kSecp256k1,
55+
crypto::secp256k1::Secp256k1ProviderImpl{}
56+
.generate()
57+
.value()
58+
.private_key));
59+
} else {
60+
return ERROR_TEXT("WalletNew: unknown type");
61+
}
62+
if (!wallet_default_address->has()) {
63+
wallet_default_address->setCbor(address);
64+
}
65+
return std::move(address);
66+
}};
67+
api->WalletSetDefault = [=](auto &address) -> outcome::result<void> {
68+
wallet_default_address->setCbor(address);
69+
return outcome::success();
70+
};
71+
api->WalletSign = [=](auto address,
72+
auto data) -> outcome::result<Signature> {
73+
if (!address.isKeyType()) {
74+
OUTCOME_TRY(context, ts_ctx({}, false));
75+
OUTCOME_TRYA(address, context.accountKey(address));
76+
}
77+
return key_store->sign(address, data);
78+
};
79+
api->WalletVerify =
80+
[=](auto address, auto data, auto signature) -> outcome::result<bool> {
81+
if (!address.isKeyType()) {
82+
OUTCOME_TRY(context, ts_ctx({}, false));
83+
OUTCOME_TRYA(address, context.accountKey(address));
84+
}
85+
return key_store->verify(address, data, signature);
86+
};
87+
}
88+
89+
} // namespace fc::api

core/api/wallet/local_wallet.hpp

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+
#pragma once
7+
8+
#include "api/wallet/wallet_api.hpp"
9+
10+
#include "api/types/tipset_context.hpp"
11+
#include "storage/keystore/keystore.hpp"
12+
#include "storage/map_prefix/prefix.hpp"
13+
14+
namespace fc::api {
15+
using storage::OneKey;
16+
using storage::keystore::KeyStore;
17+
18+
class LocalWallet {
19+
public:
20+
static void fillLocalWalletApi(
21+
const std::shared_ptr<WalletApi> &api,
22+
const std::shared_ptr<KeyStore> &key_store,
23+
const std::function<outcome::result<TipsetContext>(
24+
const TipsetKey &tipset_key, bool interpret)> &ts_ctx,
25+
const std::shared_ptr<OneKey> &wallet_default_address);
26+
};
27+
28+
} // namespace fc::api

0 commit comments

Comments
 (0)