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

Read and write xdr to file for persistent storage #24

Merged
merged 10 commits into from
Jul 8, 2022

Conversation

sisuresh
Copy link
Contributor

@sisuresh sisuresh commented Jul 8, 2022

What

Uses a file to store xdr LedgerKey-LedgerEntry pairs.

There are some TODO's in here that we should address next. I can also remove them and add issues instead.

Known limitations

This PR dumps xdr for now, but it's also possible to output JSON using Serde. I was able to get JSON working without without specifying custom serializers, but the output wasn't friendly. We would definitely benefit from spending some time specializing some of the XDR types with Serde. I have included the generic Serde output from the experiment I did, with ledger key on the first line, and the ledger entry on the second -

{"ContractData":{"contract_id":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key":{"Symbol":[97,112]}}}
{"last_modified_ledger_seq":0,"data":{"ContractData":{"contract_id":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],"key":{"Symbol":[97,112]},"val":{"Symbol":[97,112]}}},"ext":"V0"} 

Copy link
Member

@leighmcculloch leighmcculloch left a comment

Choose a reason for hiding this comment

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

Nice! One comment (❗) that I think needs addressing. I left some other comments, but defer to you on them.

src/invoke.rs Outdated
}
};

let mut lines = io::BufReader::new(file).lines();
Copy link
Member

Choose a reason for hiding this comment

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

❗ Separating the XDR blobs with new lines, then splitting on those new lines here will probably result in corrupted XDR records. If a new line byte shows up anywhere in a ledger entry it'll be split into separate lines, and then decoded only in part which will error.

You actually don't need a delimiter between the entries. XDR entries have well defined lengths since all fields are either fixed length or variable length with a length prefix. So it is safe, to write each record to file, and then to simply read each record from the file one after the other.

You can still use a BufReader if you'd like, although you don't strictly need to.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, I should have mentioned, if you put all the ledger entries in a VecM<_, _> type that is in the stellar-xdr lib, then you can read and write them in a single call, without having to iterate over them, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I just removed the newline. I didn't go the VecM route because we have both LedgerKeys and LedgerEntries in the file.

src/invoke.rs Outdated Show resolved Hide resolved
src/invoke.rs Outdated Show resolved Hide resolved
src/invoke.rs Outdated Show resolved Hide resolved
src/invoke.rs Outdated

use clap::Parser;
use stellar_contract_env_host::{
xdr::{Error as XdrError, ScVal, ScVec},
im_rc::OrdMap,
Copy link
Member

Choose a reason for hiding this comment

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

It's fine if you want to use the im_rc::OrdMap, but in the CLI it is probably unnecessary to do so. You could use the stdlib's BTreeMap which retains order and doesn't require depending on any interesting dependencies.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

storage.map, which we pass to snapshot::commit, is an OrdMap, so it's seems simpler to use that everywhere instead of also including BTreeMap. What do you think?

// LedgerEntry2
// ...

// TODO: allow option to separate input and output file
Copy link
Member

Choose a reason for hiding this comment

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

Nice idea.

src/invoke.rs Outdated
Comment on lines 118 to 125
// Initialize storage and host
// db_file format is one xdr object per line, where a LedgerKey is followed by the corresponding LedgerEntry.
//
// LedgerKey1
// LedgerEntry1
// LedgerKey2
// LedgerEntry2
// ...
Copy link
Member

Choose a reason for hiding this comment

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

Can you put this comment with the read / commit functions, since they're responsible for how that happens. You could put the functions inside a mod { ... } and put the comment there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

src/invoke.rs Outdated Show resolved Hide resolved
src/strval.rs Outdated Show resolved Hide resolved
sisuresh and others added 8 commits July 7, 2022 20:59
Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com>
Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com>
Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com>
Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com>
Co-authored-by: Leigh McCulloch <351529+leighmcculloch@users.noreply.github.com>
src/invoke.rs Outdated
Comment on lines 21 to 22
#[clap(long, parse(from_os_str))]
snapshot_file: std::path::PathBuf,
Copy link
Member

Choose a reason for hiding this comment

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

One thing left, could we set a default value for this field? Ideally it is something as a default, like ledger.xdr.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea. Done.

@leighmcculloch leighmcculloch linked an issue Jul 8, 2022 that may be closed by this pull request
@leighmcculloch leighmcculloch enabled auto-merge (squash) July 8, 2022 19:54
@leighmcculloch leighmcculloch merged commit 4cd5b2c into stellar:main Jul 8, 2022
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.

CLI: Storage to XDR file
2 participants