-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
daemon, wallet: new pay for RPC use system #5357
Conversation
BTW one the main things to tweak are the costs defined in src/rpc/core_rpc_commands_defs.h, the #define COST_PER_... ones. They should be roughly proportional to the amount of resources expended by the server. |
1b5b104
to
f4a4b94
Compare
Plus RPC error reporting changes, that'll probably get squashed into the main commit later. |
b03341a
to
791e54f
Compare
The client now spots when a top block changes after a RPC so it can update and mine on the new block straight away. |
44cdf8d
to
f1c1750
Compare
src/rpc/rpc_payment.cpp
Outdated
payments.insert(nonce); | ||
|
||
if (info.hashing_blob.size() < 43) | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where does this magic number 43 come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's to match:
#define VARIANT1_CHECK() \
do if (length < 43) \
{ \
fprintf(stderr, "Cryptonight variant 1 needs at least 43 bytes of data"); \
_exit(1); \
} while(0)
The nonce is at bytes 39-43. Though technically I think some of the data before it is variable size (the timestamp IIRC), though will not change size for quite a while.
src/rpc/rpc_payment.cpp
Outdated
{ | ||
try | ||
{ | ||
// first try reading in portable mode |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment looks like a leftover because I don't see any attempt to read next in non-portable mode
src/rpc/rpc_payment.cpp
Outdated
MWARNING("Failed to create data directory: " << directory); | ||
return false; | ||
} | ||
std::string state_file_path = directory + "/" + RPC_PAYMENTS_DATA_FILENAME; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it customary in the Monero codebase not to bother with boost::filesystem to concat cleanly because all OS in question understand "/" as separator (even, somewhat surprisingly, Windows)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know actually. I'll look up the docs for how that works.
#pragma once | ||
|
||
#define COST_PER_BLOCK 0.1 | ||
#define COST_PER_TX_RELAY 100 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At first sight that looks pretty expensive but I guess that there is a reasoning behind it, right? Because unlike for the other, much cheaper operations, network I/O is involved and considered "costly"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's also tx verification. All these costs are preliminary really.
@@ -121,11 +122,14 @@ namespace cryptonote | |||
uint64_t start_height; | |||
bool prune; | |||
bool no_miner_tx; | |||
std::string client; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's an awful lot of structs that now get a new client
field, and it all looks kind of un-elegant, but after brainstorming I was unable to come up with a alternative, better scheme: All that came to mind was either more complicated to implement or even threatened compatibility.
Why does COMMAND_RPC_SUBMIT_RAW_TX::request_t
lack a client
field?
I was musing that maybe it could be a good idea to add client
to all structs, just out of principle and for symmetry. You could be sure then that no call "escaped" that should be able to carry a cost, and you could even introduce schemes like a very small "base cost" for bothering the daemon at all with an RPC call, even if only get_height
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does client need to be specified in each RPC? Why don't we just associate a client at the beginning of a connection (via authentication) or after an open_wallet
request and keep that associated to the session?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SUBMIT_RAW_TX is not a RPC method. It's a mymonero RPC. It's been added there for reasons. I have a patch moving it to a mymonero specific header on github.
I suppose that now that we have SSL, we could cache the "I have checked this is an authorized client" in the connection structure and not recheck it every RPC. Sounds like something for later though.
f1c1750
to
4bf83ca
Compare
Rebased to latest master, and misc fixes from comments above. |
src/daemon/rpc_command_executor.cpp
Outdated
uint64_t balance = 0; | ||
for (const auto &entry: res.entries) | ||
{ | ||
tools::msg_writer() << entry.client << " " << entry.balance << "/" << entry.credits_total |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe a little header or help text line would be nice, to make clear the order of the info, something like client id, balance, total credits, (nonces good / stale / bad / dupe)
case CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB: return "Wrong block blob"; | ||
case CORE_RPC_ERROR_CODE_BLOCK_NOT_ACCEPTED: return "Block not accepted"; | ||
case CORE_RPC_ERROR_CODE_CORE_BUSY: return "Core is busy"; | ||
case CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB_SIZE: return "Wronmg block blob size"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Little typo "Wronmg"
src/rpc/rpc_payment.cpp
Outdated
@@ -0,0 +1,354 @@ | |||
// Copyright (c) 2018, The Monero Project |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New files probably need here 2018-2019 as years, or 2019 right away
error_message = "Payment too low"; | ||
info.credits = std::max(info.credits, PENALTY_FOR_BAD_HASH * m_credits_per_hash_found) - PENALTY_FOR_BAD_HASH * m_credits_per_hash_found; | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I miss something here, but right now I don't understand why a nonce that is not correct is reported as a payment that is too low. If that's done merely to avoid yet another extra error code, I am not sure it's a good idea: Maybe people should get reported quite clearly that they submit bad nonces.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's the same thing, isn't it ? If you send a hash below the threshold, it's bad.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With "conventional" standalone miners, there is a danger that your miner does not use the correct PoW algorithm and calculates completely wrong hashes because of this, so even if a hash has "the right number of zeroes in the right place" it's still not valid. I was worrying about that happening and people not finding the problem because the message "Payment too low" does not give a hint into the right direction.
But maybe this whole scenario is moot because we use Monero's own PoW code that will hardly ever produce completely wrong hashes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I'll change the message to give hints.
src/wallet/node_rpc_proxy.cpp
Outdated
bool r = net_utils::invoke_http_json_rpc("/json_rpc", "get_fee_estimate", req_t, resp_t, m_http_client, rpc_timeout); | ||
CHECK_AND_ASSERT_MES(r, std::string("Failed to connect to daemon"), "Failed to connect to daemon"); | ||
CHECK_AND_ASSERT_MES(resp_t.status != CORE_RPC_STATUS_BUSY, resp_t.status, "Failed to connect to daemon"); | ||
CHECK_AND_ASSERT_MES(resp_t.status == CORE_RPC_STATUS_OK, resp_t.status, "Failed to get fee estimate"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is RETURN_ON_RPC_RESPONSE_ERROR
not yet used here, but it should be used?
src/wallet/wallet_rpc_helpers.h
Outdated
|
||
namespace | ||
{ | ||
// credits to yrp (https://stackoverflow.com/questions/87372-check-if-a-class-has-a-member-function-of-a-given-signature |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Link rot: It's now https://stackoverflow.com/questions/87372/check-if-a-class-has-a-member-function-of-a-given-signature (note the "/" instead of "-" after the number) ...
I don't think I will ever understand that trick :)
} | ||
} | ||
else | ||
message_writer() << tr("Mining for payment"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe nothing wrong and I just don't understand the situation: Hashrate is 0 (or negative) but were are mining nevertheless, as per message? How so?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there's not been enough time to get an average (2 seconds).
I can do it later.
I did not think it was needed there. It would seem unlikely someone runs a RPC wallet but no daemon. If it's needed, I can do it later too. |
@@ -5114,27 +5116,23 @@ bool simple_wallet::check_daemon_rpc_prices(const std::string &daemon_url, uint3 | |||
{ | |||
try | |||
{ | |||
const auto nodes = m_wallet->get_public_nodes(false); | |||
for (const auto &node: nodes) | |||
auto i = m_claimed_cph.find(daemon_url); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't m_claimed_cph
going to be empty here if public_nodes
was not called prior to calling set_daemon
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be, yes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case, there's no check, since you have nothing to check with.
29337b9
to
8f390aa
Compare
Squashed and rebased. |
8f390aa
to
047ced8
Compare
Now ported to randomx |
047ced8
to
c6eb763
Compare
Rebased, and ported to the latest randomx changes. |
f969766
to
bdd3fb1
Compare
bdd3fb1
to
3362e6b
Compare
res.status = CORE_RPC_STATUS_OK; | ||
return true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it OK to return with the other fields in res
such as start_height
and current_height
left uninitialized?
src/wallet/wallet2.h
Outdated
@@ -869,6 +880,9 @@ namespace tools | |||
uint64_t get_last_block_reward() const { return m_last_block_reward; } | |||
uint64_t get_device_last_key_image_sync() const { return m_device_last_key_image_sync; } | |||
|
|||
struct rpc_node_data_t { epee::net_utils::network_address address; float credits_per_hash; bool white; }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've commented previously that this struct isn't used anywhere. No response?
KV_SERIALIZE(credits) | ||
KV_SERIALIZE(top_hash) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are already handled by KV_SERIALIZE_PARENT(rpc_access_response_base)
{ | ||
uint32_t out_peers; | ||
std::string status; | ||
|
||
BEGIN_KV_SERIALIZE_MAP() | ||
KV_SERIALIZE_PARENT(rpc_response_base) | ||
KV_SERIALIZE(out_peers) | ||
KV_SERIALIZE(status) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unneeded
KV_SERIALIZE_OPT(set, true) | ||
KV_SERIALIZE(in_peers) | ||
END_KV_SERIALIZE_MAP() | ||
}; | ||
typedef epee::misc_utils::struct_init<request_t> request; | ||
|
||
struct response_t | ||
struct response_t: public rpc_response_base | ||
{ | ||
uint32_t in_peers; | ||
std::string status; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unneeded
src/wallet/node_rpc_proxy.cpp
Outdated
blob = m_rpc_payment_blob; | ||
height = m_rpc_payment_height; | ||
cookie = m_rpc_payment_cookie; | ||
return boost::optional<std::string>(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As @vtnerd suggested, I also prefer boost::none
. Also, return boost::optional<std::string>("...");
can just be simply written as return "...";
which I prefer for conciseness.
uint32_t cookie; | ||
cryptonote::blobdata blob; | ||
crypto::hash seed_hash, next_seed_hash; | ||
return get_rpc_payment_info(false, payment_required, credits, diff, credits_per_hash_found, blob, height, seed_height, seed_hash, next_seed_hash, cookie) && payment_required; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_rpc_payment_info
returns true if the querying process was successful; whether the daemon requires payment or not is held in payment_required
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a && at the end.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I missed that :)
src/wallet/wallet_rpc_payments.cpp
Outdated
unsigned int n_hashes = 0; | ||
cryptonote::blobdata hashing_blob; | ||
crypto::hash seed_hash, next_seed_hash; | ||
int cn_variant; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unneeded
src/simplewallet/simplewallet.cpp
Outdated
"auto-mine-for-rpc-payment-threshold <float>\n " | ||
" Whether to automatically start mining for RPC payment if the daemon requires it.\n" | ||
"credits-target <unsigned int>\n" | ||
" The RPC payment credits balance to target.")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe mention the special value 0 being interpreted as the default 50000?
if (next_height != seed_height) | ||
next_seed_hash = m_core.get_block_id_by_height(next_height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This leaves next_seed_hash
uninitialized when next_height == seed_height
which seems problematic for later:
if (seed_hash != next_seed_hash)
res.next_seed_hash = string_tools::pod_to_hex(next_seed_hash);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICT all of them are run if the block version is >= RX_BLOCK_VERSION. I'll add a null_hash anyway though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAICT all of them are run if the block version is >= RX_BLOCK_VERSION.
I'm confused, I'm talking about when version >= RX_BLOCK_VERSION
. What I meant originally is a suggestion to change something like:
{
uint64_t next_height;
crypto::rx_seedheights(height, &seed_height, &next_height);
seed_hash = m_core.get_block_id_by_height(seed_height);
if (next_height != seed_height)
next_seed_hash = m_core.get_block_id_by_height(next_height);
+ else
+ next_seed_hash = crypto::null_hash; // or seed_hash
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I had totally missed it, thanks.
I see a slight problem in the commit message:
It should be 250 / 1000 = 0.25. |
No widget to reply to that particular comment, so:
/home/user/src/bitmonero/src/wallet/node_rpc_proxy.cpp: In member function ‘boost::optional<std::__cxx11::basic_string > tools::NodeRPCProxy::get_rpc_payment_info(bool, bool&, uint64_t&, uint64_t&, uint64_t&, cryptonote::blobdata&, uint64_t&, uint64_t&, crypto::hash&, crypto::hash&, uint32_t&)’: |
3362e6b
to
f813962
Compare
I commented without testing it myself. Obviously it'd need to be |
src/simplewallet/simplewallet.cpp
Outdated
"auto-mine-for-rpc-payment-threshold <float>\n " | ||
" Whether to automatically start mining for RPC payment if the daemon requires it.\n" | ||
"credits-target <unsigned int>\n" | ||
" The RPC payment credits balance to target (0 for default " BOOST_STRINGIZE(CREDITS_TARGET) ").")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure, but is it OK to have a macro call within tr(...)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, it'll end up within the translatable string, I'll change.
Daemons intended for public use can be set up to require payment in the form of hashes in exchange for RPC service. This enables public daemons to receive payment for their work over a large number of calls. This system behaves similarly to a pool, so payment takes the form of valid blocks every so often, yielding a large one off payment, rather than constant micropayments. This system can also be used by third parties as a "paywall" layer, where users of a service can pay for use by mining Monero to the service provider's address. An example of this for web site access is Primo, a Monero mining based website "paywall": https://github.com/selene-kovri/primo This has some advantages: - incentive to run a node providing RPC services, thereby promoting the availability of third party nodes for those who can't run their own - incentive to run your own node instead of using a third party's, thereby promoting decentralization - decentralized: payment is done between a client and server, with no third party needed - private: since the system is "pay as you go", you don't need to identify yourself to claim a long lived balance - no payment occurs on the blockchain, so there is no extra transactional load - one may mine with a beefy server, and use those credits from a phone, by reusing the client ID (at the cost of some privacy) - no barrier to entry: anyone may run a RPC node, and your expected revenue depends on how much work you do - Sybil resistant: if you run 1000 idle RPC nodes, you don't magically get more revenue - no large credit balance maintained on servers, so they have no incentive to exit scam - you can use any/many node(s), since there's little cost in switching servers - market based prices: competition between servers to lower costs - incentive for a distributed third party node system: if some public nodes are overused/slow, traffic can move to others - increases network security - helps counteract mining pools' share of the network hash rate - zero incentive for a payer to "double spend" since a reorg does not give any money back to the miner And some disadvantages: - low power clients will have difficulty mining (but one can optionally mine in advance and/or with a faster machine) - payment is "random", so a server might go a long time without a block before getting one - a public node's overall expected payment may be small Public nodes are expected to compete to find a suitable level for cost of service. The daemon can be set up this way to require payment for RPC services: monerod --rpc-payment-address 4xxxxxx \ --rpc-payment-credits 250 --rpc-payment-difficulty 1000 These values are an example only. The --rpc-payment-difficulty switch selects how hard each "share" should be, similar to a mining pool. The higher the difficulty, the fewer shares a client will find. The --rpc-payment-credits switch selects how many credits are awarded for each share a client finds. Considering both options, clients will be awarded credits/difficulty credits for every hash they calculate. For example, in the command line above, 0.25 credits per hash. A client mining at 100 H/s will therefore get an average of 25 credits per second. For reference, in the current implementation, a credit is enough to sync 20 blocks, so a 100 H/s client that's just starting to use Monero and uses this daemon will be able to sync 500 blocks per second. The wallet can be set to automatically mine if connected to a daemon which requires payment for RPC usage. It will try to keep a balance of 50000 credits, stopping mining when it's at this level, and starting again as credits are spent. With the example above, a new client will mine this much credits in about half an hour, and this target is enough to sync 500000 blocks (currently about a third of the monero blockchain). There are three new settings in the wallet: - credits-target: this is the amount of credits a wallet will try to reach before stopping mining. The default of 0 means 50000 credits. - auto-mine-for-rpc-payment-threshold: this controls the minimum credit rate which the wallet considers worth mining for. If the daemon credits less than this ratio, the wallet will consider mining to be not worth it. In the example above, the rate is 0.25 - persistent-rpc-client-id: if set, this allows the wallet to reuse a client id across runs. This means a public node can tell a wallet that's connecting is the same as one that connected previously, but allows a wallet to keep their credit balance from one run to the other. Since the wallet only mines to keep a small credit balance, this is not normally worth doing. However, someone may want to mine on a fast server, and use that credit balance on a low power device such as a phone. If left unset, a new client ID is generated at each wallet start, for privacy reasons. To mine and use a credit balance on two different devices, you can use the --rpc-client-secret-key switch. A wallet's client secret key can be found using the new rpc_payments command in the wallet. Note: anyone knowing your RPC client secret key is able to use your credit balance. The wallet has a few new commands too: - start_mining_for_rpc: start mining to acquire more credits, regardless of the auto mining settings - stop_mining_for_rpc: stop mining to acquire more credits - rpc_payments: display information about current credits with the currently selected daemon The node has an extra command: - rpc_payments: display information about clients and their balances The node will forget about any balance for clients which have been inactive for 6 months. Balances carry over on node restart.
Lists nodes exposing their RPC port for public use
f813962
to
ffa4602
Compare
Daemons intended for public use can be set up to require payment in the form of hashes in exchange for RPC service. This enables public daemons to receive payment for their work over a large number of calls. This system behaves similarly to a pool, so payment takes the form of valid blocks every so often, yielding a large one off payment, rather than constant micropayments. This system can also be used by third parties as a "paywall" layer, where users of a service can pay for use by mining Sumokoin to the service provider's address. An example of this for web site access is Primo, a Sumokoin mining based website "paywall": https://github.com/selene-kovri/primo This has some advantages: - incentive to run a node providing RPC services, thereby promoting the availability of third party nodes for those who can't run their own - incentive to run your own node instead of using a third party's, thereby promoting decentralization - decentralized: payment is done between a client and server, with no third party needed - private: since the system is "pay as you go", you don't need to identify yourself to claim a long lived balance - no payment occurs on the blockchain, so there is no extra transactional load - one may mine with a beefy server, and use those credits from a phone, by reusing the client ID (at the cost of some privacy) - no barrier to entry: anyone may run a RPC node, and your expected revenue depends on how much work you do - Sybil resistant: if you run 1000 idle RPC nodes, you don't magically get more revenue - no large credit balance maintained on servers, so they have no incentive to exit scam - you can use any/many node(s), since there's little cost in switching servers - market based prices: competition between servers to lower costs - incentive for a distributed third party node system: if some public nodes are overused/slow, traffic can move to others - increases network security - helps counteract mining pools' share of the network hash rate - zero incentive for a payer to "double spend" since a reorg does not give any money back to the miner And some disadvantages: - low power clients will have difficulty mining (but one can optionally mine in advance and/or with a faster machine) - payment is "random", so a server might go a long time without a block before getting one - a public node's overall expected payment may be small Public nodes are expected to compete to find a suitable level for cost of service. The daemon can be set up this way to require payment for RPC services: ``` sumokoind --restricted-rpc --rpc-payment-address Sumoxxxxxx \ --rpc-payment-credits 250 --rpc-payment-difficulty 1000 ``` These values are an example only. The `--rpc-payment-difficulty` switch selects how hard each "share" should be, similar to a mining pool. The higher the difficulty, the fewer shares a client will find. The `--rpc-payment-credits` switch selects how many credits are awarded for each share a client finds. Considering both options, clients will be awarded credits/difficulty credits for every hash they calculate. For example, in the command line above, 0.25 credits per hash. A client mining at 100 H/s will therefore get an average of 25 credits per second. For reference, in the current implementation, a credit is enough to sync 20 blocks, so a 100 H/s client that's just starting to use Sumokoin and uses this daemon will be able to sync 500 blocks per second. The wallet can be set to automatically mine if connected to a daemon which requires payment for RPC usage. It will try to keep a balance of 50000 credits, stopping mining when it's at this level, and starting again as credits are spent. With the example above, a new client will mine this much credits in about half an hour, and this target is enough to sync 500000 blocks. There are three new settings in the wallet: - credits-target: this is the amount of credits a wallet will try to reach before stopping mining. The default of 0 means 50000 credits. - auto-mine-for-rpc-payment-threshold: this controls the minimum credit rate which the wallet considers worth mining for. If the daemon credits less than this ratio, the wallet will consider mining to be not worth it. In the example above, the rate is 0.25 - persistent-rpc-client-id: if set, this allows the wallet to reuse a client id across runs. This means a public node can tell a wallet that's connecting is the same as one that connected previously, but allows a wallet to keep their credit balance from one run to the other. Since the wallet only mines to keep a small credit balance, this is not normally worth doing. However, someone may want to mine on a fast server, and use that credit balance on a low power device such as a phone. If left unset, a new client ID is generated at each wallet start, for privacy reasons. To mine and use a credit balance on two different devices, you can use the `--rpc-client-secret-key` switch. A wallet's client secret key can be found using the new rpc_payments command in the wallet. Note: anyone knowing your RPC client secret key is able to use your credit balance. The wallet has a few new commands too: - start_mining_for_rpc: start mining to acquire more credits, regardless of the auto mining settings - stop_mining_for_rpc: stop mining to acquire more credits - rpc_payments: display information about current credits with the currently selected daemon The node has an extra command: - rpc_payments: display information about clients and their balances The node will forget about any balance for clients which have been inactive for 6 months. Balances carry over on node restart. Ref: monero-project/monero#5357
No description provided.