Electroneum
Toggle main menu visibility
Loading...
Searching...
No Matches
pending_transaction.cpp
Go to the documentation of this file.
1
// Copyrights(c) 2017-2021, The Electroneum Project
2
// Copyrights(c) 2014-2019, The Monero Project
3
//
4
// All rights reserved.
5
//
6
// Redistribution and use in source and binary forms, with or without modification, are
7
// permitted provided that the following conditions are met:
8
//
9
// 1. Redistributions of source code must retain the above copyright notice, this list of
10
// conditions and the following disclaimer.
11
//
12
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13
// of conditions and the following disclaimer in the documentation and/or other
14
// materials provided with the distribution.
15
//
16
// 3. Neither the name of the copyright holder nor the names of its contributors may be
17
// used to endorse or promote products derived from this software without specific
18
// prior written permission.
19
//
20
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
//
30
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
31
32
#include "
pending_transaction.h
"
33
#include "
wallet.h
"
34
#include "
common_defines.h
"
35
36
#include "
cryptonote_basic/cryptonote_format_utils.h
"
37
#include "
cryptonote_basic/cryptonote_basic_impl.h
"
38
#include "
common/base58.h
"
39
40
#include <memory>
41
#include <vector>
42
#include <sstream>
43
#include <boost/format.hpp>
44
45
using namespace
std
;
46
47
namespace
Electroneum
{
48
49
PendingTransaction::~PendingTransaction
() {}
50
51
52
PendingTransactionImpl::PendingTransactionImpl
(
WalletImpl
&wallet)
53
: m_wallet(wallet)
54
{
55
m_status =
Status_Ok
;
56
}
57
58
PendingTransactionImpl::~PendingTransactionImpl
()
59
{
60
61
}
62
63
int
PendingTransactionImpl::status
()
const
64
{
65
return
m_status;
66
}
67
68
string
PendingTransactionImpl::errorString
()
const
69
{
70
return
m_errorString;
71
}
72
73
std::vector<std::string>
PendingTransactionImpl::txid
()
const
74
{
75
std::vector<std::string>
txid
;
76
for
(
const
auto
&pt: m_pending_tx)
77
txid
.push_back(
epee::string_tools::pod_to_hex
(
cryptonote::get_transaction_hash
(pt.tx)));
78
return
txid
;
79
}
80
81
bool
PendingTransactionImpl::commit
(
const
std::string &filename,
bool
overwrite)
82
{
83
84
LOG_PRINT_L3
(
"m_pending_tx size: "
<< m_pending_tx.size());
85
86
try
{
87
// Save tx to file
88
if
(!filename.empty()) {
89
boost::system::error_code ignore;
90
bool
tx_file_exists = boost::filesystem::exists(filename, ignore);
91
if
(tx_file_exists && !overwrite){
92
m_errorString = string(
tr
(
"Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:"
)) + filename;
93
m_status =
Status_Error
;
94
LOG_ERROR
(m_errorString);
95
return
false
;
96
}
97
bool
r = m_wallet.m_wallet->save_tx(m_pending_tx, filename);
98
if
(!r) {
99
m_errorString =
tr
(
"Failed to write transaction(s) to file"
);
100
m_status =
Status_Error
;
101
}
else
{
102
m_status =
Status_Ok
;
103
}
104
}
105
// Commit tx
106
else
{
107
auto
multisigState = m_wallet.multisig();
108
if
(multisigState.isMultisig && m_signers.size() < multisigState.threshold) {
109
throw
runtime_error(
"Not enough signers to send multisig transaction"
);
110
}
111
112
m_wallet.pauseRefresh();
113
114
const
bool
tx_cold_signed = m_wallet.m_wallet->get_account().get_device().has_tx_cold_sign();
115
if
(tx_cold_signed){
116
std::unordered_set<size_t> selected_transfers;
117
for
(
const
tools::wallet2::pending_tx
& ptx : m_pending_tx){
118
for
(
size_t
s : ptx.selected_transfers){
119
selected_transfers.insert(s);
120
}
121
}
122
123
m_wallet.m_wallet->cold_tx_aux_import(m_pending_tx, m_tx_device_aux);
124
bool
r = m_wallet.m_wallet->import_key_images(m_key_images, 0, selected_transfers);
125
if
(!r){
126
throw
runtime_error(
"Cold sign transaction submit failed - key image sync fail"
);
127
}
128
}
129
130
while
(!m_pending_tx.empty()) {
131
auto
& ptx = m_pending_tx.back();
132
m_wallet.m_wallet->commit_tx(ptx);
133
// if no exception, remove element from vector
134
m_pending_tx.pop_back();
135
}
// TODO: extract method;
136
}
137
}
catch
(
const
tools::error::daemon_busy
&) {
138
// TODO: make it translatable with "tr"?
139
m_errorString =
tr
(
"daemon is busy. Please try again later."
);
140
m_status =
Status_Error
;
141
}
catch
(
const
tools::error::no_connection_to_daemon
&) {
142
m_errorString =
tr
(
"no connection to daemon. Please make sure daemon is running."
);
143
m_status =
Status_Error
;
144
}
catch
(
const
tools::error::tx_rejected
& e) {
145
std::ostringstream writer(m_errorString);
146
writer << (boost::format(
tr
(
"transaction %s was rejected by daemon with status: "
)) % get_transaction_hash(e.
tx
())) << e.
status
();
147
std::string reason = e.
reason
();
148
m_status =
Status_Error
;
149
m_errorString = writer.str();
150
if
(!reason.empty())
151
m_errorString += string(
tr
(
". Reason: "
)) + reason;
152
}
catch
(
const
std::exception &e) {
153
m_errorString = string(
tr
(
"Unknown exception: "
)) + e.what();
154
m_status =
Status_Error
;
155
}
catch
(...) {
156
m_errorString =
tr
(
"Unhandled exception"
);
157
LOG_ERROR
(m_errorString);
158
m_status =
Status_Error
;
159
}
160
161
m_wallet.startRefresh();
162
return
m_status ==
Status_Ok
;
163
}
164
165
uint64_t
PendingTransactionImpl::amount
()
const
166
{
167
uint64_t
result = 0;
168
for
(
const
auto
&ptx : m_pending_tx) {
169
for
(
const
auto
&
dest
: ptx.dests) {
170
result +=
dest
.amount;
171
}
172
}
173
return
result;
174
}
175
176
uint64_t
PendingTransactionImpl::dust
()
const
177
{
178
uint64_t
result = 0;
179
for
(
const
auto
& ptx : m_pending_tx) {
180
result += ptx.dust;
181
}
182
return
result;
183
}
184
185
uint64_t
PendingTransactionImpl::fee
()
const
186
{
187
uint64_t
result = 0;
188
for
(
const
auto
&ptx : m_pending_tx) {
189
result += ptx.fee;
190
}
191
return
result;
192
}
193
194
uint64_t
PendingTransactionImpl::txCount
()
const
195
{
196
return
m_pending_tx.size();
197
}
198
199
std::vector<uint32_t>
PendingTransactionImpl::subaddrAccount
()
const
200
{
201
std::vector<uint32_t> result;
202
for
(
const
auto
& ptx : m_pending_tx)
203
result.push_back(ptx.construction_data.subaddr_account);
204
return
result;
205
}
206
207
std::vector<std::set<uint32_t>>
PendingTransactionImpl::subaddrIndices
()
const
208
{
209
std::vector<std::set<uint32_t>> result;
210
for
(
const
auto
& ptx : m_pending_tx)
211
result.push_back(ptx.construction_data.subaddr_indices);
212
return
result;
213
}
214
215
std::string
PendingTransactionImpl::multisigSignData
() {
216
try
{
217
if
(!m_wallet.multisig().isMultisig) {
218
throw
std::runtime_error(
"wallet is not multisig"
);
219
}
220
221
tools::wallet2::multisig_tx_set
txSet;
222
txSet.
m_ptx
= m_pending_tx;
223
txSet.
m_signers
= m_signers;
224
auto
cipher = m_wallet.m_wallet->save_multisig_tx(txSet);
225
226
return
epee::string_tools::buff_to_hex_nodelimer
(cipher);
227
}
catch
(
const
std::exception& e) {
228
m_status =
Status_Error
;
229
m_errorString = std::string(
tr
(
"Couldn't multisig sign data: "
)) + e.what();
230
}
231
232
return
std::string();
233
}
234
235
void
PendingTransactionImpl::signMultisigTx
() {
236
try
{
237
std::vector<crypto::hash> ignore;
238
239
tools::wallet2::multisig_tx_set
txSet;
240
txSet.
m_ptx
= m_pending_tx;
241
txSet.
m_signers
= m_signers;
242
243
if
(!m_wallet.m_wallet->sign_multisig_tx(txSet, ignore)) {
244
throw
std::runtime_error(
"couldn't sign multisig transaction"
);
245
}
246
247
std::swap(m_pending_tx, txSet.
m_ptx
);
248
std::swap(m_signers, txSet.
m_signers
);
249
}
catch
(
const
std::exception& e) {
250
m_status =
Status_Error
;
251
m_errorString = std::string(
tr
(
"Couldn't sign multisig transaction: "
)) + e.what();
252
}
253
}
254
255
std::vector<std::string>
PendingTransactionImpl::signersKeys
()
const
{
256
std::vector<std::string> keys;
257
keys.reserve(m_signers.size());
258
259
for
(
const
auto
& signer: m_signers) {
260
keys.emplace_back(
tools::base58::encode
(
cryptonote::t_serializable_object_to_blob
(signer)));
261
}
262
263
return
keys;
264
}
265
266
}
267
268
namespace
Bitelectroneum
=
Electroneum
;
269
base58.h
Electroneum::PendingTransactionImpl::errorString
std::string errorString() const override
Definition
pending_transaction.cpp:68
Electroneum::PendingTransactionImpl::multisigSignData
std::string multisigSignData() override
multisigSignData
Definition
pending_transaction.cpp:215
Electroneum::PendingTransactionImpl::WalletImpl
friend class WalletImpl
Definition
pending_transaction.h:64
Electroneum::PendingTransactionImpl::~PendingTransactionImpl
~PendingTransactionImpl()
Definition
pending_transaction.cpp:58
Electroneum::PendingTransactionImpl::signersKeys
std::vector< std::string > signersKeys() const override
signersKeys
Definition
pending_transaction.cpp:255
Electroneum::PendingTransactionImpl::signMultisigTx
void signMultisigTx() override
Definition
pending_transaction.cpp:235
Electroneum::PendingTransactionImpl::amount
uint64_t amount() const override
Definition
pending_transaction.cpp:165
Electroneum::PendingTransactionImpl::status
int status() const override
Definition
pending_transaction.cpp:63
Electroneum::PendingTransactionImpl::txCount
uint64_t txCount() const override
txCount - number of transactions current transaction will be splitted to
Definition
pending_transaction.cpp:194
Electroneum::PendingTransactionImpl::fee
uint64_t fee() const override
Definition
pending_transaction.cpp:185
Electroneum::PendingTransactionImpl::subaddrIndices
std::vector< std::set< uint32_t > > subaddrIndices() const override
Definition
pending_transaction.cpp:207
Electroneum::PendingTransactionImpl::dust
uint64_t dust() const override
Definition
pending_transaction.cpp:176
Electroneum::PendingTransactionImpl::txid
std::vector< std::string > txid() const override
Definition
pending_transaction.cpp:73
Electroneum::PendingTransactionImpl::commit
bool commit(const std::string &filename="", bool overwrite=false) override
Definition
pending_transaction.cpp:81
Electroneum::PendingTransactionImpl::subaddrAccount
std::vector< uint32_t > subaddrAccount() const override
Definition
pending_transaction.cpp:199
Electroneum::PendingTransactionImpl::PendingTransactionImpl
PendingTransactionImpl(WalletImpl &wallet)
Definition
pending_transaction.cpp:52
common_defines.h
tr
#define tr(x)
Definition
common_defines.h:4
cryptonote_basic_impl.h
cryptonote_format_utils.h
LOG_PRINT_L3
#define LOG_PRINT_L3(x)
Definition
misc_log_ex.h:102
LOG_ERROR
#define LOG_ERROR(x)
Definition
misc_log_ex.h:98
Electroneum
Definition
address_book.cpp:41
cryptonote::get_transaction_hash
crypto::hash get_transaction_hash(const transaction &t)
Definition
cryptonote_format_utils.cpp:1012
cryptonote::t_serializable_object_to_blob
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
Definition
cryptonote_format_utils.h:160
epee::string_tools::pod_to_hex
std::string pod_to_hex(const t_pod_type &s)
Definition
string_tools.h:317
epee::string_tools::buff_to_hex_nodelimer
std::string buff_to_hex_nodelimer(const std::string &src)
Definition
string_tools.h:87
std
STL namespace.
tools::base58::encode
std::string encode(const std::string &data)
Definition
base58.cpp:173
pending_transaction.h
dest
CXA_THROW_INFO_T void(* dest)(void *))
Definition
stack_trace.cpp:91
uint64_t
unsigned __int64 uint64_t
Definition
stdint.h:136
Electroneum::PendingTransaction::Status_Error
@ Status_Error
Definition
wallet2_api.h:76
Electroneum::PendingTransaction::Status_Ok
@ Status_Ok
Definition
wallet2_api.h:75
Electroneum::PendingTransaction::~PendingTransaction
virtual ~PendingTransaction()=0
Definition
pending_transaction.cpp:49
tools::error::daemon_busy
Definition
wallet_errors.h:810
tools::error::no_connection_to_daemon
Definition
wallet_errors.h:818
tools::error::tx_rejected
Definition
wallet_errors.h:653
tools::error::tx_rejected::tx
const cryptonote::transaction & tx() const
Definition
wallet_errors.h:662
tools::error::tx_rejected::reason
const std::string & reason() const
Definition
wallet_errors.h:664
tools::error::tx_rejected::status
const std::string & status() const
Definition
wallet_errors.h:663
tools::wallet2::multisig_tx_set
Definition
wallet2.h:511
tools::wallet2::multisig_tx_set::m_signers
std::unordered_set< crypto::public_key > m_signers
Definition
wallet2.h:513
tools::wallet2::multisig_tx_set::m_ptx
std::vector< pending_tx > m_ptx
Definition
wallet2.h:512
tools::wallet2::pending_tx
Definition
wallet2.h:465
wallet.h
src
wallet
api
pending_transaction.cpp
Generated on
for Electroneum by
1.17.0