Skip to content
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 RPC: add a new method to get height from a timestamp #8088

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tevador
Copy link
Contributor

@tevador tevador commented Nov 27, 2021

This is for wallets that need to convert a user-provided date to a blockchain height.

Similar function is currently implemented in wallet2::get_blockchain_height_by_date, but it's done quite inefficiently by pulling whole block blobs from the daemon. The code is ported from there with some optimizations. The precision is increased from 2 days to 1 hour.

This RPC method will be especially useful if #6639 is implemented and the mnemonic seed encodes the wallet birthday timestamp.

@hyc
Copy link
Collaborator

hyc commented Nov 27, 2021

Is it worth replacing the wallet2 code with this RPC call then?

@@ -88,7 +88,7 @@ namespace cryptonote
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 3
#define CORE_RPC_VERSION_MINOR 8
#define CORE_RPC_VERSION_MINOR 9
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will conflict, we're already at 9 in master.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, rebased and bumped the version to 10.

@tevador
Copy link
Contributor Author

tevador commented Nov 28, 2021

Is it worth replacing the wallet2 code with this RPC call then?

Yes and I'm assuming the GUI and 3rd party wallets will use it too. Also services like MyMonero that scan on behalf of users.

This is for wallets that need to convert a user-provided
date to a blockchain height.
@selsta
Copy link
Collaborator

selsta commented Nov 29, 2021

Yes and I'm assuming the GUI and 3rd party wallets will use it too.

One thing to consider is that at least the GUI doesn't have a daemon connection yet during wallet restore. We use this code currently which is a port from wallet2: https://github.com/monero-project/monero-gui/blob/master/js/Wizard.js#L134

@tevador
Copy link
Contributor Author

tevador commented Nov 29, 2021

At some point the GUI has to connect to a daemon to start scanning outputs, so the request could be deferred until then.

I know it is possible to make a reasonably good estimate without a daemon connection (by hardcoding some timestamps and heights), but it's a much less maintainable solution. I tested get_height_by_time on stagenet and it works very well even with large gaps between blocks (for example 9 days between 268999 and 269000 etc.).

Copy link

@Agorist-Action Agorist-Action left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestions for this MR.

KV_SERIALIZE(timestamp)
END_KV_SERIALIZE_MAP()
};
typedef epee::misc_utils::struct_init<response_t> response;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer using to typedef. For example: using response = epee::misc_utils::struct_init<response_t>;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not my decision. I'm simply following the established coding practice for this header file.

CHECK_PAYMENT(req, res, COST_PER_HEIGHT_BY_TIME);

constexpr uint64_t buffer_time = 1 * 60 * 60; //1 hour
constexpr uint64_t buffer_height = 1 * 30; //1 hour

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this 30 from 60 minutes in an hour divided by a block every two minutes? In other words, what is buffer_height?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refer to lines 3638-3642. The binary search ends when the boundary block heights are closer than buffer_height. The search uses both a time-based and a height-based condition to ensure a good behavior even with irregular block times.

@@ -3570,6 +3570,93 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_height_by_time(const COMMAND_RPC_GET_HEIGHT_BY_TIME::request& req, COMMAND_RPC_GET_HEIGHT_BY_TIME::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to also follow up with a request to add this method to the online developer documentation if it gets merged. See this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this should be done if this PR ever gets merged.


auto& db = m_core.get_blockchain_storage().get_db();

for (;;)
Copy link
Contributor

@serhack serhack May 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like to be fussy or pedantic, but I'm not too sure about these endless cycles. Would be possible to implement the same functionality without the for(;;) and break? It's very tricky to manage all the hypothetical branches imho.

@woodser
Copy link
Contributor

woodser commented Jan 14, 2024

Any chance this PR can be revived and move forward?

Without this, there is currently no way for RPC clients to restore a wallet from a date, since there is no way to translate from the date to the restore height.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants