further enhancment of locked/unlocked txs, error reporting, and others

pull/4/head
moneroexamples 7 years ago
parent 99c826abff
commit c17303a831

@ -1,6 +1,6 @@
var config = {
apiUrl: "http://127.0.0.1:1984/",
testnet: false,
testnet: true,
coinUnitPlaces: 12,
txMinConfirms: 10, // corresponds to CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE in Monero
txCoinbaseMinConfirms: 60, // corresponds to CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW in Monero
@ -12,7 +12,7 @@ var config = {
integratedAddressPrefix: 19,
addressPrefixTestnet: 53,
integratedAddressPrefixTestnet: 54,
feePerKB: new JSBigInt('2000000000'),//10^10
feePerKB: new JSBigInt('2000000000'),//20^10 - for testnet its not used, as fee is dynamic.
dustThreshold: new JSBigInt('1000000000'),//10^10 used for choosing outputs/change - we decompose all the way down if the receiver wants now regardless of threshold
txChargeRatio: 0.5,
defaultMixin: 4,

@ -187,6 +187,7 @@ thinwalletCtrls.controller('AccountCtrl', function($scope, $rootScope, $http, $q
});
$scope.transactions = transactions;
$scope.total_received = new JSBigInt(data.total_received || 0);
$scope.total_received_unlocked = new JSBigInt(data.total_received_unlocked || 0);
});
}
};
@ -199,11 +200,13 @@ thinwalletCtrls.controller('AccountCtrl', function($scope, $rootScope, $http, $q
function(scope) {
return {
sent: scope.total_sent,
received: scope.total_received
received: scope.total_received,
received_unlocked: scope.total_received_unlocked
};
},
function(data) {
$scope.balance = data.received.subtract(data.sent);
$scope.balance_unlocked = data.received_unlocked.subtract(data.sent);
},
true
);

@ -323,7 +323,14 @@ thinwalletCtrls.controller('SendCoinsCtrl', function($scope, $http, $q, AccountS
tx: raw_tx
};
$http.post(config.apiUrl + 'submit_raw_tx', request)
.success(function() {
.success(function(data) {
if (data.status === "error")
{
$scope.status = "";
$scope.submitting = false;
$scope.error = "Something unexpected occurred when submitting your transaction: " + data.error;
return;
}
console.log("Successfully submitted tx");
$scope.targets = [{}];
$scope.sent_tx = {

@ -32,7 +32,7 @@ thinwalletCtrls.controller('TransactionsCtrl', function ($scope, $rootScope, $ht
$scope.pageNum = 0;
$scope.pageSize = 10;
$scope.predicate = 'timestamp';
$scope.predicate = 'id';
$scope.reverse = true;
$scope.predicateIcon = function(expected) {

@ -13,34 +13,12 @@
<div class="w-clearfix">
<div class="balance-header">Your Balance</div>
</div>
<div class="balance-text">{{balance | money:false:true}}</div>
<div class="balance-text">{{balance | money:false:true}}<br/>
(unlocked: {{balance_unlocked | money:false:true}})</div>
</div>
</div>
</div>
</div>
<div class="generated-results">
<div class="details-block top">
<div class="result-header">YOUR&nbsp;MNEMONIC <span class="info-text">(Youll need this to login. Don't forget it!)</span>
</div>
<div class="tooltip-div">
</div>
<div class="result-text">tiny bubble double throw decay catch storm confidence aim gaze alas string</div>
</div>
<div class="details-block">
<div class="result-header">PUBLIC&nbsp;ADDRESS</div>
<div class="tooltip-div">
</div>
<div class="result-text">42kwuZYEchdfYAHNyuh1M72YbnZ1EcwMxNdxucqcCGK1Y5nkwNBGUyW9hmTGNjdfECUbouzhXJVYMjFeR3NVXdi7Tds6kBi</div>
</div>
<div class="details-block">
<div class="result-header">VIEW&nbsp;KEY</div>
<div class="tooltip-div"> </div>
<div class="result-text">9047891260162782cf955771b45b3ba8e5d240bc8ed35ced7a9cc08c12565f00</div>
</div>
<div class="login-div"><a class="button generate-btn login">Log In</a>
</div>
</div>
</div>
<div class="w-container middle-container overview-page">
<div class="middle-div">
<div class="overview-body-head">Address</div>

@ -15,7 +15,9 @@
<div class="w-clearfix">
<div class="balance-header">Your Balance</div>
</div>
<div class="balance-text">{{balance | money:false:true}}</div>
<div class="balance-text">{{balance | money:false:true}}<br/>
(unlocked: {{balance_unlocked | money:false:true}})</div>
</div>
</div>
</div>
</div>
@ -50,7 +52,7 @@
<div class="w-col w-col-2 shift-column none" ng-click="clickedPredicate('approx_float_amount')">
<div class="transaction-head transactions">Value (XMR) <i class="fa {{predicateIcon('approx_float_amount')}}"></i></div>
</div>
<div class="w-col w-col-3 shift-column" ng-click="clickedPredicate('timestamp')">
<div class="w-col w-col-3 shift-column" ng-click="clickedPredicate('id')">
<div class="transaction-head transactions">Date Received <i class="fa {{predicateIcon('timestamp')}}"></i></div>
</div>
<div class="w-col w-col-1 shift-column" ng-click="clickedPredicate('mixin')">

@ -69,7 +69,7 @@ xmreg::MySqlConnector::dbname = "openmonero";
xmreg::CurrentBlockchainStatus::set_blockchain_path(blockchain_path.string());
xmreg::CurrentBlockchainStatus::set_testnet(testnet);
xmreg::CurrentBlockchainStatus::deamon_url = deamon_url;
xmreg::CurrentBlockchainStatus::refresh_block_status_every_seconds = 30;
xmreg::CurrentBlockchainStatus::refresh_block_status_every_seconds = 10;
xmreg::CurrentBlockchainStatus::import_payment_address = address_str;
xmreg::CurrentBlockchainStatus::import_payment_viewkey = viewkey_str;
xmreg::CurrentBlockchainStatus::import_fee = static_cast<uint64_t>(0.01e12);

@ -23,14 +23,13 @@ string CurrentBlockchainStatus::deamon_url{"http:://127.0.0.1:1
bool CurrentBlockchainStatus::testnet{false};
bool CurrentBlockchainStatus::is_running{false};
std::thread CurrentBlockchainStatus::m_thread;
uint64_t CurrentBlockchainStatus::refresh_block_status_every_seconds{60};
uint64_t CurrentBlockchainStatus::refresh_block_status_every_seconds{20};
xmreg::MicroCore CurrentBlockchainStatus::mcore;
cryptonote::Blockchain *CurrentBlockchainStatus::core_storage;
vector<pair<uint64_t, transaction>> CurrentBlockchainStatus::mempool_txs;
string CurrentBlockchainStatus::import_payment_address;
string CurrentBlockchainStatus::import_payment_viewkey;
uint64_t CurrentBlockchainStatus::import_fee {10000000000}; // 0.01 xmr
uint64_t CurrentBlockchainStatus::spendable_age {10}; // default number in monero
account_public_address CurrentBlockchainStatus::address;
secret_key CurrentBlockchainStatus::viewkey;
map<string, shared_ptr<TxSearch>> CurrentBlockchainStatus::searching_threads;
@ -139,11 +138,19 @@ CurrentBlockchainStatus::init_monero_blockchain()
bool
CurrentBlockchainStatus::is_tx_unlocked(uint64_t tx_blk_height)
CurrentBlockchainStatus::is_tx_unlocked(uint64_t tx_blk_height, bool is_coinbase)
{
return (tx_blk_height + spendable_age < get_current_blockchain_height());
if (!is_coinbase)
{
return (tx_blk_height + CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE <= get_current_blockchain_height());
}
else
{
return (tx_blk_height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW <= get_current_blockchain_height());
}
}
bool
CurrentBlockchainStatus::get_block(uint64_t height, block &blk)
{
@ -751,7 +758,17 @@ CurrentBlockchainStatus::construct_output_rct_field(
output_data_t od = get_output_key(out_amount, global_amount_index);
rtc_outpk = pod_to_hex(od.commitment);
rtc_outpk = pod_to_hex(od.commitment);
if (is_coinbase(random_output_tx))
{
// i think for ringct coinbase txs, mask is identity mask
// as suggested by this code:
// https://github.com/monero-project/monero/blob/eacf2124b6822d088199179b18d4587404408e0f/src/wallet/wallet2.cpp#L893
rtc_mask = pod_to_hex(rct::identity());
}
//rtc_amount = pod_to_hex(rct::identity());
}
return make_tuple(rtc_outpk, rtc_mask, rtc_amount);

@ -53,6 +53,7 @@ struct CurrentBlockchainStatus
static string import_payment_viewkey;
static uint64_t import_fee;
static uint64_t spendable_age;
static uint64_t spendable_age_coinbase;
static account_public_address address;
static secret_key viewkey;
@ -90,7 +91,7 @@ struct CurrentBlockchainStatus
init_monero_blockchain();
static bool
is_tx_unlocked(uint64_t tx_blk_height);
is_tx_unlocked(uint64_t tx_blk_height, bool is_coinbase);
static bool
get_block(uint64_t height, block &blk);

@ -832,7 +832,7 @@ MySqlAccounts::select_txs_for_account_spendability_check(
if (bool {tx.spendable} == false)
{
if (CurrentBlockchainStatus::is_tx_unlocked(tx.height))
if (CurrentBlockchainStatus::is_tx_unlocked(tx.height, tx.coinbase))
{
// this tx was before marked as unspendable, but now

@ -134,11 +134,6 @@ TxSearch::search()
searched_blk_no, pod_to_hex(get_block_hash(blk)));
}
// flag indicating whether the txs in the given block are spendable.
// this is true when block number is more than 10 blocks from current
// blockchain height.
bool is_spendable = CurrentBlockchainStatus::is_tx_unlocked(searched_blk_no);
DateTime blk_timestamp_mysql_format
= XmrTransaction::timestamp_to_DateTime(blk.timestamp);
@ -163,6 +158,12 @@ TxSearch::search()
// and inputs in a given tx.
OutputInputIdentification oi_identification {&address, &viewkey, &tx};
// flag indicating whether the txs in the given block are spendable.
// this is true when block number is more than 10 blocks from current
// blockchain height.
bool is_spendable = CurrentBlockchainStatus::is_tx_unlocked(
searched_blk_no, oi_identification.tx_is_coinbase);
// FIRSt step.
oi_identification.identify_outputs();

@ -148,7 +148,8 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
// initialize json response
json j_response {
{ "total_received", "0"}, // taken from Accounts table
{ "total_received", "0"}, // calculated in this function
{ "total_received_unlocked", "0"}, // calculated in this function
{ "scanned_height", 0}, // not used. it is here to match mymonero
{ "scanned_block_height", 0}, // taken from Accounts table
{ "start_height", 0}, // blockchain hieght when acc was created
@ -164,7 +165,8 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
// select this account if its existing one
if (xmr_accounts->select(xmr_address, acc)) {
uint64_t total_received{0};
uint64_t total_received {0};
uint64_t total_received_unlocked {0};
j_response["total_received"] = total_received;
j_response["start_height"] = acc.start_height;
@ -221,11 +223,17 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
total_received += tx.total_received;
if (bool {tx.spendable})
{
total_received_unlocked += tx.total_received;
}
j_txs.push_back(j_tx);
} // for (XmrTransaction tx: txs)
j_response["total_received"] = total_received;
j_response["total_received"] = total_received;
j_response["total_received_unlocked"] = total_received_unlocked;
j_response["transactions"] = j_txs;
@ -244,6 +252,7 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
if(!j_mempool_tx.empty())
{
uint64_t total_received_mempool {0};
uint64_t total_sent_mempool {0};
// get last tx id (i.e., index) so that we can
// set some ids for the mempool txs. These ids are
@ -253,7 +262,7 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
if (!j_response["transactions"].empty())
{
uint64_t last_tx_id_db = j_response["transactions"].back()["id"];
last_tx_id_db = j_response["transactions"].back()["id"];
}
for (json& j_tx: j_mempool_tx)
@ -262,7 +271,9 @@ YourMoneroRequests::get_address_txs(const shared_ptr< Session > session, const B
<< j_tx["total_received"] << endl;
j_tx["id"] = ++last_tx_id_db;
total_received_mempool += j_tx["total_received"].get<uint64_t>();
total_sent_mempool += j_tx["total_sent"].get<uint64_t>();
j_response["transactions"].push_back(j_tx);
}
@ -431,19 +442,9 @@ YourMoneroRequests::get_unspent_outs(const shared_ptr< Session > session, const
int64_t time_since_unlock = current_blockchain_height - tx.unlock_time;
if (tx.coinbase)
if (!CurrentBlockchainStatus::is_tx_unlocked(tx.height, tx.coinbase))
{
if (time_since_unlock < CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW)
{
continue;
}
}
else
{
if (time_since_unlock < CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE)
{
continue;
}
continue;
}
vector<XmrOutput> outs;
@ -473,10 +474,13 @@ YourMoneroRequests::get_unspent_outs(const shared_ptr< Session > session, const
// as in Outputs table we store decoded outputs amounts
if (tx.is_rct)
{
out_amount = 0;
// out_amount = 0;
if (tx.coinbase)
{
// not really sure how to treet coinbase
// ringct unspent txs.
// // https://github.com/monero-project/monero/blob/eacf2124b6822d088199179b18d4587404408e0f/src/wallet/wallet2.cpp#L893
output_data_t od =
CurrentBlockchainStatus::get_output_key(
@ -486,7 +490,7 @@ YourMoneroRequests::get_unspent_outs(const shared_ptr< Session > session, const
string rtc_mask = pod_to_hex(rct::identity());
string rtc_amount(64, '0');
//rct = rtc_outpk + rtc_mask + rtc_amount;
rct = rtc_outpk + rtc_mask + rtc_amount;
}
}
@ -653,10 +657,12 @@ YourMoneroRequests::submit_raw_tx(const shared_ptr< Session > session, const Byt
if (!CurrentBlockchainStatus::commit_tx(raw_tx_blob, error_msg))
{
j_response["status"] = "error";
j_response["error"] = error_msg + "error message";
j_response["error"] = error_msg;
}
else
{
j_response["status"] = "success";
}
j_response["status"] = "success";
string response_body = j_response.dump();

@ -275,6 +275,11 @@ namespace xmreg
{
error_msg = res.reason;
if (error_msg.empty())
{
error_msg = "Reason not given by daemon. A guess is 'Failed to check ringct signatures!'.";
}
cerr << "Error sending tx: " << res.reason << endl;
return false;
}

Loading…
Cancel
Save