Skip to content

Commit

Permalink
Merge branch 'master' of github.com:nav-io/navio-core into create_wal…
Browse files Browse the repository at this point in the history
…let_from_seed
  • Loading branch information
alex v committed Aug 9, 2024
2 parents 35df336 + a9347aa commit 3e938c7
Show file tree
Hide file tree
Showing 12 changed files with 131 additions and 56 deletions.
16 changes: 8 additions & 8 deletions contrib/guix/guix-build
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ INFO: Building ${VERSION:?not set} for platform triple ${HOST:?not set}:
...using reference timestamp: ${SOURCE_DATE_EPOCH:?not set}
...running at most ${JOBS:?not set} jobs
...from worktree directory: '${PWD}'
...bind-mounted in container to: '/bitcoin'
...bind-mounted in container to: '/navio'
...in build directory: '$(distsrc_for_host "$HOST")'
...bind-mounted in container to: '$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$HOST")'
...outputting in: '$(outdir_for_host "$HOST")'
Expand All @@ -381,24 +381,24 @@ EOF
#
# When --container is specified, the default behavior is to share
# the current working directory with the isolated container at the
# same exact path (e.g. mapping '/home/satoshi/bitcoin/' to
# '/home/satoshi/bitcoin/'). This means that the $PWD inside the
# same exact path (e.g. mapping '/home/satoshi/navio/' to
# '/home/satoshi/navio/'). This means that the $PWD inside the
# container becomes a source of irreproducibility. --no-cwd disables
# this behaviour.
#
# --share=SPEC for containers, share writable host file system
# according to SPEC
#
# --share="$PWD"=/bitcoin
# --share="$PWD"=/navio
#
# maps our current working directory to /bitcoin
# maps our current working directory to /navio
# inside the isolated container, which we later cd
# into.
#
# While we don't want to map our current working directory to the
# same exact path (as this introduces irreproducibility), we do want
# it to be at a _fixed_ path _somewhere_ inside the isolated
# container so that we have something to build. '/bitcoin' was
# container so that we have something to build. '/navio' was
# chosen arbitrarily.
#
# ${SOURCES_PATH:+--share="$SOURCES_PATH"}
Expand Down Expand Up @@ -432,7 +432,7 @@ EOF
--container \
--pure \
--no-cwd \
--share="$PWD"=/bitcoin \
--share="$PWD"=/navio \
--share="$DISTSRC_BASE"=/distsrc-base \
--share="$OUTDIR_BASE"=/outdir-base \
--expose="$(git rev-parse --git-common-dir)" \
Expand All @@ -457,7 +457,7 @@ EOF
DISTSRC="$(DISTSRC_BASE=/distsrc-base && distsrc_for_host "$HOST")" \
OUTDIR="$(OUTDIR_BASE=/outdir-base && outdir_for_host "$HOST")" \
DIST_ARCHIVE_BASE=/outdir-base/dist-archive \
bash -c "cd /bitcoin && bash contrib/guix/libexec/build.sh"
bash -c "cd /navio && bash contrib/guix/libexec/build.sh"
)

done
2 changes: 1 addition & 1 deletion contrib/guix/libexec/prelude.bash
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ time-machine() {
################

VERSION="${FORCE_VERSION:-$(git_head_version)}"
DISTNAME="${DISTNAME:-bitcoin-${VERSION}}"
DISTNAME="${DISTNAME:-navio-${VERSION}}"

version_base_prefix="${PWD}/guix-build-"
VERSION_BASE="${version_base_prefix}${VERSION}" # TOP
Expand Down
15 changes: 15 additions & 0 deletions src/blsct/wallet/keyman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,21 @@ blsct::PrivateKey KeyMan::GetMasterSeedKey() const
return ret;
}

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

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 ret;
}

blsct::PrivateKey KeyMan::GetSpendingKey() const
{
if (!fSpendKeyDefined)
Expand Down
1 change: 1 addition & 0 deletions src/blsct/wallet/keyman.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class KeyMan : public Manager, public KeyRing
CKeyID GetHashId(const blsct::PublicKey& blindingKey, const blsct::PublicKey& spendingKey) const;
CTxDestination GetDestination(const CTxOut& txout) const;
blsct::PrivateKey GetMasterSeedKey() const;
blsct::PrivateKey GetPrivateViewKey() const;
blsct::PrivateKey GetSpendingKey() const;
blsct::PrivateKey GetSpendingKeyForOutput(const CTxOut& out) const;
blsct::PrivateKey GetSpendingKeyForOutput(const CTxOut& out, const CKeyID& id) const;
Expand Down
102 changes: 59 additions & 43 deletions src/blsct/wallet/txfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,23 @@ using Scalars = Elements<Scalar>;

namespace blsct {

void TxFactoryBase::AddOutput(const SubAddress& destination, const CAmount& nAmount, std::string sMemo, const TokenId& token_id, const CreateTransactionType& type, const CAmount& minStake)
void TxFactoryBase::AddOutput(const SubAddress& destination, const CAmount& nAmount, std::string sMemo, const TokenId& token_id, const CreateTransactionType& type, const CAmount& minStake, const bool& fSubtractFeeFromAmount)
{
UnsignedOutput out;

out = CreateOutput(destination.GetKeys(), nAmount, sMemo, token_id, Scalar::Rand(), type, minStake);

CAmount nFee = 0;

if (fSubtractFeeFromAmount) {
nFee = GetTransactioOutputWeight(out.out) * BLSCT_DEFAULT_FEE;
out = CreateOutput(destination.GetKeys(), nAmount - nFee, sMemo, token_id, Scalar::Rand(), type, minStake);
};

if (nAmounts.count(token_id) == 0)
nAmounts[token_id] = {0, 0};

nAmounts[token_id].nFromOutputs += nAmount;
nAmounts[token_id].nFromOutputs += nAmount - nFee;

if (vOutputs.count(token_id) == 0)
vOutputs[token_id] = std::vector<UnsignedOutput>();
Expand All @@ -47,55 +55,77 @@ bool TxFactoryBase::AddInput(const CAmount& amount, const MclScalar& gamma, cons
std::optional<CMutableTransaction>
TxFactoryBase::BuildTx(const blsct::DoublePublicKey& changeDestination, const CAmount& minStake, const CreateTransactionType& type, const bool& fSubtractedFee)
{
CAmount nFee = BLSCT_DEFAULT_FEE * (vInputs.size() + vOutputs.size());
this->tx = CMutableTransaction();

std::vector<Signature> outputSignatures;
Scalar outputGammas;
CAmount nFee = 0;

for (auto& out_ : vOutputs) {
for (auto& out : out_.second) {
this->tx.vout.push_back(out.out);
outputGammas = outputGammas - out.gamma;
outputSignatures.push_back(PrivateKey(out.blindingKey).Sign(out.out.GetHash()));
}
}

while (true) {
CMutableTransaction tx;
CMutableTransaction tx = this->tx;
tx.nVersion |= CTransaction::BLSCT_MARKER;

Scalar gammaAcc;
Scalar gammaAcc = outputGammas;
std::map<TokenId, CAmount> mapChange;
std::vector<Signature> txSigs;

for (auto& amounts : nAmounts) {
if (amounts.second.nFromInputs < amounts.second.nFromOutputs + nFee)
return std::nullopt;
mapChange[amounts.first] = amounts.second.nFromInputs - amounts.second.nFromOutputs - nFee;
}
std::map<TokenId, CAmount> mapInputs;
std::vector<Signature> txSigs = outputSignatures;

for (auto& in_ : vInputs) {
auto tokenFee = (in_.first == TokenId() ? nFee : 0);

for (auto& in : in_.second) {
tx.vin.push_back(in.in);
gammaAcc = gammaAcc + in.gamma;
txSigs.push_back(in.sk.Sign(in.in.GetHash()));

if (!mapInputs[in_.first]) mapInputs[in_.first] = 0;

mapInputs[in_.first] += in.value.GetUint64();

if (mapInputs[in_.first] > nAmounts[in_.first].nFromOutputs + nFee) break;
}
}

for (auto& out_ : vOutputs) {
for (auto& out : out_.second) {
tx.vout.push_back(out.out);
gammaAcc = gammaAcc - out.gamma;
txSigs.push_back(PrivateKey(out.blindingKey).Sign(out.out.GetHash()));
}
for (auto& amounts : nAmounts) {
auto tokenFee = (amounts.first == TokenId() ? nFee : 0);

auto nFromInputs = mapInputs[amounts.first];

if (nFromInputs < amounts.second.nFromOutputs + tokenFee) return std::nullopt;

mapChange[amounts.first] = nFromInputs - amounts.second.nFromOutputs - tokenFee;
}

for (auto& change : mapChange) {
if (change.second == 0) continue;

auto changeOutput = CreateOutput(changeDestination, change.second, "Change", change.first, MclScalar::Rand(), type == CreateTransactionType::STAKED_COMMITMENT_UNSTAKE ? STAKED_COMMITMENT : NORMAL, minStake);
tx.vout.push_back(changeOutput.out);

gammaAcc = gammaAcc - changeOutput.gamma;

tx.vout.push_back(changeOutput.out);
txSigs.push_back(PrivateKey(changeOutput.blindingKey).Sign(changeOutput.out.GetHash()));
}

if (nFee == (long long)(BLSCT_DEFAULT_FEE * (tx.vin.size() + tx.vout.size()))) {
if (nFee == GetTransactionWeight(CTransaction(tx)) * BLSCT_DEFAULT_FEE) {
CTxOut fee_out{nFee, CScript(OP_RETURN)};

tx.vout.push_back(fee_out);
txSigs.push_back(PrivateKey(gammaAcc).SignBalance());
tx.txSig = Signature::Aggregate(txSigs);

return tx;
}

nFee = BLSCT_DEFAULT_FEE * (tx.vin.size() + tx.vout.size());
nFee = GetTransactionWeight(CTransaction(tx)) * BLSCT_DEFAULT_FEE;
}

return std::nullopt;
Expand All @@ -108,45 +138,31 @@ std::optional<CMutableTransaction> TxFactoryBase::CreateTransaction(const std::v

if (type == STAKED_COMMITMENT) {
CAmount inputFromStakedCommitments = 0;
for (const auto& output : inputCandidates) {
if (!output.is_staked_commitment)
continue;

tx.AddInput(output.amount, output.gamma, output.spendingKey, output.token_id, COutPoint(output.outpoint.hash, output.outpoint.n));

inputFromStakedCommitments += output.amount;
}
for (const auto& output : inputCandidates) {
if (output.is_staked_commitment)
continue;
inputFromStakedCommitments += output.amount;
if (!output.is_staked_commitment)
inAmount += output.amount;

tx.AddInput(output.amount, output.gamma, output.spendingKey, output.token_id, COutPoint(output.outpoint.hash, output.outpoint.n));

inAmount += output.amount;

if (tx.nAmounts[token_id].nFromInputs - inputFromStakedCommitments > nAmount + (long long)(BLSCT_DEFAULT_FEE * (tx.vInputs.size() + 2)))
break;
}

if (nAmount + inputFromStakedCommitments < minStake) {
throw std::runtime_error(strprintf("A minimum of %s is required to stake", FormatMoney(minStake)));
}

tx.AddOutput(destination, nAmount + inputFromStakedCommitments, sMemo, token_id, type, minStake);
bool fSubtractFeeFromAmount = false; // nAmount == inAmount + inputFromStakedCommitments;

tx.AddOutput(destination, nAmount + inputFromStakedCommitments, sMemo, token_id, type, minStake, fSubtractFeeFromAmount);
} else {
for (const auto& output : inputCandidates) {
tx.AddInput(output.amount, output.gamma, output.spendingKey, output.token_id, COutPoint(output.outpoint.hash, output.outpoint.n));
inAmount += output.amount;
if (tx.nAmounts[token_id].nFromInputs > nAmount + (long long)(BLSCT_DEFAULT_FEE * (tx.vInputs.size() + 2))) break;
}

CAmount subtract = 0;
bool fChangeNeeded = inAmount > nAmount;

if (type == CreateTransactionType::STAKED_COMMITMENT_UNSTAKE)
subtract = (BLSCT_DEFAULT_FEE * (tx.vInputs.size() + 1 + fChangeNeeded));
bool fSubtractFeeFromAmount = false; // type == CreateTransactionType::STAKED_COMMITMENT_UNSTAKE;

tx.AddOutput(destination, nAmount - subtract, sMemo, token_id, type, minStake);
tx.AddOutput(destination, nAmount, sMemo, token_id, type, minStake, fSubtractFeeFromAmount);
}

return tx.BuildTx(changeDestination, minStake, type);
Expand Down
2 changes: 1 addition & 1 deletion src/blsct/wallet/txfactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class TxFactoryBase
public:
TxFactoryBase(){};

void AddOutput(const SubAddress& destination, const CAmount& nAmount, std::string sMemo, const TokenId& token_id = TokenId(), const CreateTransactionType& type = NORMAL, const CAmount& minStake = 0);
void AddOutput(const SubAddress& destination, const CAmount& nAmount, std::string sMemo, const TokenId& token_id = TokenId(), const CreateTransactionType& type = NORMAL, const CAmount& minStake = 0, const bool& fSubtractFeeFromAmount = false);
bool AddInput(const CAmount& amount, const MclScalar& gamma, const blsct::PrivateKey& spendingKey, const TokenId& token_id, const COutPoint& outpoint, const bool& rbf = false);
std::optional<CMutableTransaction>
BuildTx(const blsct::DoublePublicKey& changeDestination, const CAmount& minStake = 0, const CreateTransactionType& type = NORMAL, const bool& fSubtractedFee = false);
Expand Down
10 changes: 10 additions & 0 deletions src/blsct/wallet/txfactory_global.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,4 +123,14 @@ CTransactionRef AggregateTransactions(const std::vector<CTransactionRef>& txs)

return MakeTransactionRef(ret);
}

int32_t GetTransactionWeight(const CTransaction& tx)
{
return ::GetSerializeSize(TX_WITH_WITNESS(tx));
}

int32_t GetTransactioOutputWeight(const CTxOut& out)
{
return ::GetSerializeSize(out);
}
} // namespace blsct
4 changes: 3 additions & 1 deletion src/blsct/wallet/txfactory_global.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ using Points = Elements<Point>;
using Scalar = T::Scalar;
using Scalars = Elements<Scalar>;

#define BLSCT_DEFAULT_FEE 200000
#define BLSCT_DEFAULT_FEE 50

namespace blsct {
struct UnsignedOutput {
Expand Down Expand Up @@ -68,6 +68,8 @@ enum CreateTransactionType {
CTransactionRef
AggregateTransactions(const std::vector<CTransactionRef>& txs);
UnsignedOutput CreateOutput(const blsct::DoublePublicKey& destination, const CAmount& nAmount, std::string sMemo, const TokenId& tokenId = TokenId(), const Scalar& blindingKey = Scalar::Rand(), const CreateTransactionType& type = NORMAL, const CAmount& minStake = 0);
int32_t GetTransactionWeight(const CTransaction& tx);
int32_t GetTransactioOutputWeight(const CTxOut& out);
} // namespace blsct

#endif // TXFACTORY_GLOBAL_H
1 change: 0 additions & 1 deletion src/navio-staker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
#include <memory>
#include <optional>
#include <string>
#include <tuple>

#ifndef WIN32
#include <unistd.h>
Expand Down
6 changes: 5 additions & 1 deletion src/util/rbf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@

bool SignalsOptInRBF(const CTransaction &tx)
{
for (const CTxIn &txin : tx.vin) {
// BLSCT always allows RBF
if (tx.IsBLSCT())
return true;

for (const CTxIn& txin : tx.vin) {
if (txin.nSequence <= MAX_BIP125_RBF_SEQUENCE) {
return true;
}
Expand Down
26 changes: 26 additions & 0 deletions src/wallet/rpc/backup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,32 @@ RPCHelpMan getblsctseed()
};
}


RPCHelpMan getblsctviewkey()
{
return RPCHelpMan{
"getblsctviewkey",
"\nDumps the BLSCT wallet private view key, which can be used to observe the wallet history without being able to spend the transactions.\n"
"Note: This command is only compatible with BLSCT wallets.\n",
{},
RPCResult{
RPCResult::Type::STR, "viewkey", "The BLSCT wallet private view key"},
RPCExamples{HelpExampleCli("getblsctviewkey", "") + HelpExampleRpc("getblsctseed", "")},
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue {
const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
if (!pwallet) return UniValue::VNULL;

const CWallet& wallet = *pwallet;
const blsct::KeyMan& blsct_km = EnsureConstBlsctKeyMan(wallet);

auto seed = blsct_km.GetMasterSeedKey();

return seed.GetScalar().GetString();
},
};
}


RPCHelpMan dumpwallet()
{
return RPCHelpMan{"dumpwallet",
Expand Down
2 changes: 2 additions & 0 deletions src/wallet/rpc/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -841,6 +841,7 @@ RPCHelpMan walletdisplayaddress();

// backup
RPCHelpMan getblsctseed();
RPCHelpMan getblsctviewkey();
RPCHelpMan dumpprivkey();
RPCHelpMan importprivkey();
RPCHelpMan importaddress();
Expand Down Expand Up @@ -920,6 +921,7 @@ Span<const CRPCCommand> GetWalletRPCCommands()
{"wallet", &getaddressinfo},
{"wallet", &getbalance},
{"wallet", &getblsctseed},
{"wallet", &getblsctviewkey},
{"wallet", &getnewaddress},
{"wallet", &getrawchangeaddress},
{"wallet", &getreceivedbyaddress},
Expand Down

0 comments on commit 3e938c7

Please sign in to comment.