-
Notifications
You must be signed in to change notification settings - Fork 11.4k
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
Implement Interactive CLI #357
Conversation
fastpay/src/cli_commands.rs
Outdated
about = "A Byzantine fault tolerant payments chain with low-latency finality and high throughput", | ||
rename_all = "kebab-case" | ||
)] | ||
pub enum ClientCommands { |
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.
For this, I think it would be good to start from a very minimal set of commands that we all agree on the structure of + that the REST API can also support (e.g. the commands suggested here) instead of trying support everything that the old CLI did (since I think there is much that we'd like to get rid of or change).
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.
@patrickkuo I've already ported the commands from the GDC doc here in my other PR and it works with completion, etc.
You can just copy it over as we discussed and use the skeleton provided.
https://github.com/MystenLabs/fastnft/blob/ee8def7664a021639f8fb162ac5e2e5c777f5f77/fastpay/src/cli.rs#L17
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.
@sblackshear agree, all the commands will adhere to the doc when it's done
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.
@oxade are you sure completion works? I have checked out yours but its not working..... (completion is auto completing commands when you press the tab key).
I have everything wired up with working queries and transfer, now working on refactoring the genesis and account creation, also working on better UX and unit tests
792715d
to
0f40b18
Compare
Great, thanks for working avidly on this.
In this CLI, hitting ret prints a multi-line help which is not really ideal
|
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 a general statement/FYI: camino is a heck of a lot more ergonomic in argument positions than the str
soup we have to deal with (fallibly!) here (and that's valid for the whole code base, so you may want to take this with a grain of scope).
One thing I'd also love to see in future iterations of this is a nod towards #370.
fastpay/Cargo.toml
Outdated
move-core-types = { git = "https://github.com/diem/move", rev = "62b5a5075378ae6a7102bbfc1fb33b57ba6125d2", features = ["address20"] } | ||
move-bytecode-verifier = { git = "https://github.com/diem/move", rev = "62b5a5075378ae6a7102bbfc1fb33b57ba6125d2" } | ||
|
||
shellfish = { version = "0.6.0", features = ["async"] } |
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 afraid that as cargo-deny
indicates, this imports the BSL-licensed str-buf
, error-code
and clipboard-win
, which IIUC revert to a copyleft license (GPL v2) after 4y. I don't think this is something we're ok with at this stage..
/cc @sblackshear
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 am removing shellfish as we only use it as a line parser, which can be handled ourselves, however I am still using rustyline, which might contain some of these dependencies..... I will see if I can replace it...
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.
Digging into this, BSL is actually the SPDX of the Boost software license, which is what those crates are using (I did eyeball each repo's LICENSE file).
The Boost Software License is fine (it's an MIT/BSD style w/o copyright redistribution).
You can add the SPDX identifier for the Boost software license here:
https://github.com/MystenLabs/fastnft/blob/main/deny.toml#L78-L88
The SPDX is defined here: https://spdx.org/licenses/
let mut config = | ||
NetworkConfig::read_or_create(&network_conf_path).expect("Unable to read user accounts"); | ||
|
||
match options.command { |
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 going to be a bit hard to maintain the functionality in the handler, could we export the scenario run in each command to a different file, or at least a different function?
fastpay/src/fastx.rs
Outdated
impl NetworkConfig { | ||
pub fn read_or_create(path: &str) -> Result<Self, anyhow::Error> { | ||
let path_buf = PathBuf::from(path); | ||
Ok(if path_buf.exists() { |
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.
Same comment on logging with tracing.
fastpay/src/fastx.rs
Outdated
config_path: String, | ||
} | ||
|
||
impl NetworkConfig { |
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.
Could we define a common interface trait Config
which contains the common functionality and then just implement the specifics here?
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 will make one and put it in utils.rs, will be useful for rest server as well
FYI @arun-koshy
fastpay/src/wallet.rs
Outdated
} | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { |
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 works, but returning anyhow::Error
rather than a manual Box<dyn std::error::Error
should be more ergonomic.
fastpay/src/wallet_commands.rs
Outdated
println!("Owner: {:#?}", object.owner); | ||
println!("Version: {:#?}", object.version().value()); | ||
println!("ID: {:#?}", object.id()); | ||
println!("Readonly: {:#?}", object.is_read_only()); | ||
println!( | ||
"Type: {:#?}", | ||
object | ||
.data | ||
.type_() | ||
.map_or("Type Unwrap Failed".to_owned(), |type_| type_ | ||
.module | ||
.as_ident_str() | ||
.to_string()) | ||
); | ||
if deep { | ||
println!("Full Info: {:#?}", object); | ||
} |
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 there a formatting routine missing in the client, that could be reused here?
a993789
to
f556f74
Compare
This PR is code complete Although I am still working on unit test, readme.md and adding more code comments, I will mark this as ready to review before it grow too big.... Thanks @huitseeker for the early review 😂, I have addressed most of your comments and ready for round 2. |
thanks @huitseeker for figuring out BSL License is ok to include, I will revert the line processor back to rustyline as it's more stable and mature then reedline |
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.
So sorry for the license confusion I originated!
I can foresee myself debugging this after an error, and lacking some info about the setup and details of what happened.
How do I figure out the following from secondary output (e.g. logs, or at least stderr):
- what are the processes that have been launched?
- what their type is?
- what their (network) location is?
The feedback may not be for this CLI tool: you may want to punt that it's the role of the spawn of e.g. a server to make its context clear (and please open issues for anything missing there). But note tracing spans can help here:
fastpay/src/fastx.rs
Outdated
make_server(&authority, &committee, &preload_objects, config.buffer_size).await; | ||
} | ||
|
||
let wallet_config = WalletConfig::create("./wallet.conf")?; |
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.
Does re-running this make the assumption we are in a clean directory?
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.
yes, genesis assume it's writing to a clean directory, it does a check at line 109 to make sure there are no existing network configured, if there are no authorities configured but there are existing wallet config file, it will be overwritten.
pub committee_config: CommitteeConfig, | ||
} | ||
|
||
#[derive(Serialize, Deserialize)] |
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.
Nit:
I expect that outside contexts where we generate a dummy account (and want to write the generated key pair to disk as part of generation), we'll want to skip serializing the key in the future.
No need to address this as part of this PR, I'm just writing this so you don't introduce a #[derive(Serialize)]
you could avoid.
prompt_indicator: "fastx>-$ ".to_string(), | ||
}; | ||
|
||
'shell: loop { |
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.
Nice :)
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.
Oh wow, this is our own repl shell.
fastpay/src/shell.rs
Outdated
|
||
impl<P: Display, S: Send, H: AsyncHandler<S>> Shell<P, S, H> { | ||
pub async fn run_async(&mut self) -> Result<(), anyhow::Error> { | ||
let mut keybindings = default_emacs_keybindings(); |
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.
Nice :)
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.
Not emacs...
277370a
to
f86c986
Compare
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 is very cool, and a key part of the demo.
The more I look at this the more I want to build a Python library to call fastx client functions, since then we can use higher productivity libraries and tools to write tools like this in. Watching you iterate through strings (there must be a regex lib) broke my heart.
fastpay/src/fastx.rs
Outdated
|
||
#[derive(StructOpt)] | ||
#[structopt( | ||
name = "FastX", |
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 guess this is really a "fastx local" tool right? Not the main server that people should run.
.await; | ||
|
||
for object in pre_load_objects { | ||
state.init_order_lock(object.to_object_reference()).await; |
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.
Do we ever use insert_object without the lock? Maybe we should integrate the lock update inside the insert. Different PR though.
prompt_indicator: "fastx>-$ ".to_string(), | ||
}; | ||
|
||
'shell: loop { |
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.
Oh wow, this is our own repl shell.
fastpay/src/shell.rs
Outdated
}; | ||
|
||
// Runs the line | ||
match Self::unescape(line.trim()) { |
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 there not a standard regex library in Rust to make your life easier here?
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 like this as well 😞, let me check if I can do it with regex or maybe other libs.
fastpay/src/shell.rs
Outdated
let mut string = false; | ||
|
||
// Go through each char in the string | ||
for c in command.chars() { |
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.
You need regex here too to build the tokenizer
* use conf file instead of account/ committee files and arg values * removed create accounts command * added add-address command * removed benchmark from CLI commands * revert client.rs code * more refactoring * got structopt working with shellfish add sync client command added transfer command added objects command cli refactoring
* added fastx binary for genesis and start authorities
* new PortAllocator
* command completion using rustyline * new Config trait for easy loading/storing config files * address some PR comment
This reverts commit 371dce41
* allow BSL-1.0 license
address PR comments
6e41a12
to
8c4eb5c
Compare
Glad to see how far this has come. Nice! |
* chore(deps): bump bindgen from 0.59.2 to 0.60.1 Bumps [bindgen](https://github.com/rust-lang/rust-bindgen) from 0.59.2 to 0.60.1. - [Release notes](https://github.com/rust-lang/rust-bindgen/releases) - [Changelog](https://github.com/rust-lang/rust-bindgen/blob/master/CHANGELOG.md) - [Commits](rust-lang/rust-bindgen@v0.59.2...v0.60.1) --- updated-dependencies: - dependency-name: bindgen dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> * update workspace-hack hakari Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Anastasios Kichidis <[email protected]>
* chore(deps): bump bindgen from 0.59.2 to 0.60.1 Bumps [bindgen](https://github.com/rust-lang/rust-bindgen) from 0.59.2 to 0.60.1. - [Release notes](https://github.com/rust-lang/rust-bindgen/releases) - [Changelog](https://github.com/rust-lang/rust-bindgen/blob/master/CHANGELOG.md) - [Commits](rust-lang/rust-bindgen@v0.59.2...v0.60.1) --- updated-dependencies: - dependency-name: bindgen dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> * update workspace-hack hakari Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Anastasios Kichidis <[email protected]>
A CLI implementation using rustyline as line processor and structopt as the command processor.
This allow the cli client to work in both shell and no-shell mode
2 new binaries
fastx -- for starting the network and handle genesis
wallet -- for managing accounts, objects, and interact with client apis
Progress:
WIP:
Todos: