Skip to content

Conversation

cjjdespres
Copy link
Member

@cjjdespres cjjdespres commented Oct 9, 2025

It will be helpful for code organization purposes when generating the hard fork config to be able to copy root ledgers (via checkpointing), convert a stable-database-backed root to a converting root, and to (unsafely) view the components of a root ledger.

I've added a test of the make_converting method in particular, which converts a stable root to a converting one by migrating the stable database in chunks.

These methods were pulled out of #17816; that PR now depends on this one.

Closes: #17751

@cjjdespres cjjdespres requested a review from a team as a code owner October 9, 2025 20:03
@cjjdespres
Copy link
Member Author

!ci-bypass-changelog

Copy link
Member

@glyh glyh left a comment

Choose a reason for hiding this comment

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

LGTM, but I'm curious why can't we use multi-thread for this purpose. Is it that it's hard to design a thread safe API given the legacy code we have?

} )

let create_checkpoint_with_directory t ~directory_name =
let backing_type =
Copy link
Member

Choose a reason for hiding this comment

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

Nit: use this aux function defined in this file

  let backing_of_t = function
    | Stable_db _ ->
        Config.Stable_db
    | Converting_db _ ->
        Converting_db

[empty_hardfork_db]. The accounts are set in the target database in chunks
so the daemon is still responsive during this operation; the daemon would
otherwise stop everything as it hashed every account in the list. *)
let chunked_migration ?(chunk_size = 1 lsl 6) stable_locations_and_accounts
Copy link
Member

Choose a reason for hiding this comment

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

Why not use OCaml threads? Even if we don't have OCaml 5 level of thread support, this is still something?

https://ocaml.org/manual/4.14/api/Thread.html

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, that's also something to consider. @georgeee and I have talked about maybe introducing a ledger variant that would work more like that. I was thinking it could maintain a queue of pending set_batch operations, that would be registered whenever we wanted to commit to a new ledger state, including the initial one. Then a separate worker thread could be spawned to actually process the queue. You'd need a way of telling the worker to stop and maybe retrieving a handle to the database. The usual thread communication stuff. That kind of structure might do a better job of hiding the details of the root backing from the rest of the code.

I think we'd need code like this even then, because the worker would still be running ocaml code in the same process; it would have to avoid blocking for long periods of time.

In any case, that kind of setup might be easier to deal with elsewhere in the code. I was thinking about that in the context of #17754.

| Stable_db db ->
let directory_name =
Stable_db.get_directory db
|> Option.value_exn
Copy link
Member

Choose a reason for hiding this comment

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

Love having an error messsage

~depth:ledger_depth ~assert_synced:true ()
in
L.Root.close converting_root ;
Deferred.unit )
Copy link
Member

Choose a reason for hiding this comment

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

Might want a check to ensure there's no "long async job" happening? So to keep up with the guarantee "gradual"

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add methods to create copies of the individual databases backing a Root ledger

2 participants