-
Notifications
You must be signed in to change notification settings - Fork 4.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
Add append-vec subcommand & another env knob #9490
Conversation
runtime/src/append_vec.rs
Outdated
@@ -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() { |
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.
Well, granted I'm fond of env
s. ;)
@sakridge I guess this is neligible for the performance-wise.
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 would prefer a member variable 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.
Something like new_empty_map(len: usize, cleanup: bool) {}
and fn drop(self) { if self.cleanup { remove_file(x); }
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.
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 AppendVec
s. 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 Report
@@ 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 |
ledger-tool/src/main.rs
Outdated
println!(" - balance: {} SOL", lamports_to_sol(account.lamports)); | ||
println!(" - owner: '{}'", account.owner); | ||
println!(" - executable: {}", account.executable); | ||
println!(" - rent_epoch: {}", account.rent_epoch); |
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.
ledger-tool/src/main.rs
Outdated
println!(" - owner: '{}'", account.owner); | ||
println!(" - executable: {}", account.executable); | ||
println!(" - rent_epoch: {}", account.rent_epoch); | ||
println!(" - data: '{}'", base64::encode(&account.data)); |
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.
@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).
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.
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
Line 67 in 9bba27a
pub fn println_transaction( |
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.
@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)
.
- Pt 161616592 base64 encoding aeternity/aeternity#1733: The base58 encoding/decoding is hopelessly slow for large byte arrays.
- https://news.ycombinator.com/item?id=18408008: but is still quadratically expensive and should be used for a reasonably short, known-length data like hashes.
- https://github.com/tuupola/base58: That said, Base58 is well suited for decoding big integers but is not designed to decode long portions of binary data.
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 { |
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 flag name always bothered me..
}) | ||
.unwrap(); | ||
|
||
data.seek(SeekFrom::Start((size - 1) as u64)).unwrap(); |
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.
@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 |
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.
@sakridge Does this comment now make sense to justify my laziness of another env var? ;)
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'd vote for the following over an env var:
- Considerable plumbing
- A lazy_static like
solana/runtime/src/accounts_db.rs
Lines 61 to 65 in 40737e9
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 :)
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.
hehe, thanks for the relevant info! I'll first try the (1). :)
8162931
to
7954f36
Compare
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. |
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. |
7954f36
to
e0e2020
Compare
Arg::with_name("account_data_output") | ||
.long("account-data-output") |
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.
What if we just called this format:
Arg::with_name("account_data_output") | |
.long("account-data-output") | |
Arg::with_name("format") |
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.
A .default_value("..")
would be nice here too
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.
@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()), |
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.
encode_with_base58 for AccountDataOutputFormat::Hex?
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 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()), |
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.
encode_with_base58 for AccountDataOutputFormat::Hex? (same)
Arg::with_name("account_data_output") | ||
.long("account-data-output") |
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 as above, "format" plus a .default_value()
?
Arg::with_name("account_data_output") | |
.long("account-data-output") | |
Arg::with_name("format") |
.map(|value| match value { | ||
"base58" => AccountDataOutputFormat::Base58, | ||
"base64" => AccountDataOutputFormat::Base64, | ||
_ => unreachable!(), |
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 match is duplicated multiple times, time to promote it to clap-utils/
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. |
This stale pull request has been automatically closed. Thank you for your contributions. |
for the record, I build this pr to short-cut investigation for #17083 |
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 bysolana-validator
. Both are handy when debugging.Summary of Changes
ledger-tool
and such a environment variable, respectively.Needed this while investigation toward to #9423 / #9357