mirror of
https://github.com/monero-project/monero.git
synced 2024-11-17 08:17:37 +00:00
Wallet::createTransaction: added mixin_count param
This commit is contained in:
parent
85a632244e
commit
2efec04f74
4 changed files with 63 additions and 11 deletions
|
@ -45,7 +45,7 @@ namespace Bitmonero {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
// copy-pasted from simplewallet
|
// copy-pasted from simplewallet
|
||||||
static const size_t DEFAULT_MIX = 4;
|
static const size_t DEFAULT_MIXIN = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Wallet2CallbackImpl : public tools::i_wallet2_callback
|
struct Wallet2CallbackImpl : public tools::i_wallet2_callback
|
||||||
|
@ -380,7 +380,7 @@ bool WalletImpl::refresh()
|
||||||
// - payment_details;
|
// - payment_details;
|
||||||
// - unconfirmed_transfer_details;
|
// - unconfirmed_transfer_details;
|
||||||
// - confirmed_transfer_details)
|
// - confirmed_transfer_details)
|
||||||
PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, uint64_t amount)
|
PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, uint64_t amount, uint32_t mixin_count)
|
||||||
{
|
{
|
||||||
clearStatus();
|
clearStatus();
|
||||||
vector<cryptonote::tx_destination_entry> dsts;
|
vector<cryptonote::tx_destination_entry> dsts;
|
||||||
|
@ -389,9 +389,10 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, uint64
|
||||||
crypto::hash8 new_payment_id;
|
crypto::hash8 new_payment_id;
|
||||||
|
|
||||||
// TODO: (https://bitcointalk.org/index.php?topic=753252.msg9985441#msg9985441)
|
// TODO: (https://bitcointalk.org/index.php?topic=753252.msg9985441#msg9985441)
|
||||||
size_t fake_outs_count = m_wallet->default_mixin();
|
|
||||||
|
size_t fake_outs_count = mixin_count > 0 ? mixin_count : m_wallet->default_mixin();
|
||||||
if (fake_outs_count == 0)
|
if (fake_outs_count == 0)
|
||||||
fake_outs_count = DEFAULT_MIX;
|
fake_outs_count = DEFAULT_MIXIN;
|
||||||
|
|
||||||
PendingTransactionImpl * transaction = new PendingTransactionImpl(this);
|
PendingTransactionImpl * transaction = new PendingTransactionImpl(this);
|
||||||
|
|
||||||
|
@ -436,27 +437,30 @@ PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, uint64
|
||||||
|
|
||||||
} catch (const tools::error::not_enough_money& e) {
|
} catch (const tools::error::not_enough_money& e) {
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
std::ostringstream writer(m_errorString);
|
std::ostringstream writer;
|
||||||
|
|
||||||
writer << boost::format(tr("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)")) %
|
writer << boost::format(tr("not enough money to transfer, available only %s, transaction amount %s = %s + %s (fee)")) %
|
||||||
print_money(e.available()) %
|
print_money(e.available()) %
|
||||||
print_money(e.tx_amount() + e.fee()) %
|
print_money(e.tx_amount() + e.fee()) %
|
||||||
print_money(e.tx_amount()) %
|
print_money(e.tx_amount()) %
|
||||||
print_money(e.fee());
|
print_money(e.fee());
|
||||||
|
m_errorString = writer.str();
|
||||||
|
|
||||||
} catch (const tools::error::not_enough_outs_to_mix& e) {
|
} catch (const tools::error::not_enough_outs_to_mix& e) {
|
||||||
std::ostringstream writer(m_errorString);
|
std::ostringstream writer;
|
||||||
writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":";
|
writer << tr("not enough outputs for specified mixin_count") << " = " << e.mixin_count() << ":";
|
||||||
for (const cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& outs_for_amount : e.scanty_outs()) {
|
for (const cryptonote::COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& outs_for_amount : e.scanty_outs()) {
|
||||||
writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.amount) << ", " << tr("found outputs to mix") << " = " << outs_for_amount.outs.size();
|
writer << "\n" << tr("output amount") << " = " << print_money(outs_for_amount.amount) << ", " << tr("found outputs to mix") << " = " << outs_for_amount.outs.size();
|
||||||
}
|
}
|
||||||
|
m_errorString = writer.str();
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
} catch (const tools::error::tx_not_constructed&) {
|
} catch (const tools::error::tx_not_constructed&) {
|
||||||
m_errorString = tr("transaction was not constructed");
|
m_errorString = tr("transaction was not constructed");
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
} catch (const tools::error::tx_rejected& e) {
|
} catch (const tools::error::tx_rejected& e) {
|
||||||
std::ostringstream writer(m_errorString);
|
std::ostringstream writer;
|
||||||
writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
|
writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status();
|
||||||
|
m_errorString = writer.str();
|
||||||
m_status = Status_Error;
|
m_status = Status_Error;
|
||||||
} catch (const tools::error::tx_sum_overflow& e) {
|
} catch (const tools::error::tx_sum_overflow& e) {
|
||||||
m_errorString = e.what();
|
m_errorString = e.what();
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
uint64_t balance() const;
|
uint64_t balance() const;
|
||||||
uint64_t unlockedBalance() const;
|
uint64_t unlockedBalance() const;
|
||||||
bool refresh();
|
bool refresh();
|
||||||
PendingTransaction * createTransaction(const std::string &dst_addr, uint64_t amount);
|
PendingTransaction * createTransaction(const std::string &dst_addr, uint64_t amount, uint32_t mixin_count);
|
||||||
virtual void disposeTransaction(PendingTransaction * t);
|
virtual void disposeTransaction(PendingTransaction * t);
|
||||||
virtual TransactionHistory * history() const;
|
virtual TransactionHistory * history() const;
|
||||||
virtual void setListener(WalletListener * l);
|
virtual void setListener(WalletListener * l);
|
||||||
|
|
|
@ -128,7 +128,6 @@ struct Wallet
|
||||||
virtual std::string seed() const = 0;
|
virtual std::string seed() const = 0;
|
||||||
virtual std::string getSeedLanguage() const = 0;
|
virtual std::string getSeedLanguage() const = 0;
|
||||||
virtual void setSeedLanguage(const std::string &arg) = 0;
|
virtual void setSeedLanguage(const std::string &arg) = 0;
|
||||||
// virtual void setListener(Listener * listener) = 0;
|
|
||||||
//! returns wallet status (Status_Ok | Status_Error)
|
//! returns wallet status (Status_Ok | Status_Error)
|
||||||
virtual int status() const = 0;
|
virtual int status() const = 0;
|
||||||
//! in case error status, returns error string
|
//! in case error status, returns error string
|
||||||
|
@ -159,13 +158,23 @@ struct Wallet
|
||||||
virtual bool trustedDaemon() const = 0;
|
virtual bool trustedDaemon() const = 0;
|
||||||
virtual uint64_t balance() const = 0;
|
virtual uint64_t balance() const = 0;
|
||||||
virtual uint64_t unlockedBalance() const = 0;
|
virtual uint64_t unlockedBalance() const = 0;
|
||||||
|
|
||||||
static std::string displayAmount(uint64_t amount);
|
static std::string displayAmount(uint64_t amount);
|
||||||
static uint64_t amountFromString(const std::string &amount);
|
static uint64_t amountFromString(const std::string &amount);
|
||||||
static uint64_t amountFromDouble(double amount);
|
static uint64_t amountFromDouble(double amount);
|
||||||
|
|
||||||
// TODO?
|
// TODO?
|
||||||
// virtual uint64_t unlockedDustBalance() const = 0;
|
// virtual uint64_t unlockedDustBalance() const = 0;
|
||||||
virtual bool refresh() = 0;
|
virtual bool refresh() = 0;
|
||||||
virtual PendingTransaction * createTransaction(const std::string &dst_addr, uint64_t amount) = 0;
|
/*!
|
||||||
|
* \brief createTransaction creates transaction
|
||||||
|
* \param dst_addr destination address as string
|
||||||
|
* \param amount amount
|
||||||
|
* \param mixin_count mixin count. if 0 passed, wallet will use default value
|
||||||
|
* \return PendingTransaction object. caller is responsible to check PendingTransaction::status()
|
||||||
|
* after object returned
|
||||||
|
*/
|
||||||
|
virtual PendingTransaction * createTransaction(const std::string &dst_addr, uint64_t amount, uint32_t mixin_count) = 0;
|
||||||
virtual void disposeTransaction(PendingTransaction * t) = 0;
|
virtual void disposeTransaction(PendingTransaction * t) = 0;
|
||||||
virtual TransactionHistory * history() const = 0;
|
virtual TransactionHistory * history() const = 0;
|
||||||
virtual void setListener(WalletListener *) = 0;
|
virtual void setListener(WalletListener *) = 0;
|
||||||
|
|
|
@ -428,6 +428,45 @@ TEST_F(WalletTest1, WalletTransaction)
|
||||||
ASSERT_TRUE(wmgr->closeWallet(wallet1));
|
ASSERT_TRUE(wmgr->closeWallet(wallet1));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
TEST_F(WalletTest1, WalletTransactionWithMixin)
|
||||||
|
{
|
||||||
|
|
||||||
|
std::vector<int> mixins;
|
||||||
|
// 2,3,4,5,6,7,8,9,10,15,20,25 can we do it like that?
|
||||||
|
mixins.push_back(2); mixins.push_back(3); mixins.push_back(4); mixins.push_back(5); mixins.push_back(6);
|
||||||
|
mixins.push_back(7); mixins.push_back(8); mixins.push_back(9); mixins.push_back(10); mixins.push_back(15);
|
||||||
|
mixins.push_back(20); mixins.push_back(25);
|
||||||
|
|
||||||
|
|
||||||
|
Bitmonero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true);
|
||||||
|
|
||||||
|
|
||||||
|
// make sure testnet daemon is running
|
||||||
|
ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0));
|
||||||
|
ASSERT_TRUE(wallet1->refresh());
|
||||||
|
uint64_t balance = wallet1->balance();
|
||||||
|
ASSERT_TRUE(wallet1->status() == Bitmonero::PendingTransaction::Status_Ok);
|
||||||
|
|
||||||
|
std::string recepient_address = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS);
|
||||||
|
for (auto mixin : mixins) {
|
||||||
|
std::cerr << "Transaction mixin count: " << mixin << std::endl;
|
||||||
|
Bitmonero::PendingTransaction * transaction = wallet1->createTransaction(
|
||||||
|
recepient_address, AMOUNT_5XMR, mixin);
|
||||||
|
|
||||||
|
std::cerr << "Transaction status: " << transaction->status() << std::endl;
|
||||||
|
std::cerr << "Transaction fee: " << Bitmonero::Wallet::displayAmount(transaction->fee()) << std::endl;
|
||||||
|
std::cerr << "Transaction error: " << transaction->errorString() << std::endl;
|
||||||
|
ASSERT_TRUE(transaction->status() == Bitmonero::PendingTransaction::Status_Ok);
|
||||||
|
wallet1->disposeTransaction(transaction);
|
||||||
|
}
|
||||||
|
|
||||||
|
wallet1->refresh();
|
||||||
|
|
||||||
|
ASSERT_TRUE(wallet1->balance() == balance);
|
||||||
|
ASSERT_TRUE(wmgr->closeWallet(wallet1));
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(WalletTest1, WalletHistory)
|
TEST_F(WalletTest1, WalletHistory)
|
||||||
{
|
{
|
||||||
Bitmonero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true);
|
Bitmonero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, true);
|
||||||
|
@ -465,7 +504,7 @@ TEST_F(WalletTest1, WalletTransactionAndHistory)
|
||||||
|
|
||||||
std::string wallet4_addr = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS);
|
std::string wallet4_addr = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS);
|
||||||
|
|
||||||
Bitmonero::PendingTransaction * tx = wallet_src->createTransaction(wallet4_addr, AMOUNT_10XMR * 5);
|
Bitmonero::PendingTransaction * tx = wallet_src->createTransaction(wallet4_addr, AMOUNT_10XMR * 5, 0);
|
||||||
ASSERT_TRUE(tx->status() == Bitmonero::PendingTransaction::Status_Ok);
|
ASSERT_TRUE(tx->status() == Bitmonero::PendingTransaction::Status_Ok);
|
||||||
ASSERT_TRUE(tx->commit());
|
ASSERT_TRUE(tx->commit());
|
||||||
history = wallet_src->history();
|
history = wallet_src->history();
|
||||||
|
|
Loading…
Reference in a new issue