Skip to content

Commit

Permalink
Merge pull request #164 from nav-io/create_wallet_from_seed
Browse files Browse the repository at this point in the history
Add option to create wallet from seed or audit key
  • Loading branch information
aguycalled authored Sep 13, 2024
2 parents 708ba07 + fc6e84b commit 0f72696
Show file tree
Hide file tree
Showing 33 changed files with 197 additions and 103 deletions.
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ BLSCT_H = \
blsct/wallet/address.h \
blsct/wallet/hdchain.h \
blsct/wallet/helpers.h \
blsct/wallet/import_wallet_type.h \
blsct/wallet/keyman.h \
blsct/wallet/keyring.h \
blsct/wallet/txfactory.h \
Expand Down Expand Up @@ -560,7 +561,6 @@ libbitcoin_node_a_SOURCES = \
blsct/set_mem_proof/set_mem_proof_prover.cpp \
blsct/wallet/verification.cpp \
blsct/signature.cpp \
blsct/wallet/verification.cpp \
chain.cpp \
chainparams.cpp \
consensus/tx_verify.cpp \
Expand Down
2 changes: 1 addition & 1 deletion src/bench/wallet_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ static void WalletCreate(benchmark::Bench& bench, bool encrypted)

fs::path wallet_path = test_setup->m_path_root / strprintf("test_wallet_%d", random.rand32()).c_str();
bench.run([&] {
auto wallet = CreateWallet(context, wallet_path.utf8string(), /*load_on_start=*/std::nullopt, options, status, error_string, warnings);
auto wallet = CreateWallet(context, wallet_path.utf8string(), {}, blsct::IMPORT_MASTER_KEY, /*load_on_start=*/std::nullopt, options, status, error_string, warnings);
assert(status == DatabaseStatus::SUCCESS);
assert(wallet != nullptr);

Expand Down
1 change: 1 addition & 0 deletions src/bitcoin-wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static void SetupWalletToolArgs(ArgsManager& argsman)
argsman.AddArg("-debug=<category>", "Output debugging information (default: 0).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-descriptors", "Create descriptors wallet. Only for 'create'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-blsct", "Create blsct wallet. Only for 'create'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-seed", "Seed used for the wallet creation. Only for 'create'. Can be a master seed or an audit key.", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-legacy", "Create legacy wallet. Only for 'create'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-format=<format>", "The format of the wallet file to create. Either \"bdb\" or \"sqlite\". Only used with 'createfromdump'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -debug is true, 0 otherwise).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
Expand Down
2 changes: 2 additions & 0 deletions src/bls/src/bls_c_impl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,8 @@ int blsAggregateVerifyNoCheck(const blsSignature *sig, const blsPublicKey *pubVe
std::vector<std::future<GT>> futuresMiller;
std::vector<std::future<bool>> futures;
size_t numThreads = std::thread::hardware_concurrency();

futures.reserve(numThreads);

while (n > 0) {
size_t m = mcl::fp::min_<size_t>(n, N);
Expand Down
2 changes: 2 additions & 0 deletions src/blsct/range_proof/bulletproofs/range_proof_logic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ bool RangeProofLogic<T>::VerifyProofs(
// Vector to hold future results from async tasks
std::vector<std::future<bool>> futures;

futures.reserve(proof_transcripts.size());

// Launch a verification task for each proof transcript in parallel
for (const RangeProofWithTranscript<T>& p : proof_transcripts) {
futures.emplace_back(std::async(std::launch::async, [this, &p, max_mn]() -> bool {
Expand Down
16 changes: 16 additions & 0 deletions src/blsct/wallet/import_wallet_type.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2023 The Navio developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef NAVIO_BLSCT_IMPORT_WALLET_TYPE_H
#define NAVIO_BLSCT_IMPORT_WALLET_TYPE_H

namespace blsct {
enum SeedType {
IMPORT_MASTER_KEY,
IMPORT_VIEW_KEY
};

} // namespace blsct

#endif // NAVIO_BLSCT_KEYMAN_H
48 changes: 36 additions & 12 deletions src/blsct/wallet/keyman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ void KeyMan::SetHDSeed(const PrivateKey& key)
throw std::runtime_error(std::string(__func__) + ": AddSpendKey failed");

if (!AddViewKey(viewKey, viewKey.GetPublicKey()))
throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
throw std::runtime_error(std::string(__func__) + ": AddViewKey failed");

if (!AddKeyPubKey(tokenKey, tokenKey.GetPublicKey()))
throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
Expand All @@ -261,13 +261,39 @@ void KeyMan::SetHDSeed(const PrivateKey& key)
wallet::WalletBatch batch(m_storage.GetDatabase());
}

bool KeyMan::SetupGeneration(bool force)
bool KeyMan::SetupGeneration(const std::vector<unsigned char>& seed, const SeedType& type, bool force)
{
if ((CanGenerateKeys() && !force) || m_storage.IsLocked()) {
return false;
}

SetHDSeed(GenerateNewSeed());
if (seed.size() == 32) {
if (type == IMPORT_MASTER_KEY) {
MclScalar scalarSeed;
scalarSeed.SetVch(seed);
SetHDSeed(scalarSeed);
}
} else if (seed.size() == 80) {
if (type == IMPORT_VIEW_KEY) {
std::vector<unsigned char> viewVch(seed.begin(), seed.begin() + 32);
std::vector<unsigned char> spendingVch(seed.begin() + 32, seed.end());

MclScalar scalarView;
scalarView.SetVch(viewVch);

MclG1Point pointSpending;
pointSpending.SetVch(spendingVch);

if (!AddViewKey(scalarView, PrivateKey(scalarView).GetPublicKey()))
throw std::runtime_error(std::string(__func__) + ": AddViewKey failed");

if (!AddSpendKey(pointSpending))
throw std::runtime_error(std::string(__func__) + ": AddSpendKey failed");
}
} else {
SetHDSeed(GenerateNewSeed());
}

if (!NewSubAddressPool() || !NewSubAddressPool(-1) || !NewSubAddressPool(-2)) {
return false;
}
Expand Down Expand Up @@ -460,17 +486,15 @@ blsct::PrivateKey KeyMan::GetMasterSeedKey() const

blsct::PrivateKey KeyMan::GetPrivateViewKey() const
{
if (!IsHDEnabled())
throw std::runtime_error(strprintf("%s: the wallet has no HD enabled"));
if (!fViewKeyDefined)
throw std::runtime_error(strprintf("%s: the wallet has no view key available"));

auto viewId = m_hd_chain.view_id;

PrivateKey ret;

if (!GetKey(viewId, ret))
throw std::runtime_error(strprintf("%s: could not access the private view key", __func__));
return viewKey;
}

return ret;
blsct::PublicKey KeyMan::GetPublicSpendingKey() const
{
return spendPublicKey;
}

blsct::PrivateKey KeyMan::GetSpendingKey() const
Expand Down
6 changes: 4 additions & 2 deletions src/blsct/wallet/keyman.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <blsct/wallet/address.h>
#include <blsct/wallet/hdchain.h>
#include <blsct/wallet/helpers.h>
#include <blsct/wallet/import_wallet_type.h>
#include <blsct/wallet/keyring.h>
#include <logging.h>
#include <wallet/crypter.h>
Expand All @@ -34,7 +35,7 @@ class Manager
explicit Manager(wallet::WalletStorage& storage) : m_storage(storage) {}
virtual ~Manager(){};

virtual bool SetupGeneration(bool force = false) { return false; }
virtual bool SetupGeneration(const std::vector<unsigned char>& seed, const SeedType& type, bool force = false) { return false; }

/* Returns true if HD is enabled */
virtual bool IsHDEnabled() const { return false; }
Expand Down Expand Up @@ -72,7 +73,7 @@ class KeyMan : public Manager, public KeyRing
KeyMan(wallet::WalletStorage& storage, int64_t keypool_size)
: Manager(storage), KeyRing(), m_keypool_size(keypool_size) {}

bool SetupGeneration(bool force = false) override;
bool SetupGeneration(const std::vector<unsigned char>& seed, const SeedType& type = IMPORT_MASTER_KEY, bool force = false) override;
bool IsHDEnabled() const override;

/* Returns true if the wallet can generate new keys */
Expand Down Expand Up @@ -136,6 +137,7 @@ class KeyMan : public Manager, public KeyRing
CTxDestination GetDestination(const CTxOut& txout) const;
blsct::PrivateKey GetMasterSeedKey() const;
blsct::PrivateKey GetPrivateViewKey() const;
blsct::PublicKey GetPublicSpendingKey() const;
blsct::PrivateKey GetSpendingKey() const;
blsct::PrivateKey GetSpendingKeyForOutput(const CTxOut& out) const;
blsct::PrivateKey GetSpendingKeyForOutput(const CTxOut& out, const CKeyID& id) const;
Expand Down
11 changes: 7 additions & 4 deletions src/blsct/wallet/txfactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ class TxFactoryBase
{
protected:
CMutableTransaction tx;
std::map<TokenId, std::vector<UnsignedOutput>> vOutputs;
std::map<TokenId, std::vector<UnsignedInput>> vInputs;
std::map<TokenId, Amounts> nAmounts;
std::map<TokenId, std::vector<UnsignedOutput>>
vOutputs;
std::map<TokenId, std::vector<UnsignedInput>>
vInputs;
std::map<TokenId, Amounts>
nAmounts;

public:
TxFactoryBase(){};
Expand Down Expand Up @@ -58,4 +61,4 @@ class TxFactory : public TxFactoryBase
};
} // namespace blsct

#endif // TXFACTORY_H
#endif // TXFACTORY_H
21 changes: 18 additions & 3 deletions src/clientversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,26 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const
std::ostringstream ss;
ss << "/";
ss << name << ":" << FormatVersion(nClientVersion);
if (!comments.empty())
{
if (!comments.empty()) {
std::vector<std::string>::const_iterator it(comments.begin());
ss << "(" << *it;
for(++it; it != comments.end(); ++it)
for (++it; it != comments.end(); ++it)
ss << "; " << *it;
ss << ")";
}
ss << "/";
return ss.str();
}

std::string FormatSubVersion(const std::string& name, const std::string& strClientVersion, const std::vector<std::string>& comments)
{
std::ostringstream ss;
ss << "/";
ss << name << ":" << strClientVersion;
if (!comments.empty()) {
std::vector<std::string>::const_iterator it(comments.begin());
ss << "(" << *it;
for (++it; it != comments.end(); ++it)
ss << "; " << *it;
ss << ")";
}
Expand Down
1 change: 1 addition & 0 deletions src/clientversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ extern const std::string CLIENT_NAME;

std::string FormatFullVersion();
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
std::string FormatSubVersion(const std::string& name, const std::string& strClientVersion, const std::vector<std::string>& comments);

std::string CopyrightHolders(const std::string& strPrefix);

Expand Down
2 changes: 1 addition & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1324,7 +1324,7 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
return InitError(strprintf(_("User Agent comment (%s) contains unsafe characters."), cmt));
uacomments.push_back(cmt);
}
strSubVersion = FormatFullVersion();
strSubVersion = FormatSubVersion(CLIENT_NAME, FormatFullVersion(), uacomments);
if (strSubVersion.size() > MAX_SUBVERSION_LENGTH) {
return InitError(strprintf(_("Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments."),
strSubVersion.size(), MAX_SUBVERSION_LENGTH));
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define BITCOIN_INTERFACES_WALLET_H

#include <addresstype.h>
#include <blsct/wallet/import_wallet_type.h>
#include <consensus/amount.h>
#include <interfaces/chain.h>
#include <pubkey.h>
Expand Down Expand Up @@ -323,7 +324,7 @@ class WalletLoader : public ChainClient
{
public:
//! Create new wallet.
virtual util::Result<std::unique_ptr<Wallet>> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, std::vector<bilingual_str>& warnings) = 0;
virtual util::Result<std::unique_ptr<Wallet>> createWallet(const std::string& name, const SecureString& passphrase, const std::vector<unsigned char>& seed, const blsct::SeedType& type, uint64_t wallet_creation_flags, std::vector<bilingual_str>& warnings) = 0;

//! Load existing wallet.
virtual util::Result<std::unique_ptr<Wallet>> loadWallet(const std::string& name, std::vector<bilingual_str>& warnings) = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/logging.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct LogCategory {
};

namespace BCLog {
enum LogFlags : uint64_t {
enum LogFlags : uint32_t {
NONE = 0,
NET = (1 << 0),
TOR = (1 << 1),
Expand Down Expand Up @@ -71,7 +71,7 @@ enum LogFlags : uint64_t {
SCAN = (1 << 28),
TXPACKAGES = (1 << 29),
DANDELION = (1 << 30),
ALL = ~(uint64_t)0,
ALL = ~(uint32_t)0,
};
enum class Level {
Trace = 0, // High-volume or detailed logging for development/debugging
Expand Down
3 changes: 3 additions & 0 deletions src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "listtransactions", 1, "count" },
{ "listtransactions", 2, "skip" },
{ "listtransactions", 3, "include_watchonly" },
{ "listpendingtransactions", 1, "count" },
{ "listpendingtransactions", 2, "skip" },
{ "listpendingtransactions", 3, "include_watchonly" },
{ "walletpassphrase", 1, "timeout" },
{ "getblocktemplate", 0, "template_request" },
{ "listsinceblock", 1, "target_confirmations" },
Expand Down
2 changes: 1 addition & 1 deletion src/test/blsct/pos/pos_chain_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ BOOST_FIXTURE_TEST_CASE(StakedCommitment, TestBLSCTChain100Setup)

LOCK(wallet.cs_wallet);
auto blsct_km = wallet.GetOrCreateBLSCTKeyMan();
BOOST_CHECK(blsct_km->SetupGeneration(true));
BOOST_CHECK(blsct_km->SetupGeneration({}, blsct::IMPORT_MASTER_KEY, true));

auto recvAddress = std::get<blsct::DoublePublicKey>(blsct_km->GetNewDestination(0).value());

Expand Down
16 changes: 8 additions & 8 deletions src/test/blsct/wallet/txfactory_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ BOOST_FIXTURE_TEST_CASE(ismine_test, TestingSetup)

LOCK(wallet->cs_wallet);
auto blsct_km = wallet->GetOrCreateBLSCTKeyMan();
BOOST_CHECK(blsct_km->SetupGeneration(true));
BOOST_CHECK(blsct_km->SetupGeneration({}, blsct::IMPORT_MASTER_KEY, true));

auto recvAddress = std::get<blsct::DoublePublicKey>(blsct_km->GetNewDestination(0).value());

Expand Down Expand Up @@ -53,7 +53,7 @@ BOOST_FIXTURE_TEST_CASE(createtransaction_test, TestingSetup)

LOCK(wallet->cs_wallet);
auto blsct_km = wallet->GetOrCreateBLSCTKeyMan();
BOOST_CHECK(blsct_km->SetupGeneration(true));
BOOST_CHECK(blsct_km->SetupGeneration({}, blsct::IMPORT_MASTER_KEY, true));

auto recvAddress = std::get<blsct::DoublePublicKey>(blsct_km->GetNewDestination(0).value());

Expand Down Expand Up @@ -93,7 +93,7 @@ BOOST_FIXTURE_TEST_CASE(createtransaction_test, TestingSetup)
auto result = blsct_km->RecoverOutputs(finalTx.value().vout);

for (auto& res : result.amounts) {
if (res.message == "Change" && res.amount == (1000 - 900 - 0.006) * COIN) fFoundChange = true;
if (res.message == "Change" && res.amount == (1000 - 900 - 0.00304125) * COIN) fFoundChange = true;
}

BOOST_CHECK(fFoundChange);
Expand All @@ -114,7 +114,7 @@ BOOST_FIXTURE_TEST_CASE(addinput_test, TestingSetup)

LOCK(wallet->cs_wallet);
auto blsct_km = wallet->GetOrCreateBLSCTKeyMan();
BOOST_CHECK(blsct_km->SetupGeneration(true));
BOOST_CHECK(blsct_km->SetupGeneration({}, blsct::IMPORT_MASTER_KEY, true));

auto recvAddress = std::get<blsct::DoublePublicKey>(blsct_km->GetNewDestination(0).value());

Expand Down Expand Up @@ -151,7 +151,7 @@ BOOST_FIXTURE_TEST_CASE(addinput_test, TestingSetup)
auto result = blsct_km->RecoverOutputs(finalTx.value().vout);

for (auto& res : result.amounts) {
if (res.message == "Change" && res.amount == (1000 - 900 - 0.006) * COIN) fFoundChange = true;
if (res.message == "Change" && res.amount == (1000 - 900 - 0.00304125) * COIN) fFoundChange = true;
}

BOOST_CHECK(fFoundChange);
Expand All @@ -165,7 +165,7 @@ BOOST_FIXTURE_TEST_CASE(addinput_test, TestingSetup)
uint32_t nChangePosition = 0;

for (auto& res : wtx->blsctRecoveryData) {
if (res.second.message == "Change" && res.second.amount == (1000 - 900 - 0.006) * COIN) {
if (res.second.message == "Change" && res.second.amount == (1000 - 900 - 0.00304125) * COIN) {
nChangePosition = res.second.id;
fFoundChange = true;
break;
Expand All @@ -189,8 +189,8 @@ BOOST_FIXTURE_TEST_CASE(addinput_test, TestingSetup)
auto finalTx2 = tx2.BuildTx();
wallet->transactionAddedToMempool(MakeTransactionRef(finalTx2.value()));

BOOST_CHECK(wallet->GetDebit(CTransaction(finalTx2.value()), wallet::ISMINE_SPENDABLE_BLSCT) == (1000 - 900 - 0.006) * COIN);
BOOST_CHECK(TxGetCredit(*wallet, CTransaction(finalTx2.value()), wallet::ISMINE_SPENDABLE_BLSCT) == (1000 - 900 - 0.006 - 50 - 0.006) * COIN);
BOOST_CHECK(wallet->GetDebit(CTransaction(finalTx2.value()), wallet::ISMINE_SPENDABLE_BLSCT) == (1000 - 900 - 0.00304125) * COIN);
BOOST_CHECK(TxGetCredit(*wallet, CTransaction(finalTx2.value()), wallet::ISMINE_SPENDABLE_BLSCT) == (1000 - 900 - 0.00304125 - 50 - 0.00304125) * COIN);
}

BOOST_AUTO_TEST_SUITE_END()
2 changes: 1 addition & 1 deletion src/test/blsct/wallet/validation_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ BOOST_FIXTURE_TEST_CASE(validation_test, TestingSetup)

LOCK(wallet->cs_wallet);
auto blsct_km = wallet->GetOrCreateBLSCTKeyMan();
BOOST_CHECK(blsct_km->SetupGeneration(true));
BOOST_CHECK(blsct_km->SetupGeneration({}, blsct::IMPORT_MASTER_KEY, true));

auto recvAddress = std::get<blsct::DoublePublicKey>(blsct_km->GetNewDestination(0).value());

Expand Down
4 changes: 2 additions & 2 deletions src/wallet/interfaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -597,7 +597,7 @@ class WalletLoaderImpl : public WalletLoader
void schedulerMockForward(std::chrono::seconds delta) override { Assert(m_context.scheduler)->MockForward(delta); }

//! WalletLoader methods
util::Result<std::unique_ptr<Wallet>> createWallet(const std::string& name, const SecureString& passphrase, uint64_t wallet_creation_flags, std::vector<bilingual_str>& warnings) override
util::Result<std::unique_ptr<Wallet>> createWallet(const std::string& name, const SecureString& passphrase, const std::vector<unsigned char>& seed, const blsct::SeedType& type, uint64_t wallet_creation_flags, std::vector<bilingual_str>& warnings) override
{
DatabaseOptions options;
DatabaseStatus status;
Expand All @@ -606,7 +606,7 @@ class WalletLoaderImpl : public WalletLoader
options.create_flags = wallet_creation_flags;
options.create_passphrase = passphrase;
bilingual_str error;
std::unique_ptr<Wallet> wallet{MakeWallet(m_context, CreateWallet(m_context, name, /*load_on_start=*/true, options, status, error, warnings))};
std::unique_ptr<Wallet> wallet{MakeWallet(m_context, CreateWallet(m_context, name, seed, type, /*load_on_start=*/true, options, status, error, warnings))};
if (wallet) {
return wallet;
} else {
Expand Down
Loading

0 comments on commit 0f72696

Please sign in to comment.