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

Add append-vec subcommand & another env knob #9490

Closed
wants to merge 8 commits into from

Conversation

ryoqun
Copy link
Member

@ryoqun ryoqun commented Apr 14, 2020

Problem

There is no handy way to display the content of AppendVec and there is no easy way to view historical old state of written accounts by solana-validator. Both are handy when debugging.

Summary of Changes

  • Add such a subcommand to ledger-tool and such a environment variable, respectively.

Needed this while investigation toward to #9423 / #9357

@ryoqun ryoqun requested review from mvines and sakridge April 14, 2020 15:57
@@ -117,6 +117,10 @@ pub struct AppendVec {

impl Drop for AppendVec {
fn drop(&mut self) {
if env::var("SOLANA_DISABLE_DEAD_APPEND_VEC_REMOVAL").is_ok() {
Copy link
Member Author

Choose a reason for hiding this comment

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

Well, granted I'm fond of envs. ;)

@sakridge I guess this is neligible for the performance-wise.

Copy link
Member

Choose a reason for hiding this comment

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

I would prefer a member variable here.

Copy link
Member

Choose a reason for hiding this comment

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

Something like new_empty_map(len: usize, cleanup: bool) {} and fn drop(self) { if self.cleanup { remove_file(x); }

Copy link
Member Author

@ryoqun ryoqun Apr 17, 2020

Choose a reason for hiding this comment

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

@sakridge @mvines

Well, that knob is needed for solana-validator not for solana-ledger-tool. So, I have to resort to an env var, otherwise, some considerable plumbing is needed or lazy_static!...

Btw, solana-ledger-tool append-vec wasn't oddly removing the specified AppendVecs. Then, I found a footgun: the exit(0) immediately after it caused the process to exit without calling Drop::drop()s altogether... So, it was working as intended by mistake.

A bit scared of the misstep, I've refactored and fixed that with tests, resulting rather bigger PR... :)

Also, I've chosen read_only (false, by default) instead of cleanup (true, by default) because I think the naming more directly conveys the behavior and I generally prefer that default behavior equates to Default::default() value for compatibility, less cognitive load, and readability.

@codecov
Copy link

codecov bot commented Apr 14, 2020

Codecov Report

Merging #9490 into master will decrease coverage by 0.1%.
The diff coverage is 53.6%.

@@           Coverage Diff            @@
##           master   #9490     +/-   ##
========================================
- Coverage    80.4%   80.2%   -0.2%     
========================================
  Files         284     284             
  Lines       66167   66272    +105     
========================================
- Hits        53220   53211      -9     
- Misses      12947   13061    +114     

println!(" - balance: {} SOL", lamports_to_sol(account.lamports));
println!(" - owner: '{}'", account.owner);
println!(" - executable: {}", account.executable);
println!(" - rent_epoch: {}", account.rent_epoch);
Copy link
Member Author

@ryoqun ryoqun Apr 17, 2020

Choose a reason for hiding this comment

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

@mvines I also started to print rent_epoch as well, remotely related my recent other work #9527

println!(" - owner: '{}'", account.owner);
println!(" - executable: {}", account.executable);
println!(" - rent_epoch: {}", account.rent_epoch);
println!(" - data: '{}'", base64::encode(&account.data));
Copy link
Member Author

@ryoqun ryoqun Apr 17, 2020

Choose a reason for hiding this comment

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

@mvines Also, I've started to encoding from base58 to base64 because I've experienced so slow encoding for large data (maybe quadric time; O(n^2))..

It seems that @nearprotocol people are also experiencing this: https://github.com/nearprotocol/nearcore/blob/master/Cargo.toml#L84 (I found this just by coincidence).

Copy link
Member

Choose a reason for hiding this comment

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

How much slower is bs58 in this case? Also do the opt-level = 3 do anything? It's going to get really confusing for the user if we mix base58 and base64, especially if there's no prefix.

How about we use the same output as solana account? That output could be factored out of solana account and put in a common function, like

pub fn println_transaction(

Copy link
Member Author

@ryoqun ryoqun Apr 28, 2020

Choose a reason for hiding this comment

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

@mvines Ok, I'll do the solana account path. :) Hopefull, I'll also add base64 to the shiny --output as well. :)

Also do the opt-level = 3 do anything?

sadly, not much... ;)

How much slower is bs58 in this case?

For the record: well, it seems that it's well-known that base58 is slow algorithmically by design. And I believe this is correct to my understanding. Its computation cost is quadratic = O(n^2).

My quick observation also aligns with these quick findings:

$ cat runtime/src/bank.rs | env time -v base58 > /dev/null
        Command being timed: "base58"
        User time (seconds): 142.34
        System time (seconds): 1.39
        Percent of CPU this job got: 100%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 2:23.73
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 20044
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 1532691
        Voluntary context switches: 3
        Involuntary context switches: 162
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0
==> 2020-04-28 16:43:20.819247997|0
$ cat runtime/src/bank.rs runtime/src/bank.rs | env time -v base58 > /dev/null
        Command being timed: "base58"
        User time (seconds): 485.85
        System time (seconds): 6.86
        Percent of CPU this job got: 100%
        Elapsed (wall clock) time (h:mm:ss or m:ss): 8:12.70
        Average shared text size (kbytes): 0
        Average unshared data size (kbytes): 0
        Average stack size (kbytes): 0
        Average total size (kbytes): 0
        Maximum resident set size (kbytes): 21920
        Average resident set size (kbytes): 0
        Major (requiring I/O) page faults: 0
        Minor (reclaiming a frame) page faults: 6581747
        Voluntary context switches: 5
        Involuntary context switches: 317
        Swaps: 0
        File system inputs: 0
        File system outputs: 0
        Socket messages sent: 0
        Socket messages received: 0
        Signals delivered: 0
        Page size (bytes): 4096
        Exit status: 0

let _ignored = remove_file(&self.path);
}
}

impl AppendVec {
#[allow(clippy::mutex_atomic)]
pub fn new(file: &Path, create: bool, size: usize) -> Self {
Copy link
Member Author

Choose a reason for hiding this comment

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

this flag name always bothered me..

})
.unwrap();

data.seek(SeekFrom::Start((size - 1) as u64)).unwrap();
Copy link
Member Author

Choose a reason for hiding this comment

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

@sakridge I'm aware this should be fs::truncate or linux's fallocate but this is separate issue... :p

}

impl Drop for AppendVec {
fn drop(&mut self) {
// the env knob is needed to make solana-validator retain retired AppendVecs for
// later inspection of the files
Copy link
Member Author

Choose a reason for hiding this comment

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

@sakridge Does this comment now make sense to justify my laziness of another env var? ;)

Copy link
Member

Choose a reason for hiding this comment

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

I'd vote for the following over an env var:

  1. Considerable plumbing
  2. A lazy_static like
    lazy_static! {
    // FROZEN_ACCOUNT_PANIC is used to signal local_cluster that an AccountsDB panic has occurred,
    // as |cargo test| cannot observe panics in other threads
    pub static ref FROZEN_ACCOUNT_PANIC: Arc<AtomicBool> = { Arc::new(AtomicBool::new(false)) };
    }

When I added (2), I declined (1) myself :)

Copy link
Member Author

Choose a reason for hiding this comment

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

hehe, thanks for the relevant info! I'll first try the (1). :)

@ryoqun ryoqun force-pushed the ledger-tool-append-vec branch from 8162931 to 7954f36 Compare April 17, 2020 07:40
@stale
Copy link

stale bot commented Apr 24, 2020

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added stale [bot only] Added to stale content; results in auto-close after a week. and removed stale [bot only] Added to stale content; results in auto-close after a week. labels Apr 24, 2020
@stale
Copy link

stale bot commented May 7, 2020

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale [bot only] Added to stale content; results in auto-close after a week. label May 7, 2020
@ryoqun ryoqun force-pushed the ledger-tool-append-vec branch from 7954f36 to e0e2020 Compare May 11, 2020 07:19
@stale stale bot removed the stale [bot only] Added to stale content; results in auto-close after a week. label May 11, 2020
Comment on lines +2688 to +2689
Arg::with_name("account_data_output")
.long("account-data-output")
Copy link
Member

Choose a reason for hiding this comment

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

What if we just called this format:

Suggested change
Arg::with_name("account_data_output")
.long("account-data-output")
Arg::with_name("format")

Copy link
Member

Choose a reason for hiding this comment

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

A .default_value("..") would be nice here too

Copy link
Member Author

Choose a reason for hiding this comment

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

@mvines Well, there already exists --output, so I wanted to avoid too similarly named argument..

) -> String {
let rpc_account = match account_data_output {
AccountDataOutputFormat::Base58 => RpcAccount::encode_with_base58(account.clone()),
AccountDataOutputFormat::Hex => RpcAccount::encode_with_base58(account.clone()),
Copy link
Member

Choose a reason for hiding this comment

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

encode_with_base58 for AccountDataOutputFormat::Hex?

Copy link
Member Author

Choose a reason for hiding this comment

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

Nice catch! the last pushed commit is still being baked... ;)

for (pubkey, account) in accounts {
let rpc_account = match account_data_output {
AccountDataOutputFormat::Base58 => RpcAccount::encode_with_base58(account.clone()),
AccountDataOutputFormat::Hex => RpcAccount::encode_with_base58(account.clone()),
Copy link
Member

Choose a reason for hiding this comment

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

encode_with_base58 for AccountDataOutputFormat::Hex? (same)

Comment on lines +839 to +840
Arg::with_name("account_data_output")
.long("account-data-output")
Copy link
Member

Choose a reason for hiding this comment

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

same as above, "format" plus a .default_value()?

Suggested change
Arg::with_name("account_data_output")
.long("account-data-output")
Arg::with_name("format")

Comment on lines +1199 to +1202
.map(|value| match value {
"base58" => AccountDataOutputFormat::Base58,
"base64" => AccountDataOutputFormat::Base64,
_ => unreachable!(),
Copy link
Member

Choose a reason for hiding this comment

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

This match is duplicated multiple times, time to promote it to clap-utils/

@stale
Copy link

stale bot commented May 20, 2020

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@stale stale bot added the stale [bot only] Added to stale content; results in auto-close after a week. label May 20, 2020
@stale
Copy link

stale bot commented May 27, 2020

This stale pull request has been automatically closed. Thank you for your contributions.

@ryoqun
Copy link
Member Author

ryoqun commented May 7, 2021

for the record, I build this pr to short-cut investigation for #17083

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale [bot only] Added to stale content; results in auto-close after a week.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants