-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Fix Snapshot restoration failure on Windows #9491
Conversation
Thankyou for bringing up this issue for investigation. Is anybody aware of any manual workarounds in the mean time? |
Sadly there are no manual fixes other than not using Windows or using an older Parity version :/ |
Ok thanks. I'm not too worried as for me this only affects mainnet, ropsten is syncing fine and that's all I need at the moment for solidity development purposes :). Although I may just end up dual booting my new machine. Thanks for your help, keep up the great work 👍 |
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.
lgtm modulo spelling nits
ethcore/src/blockchain/blockchain.rs
Outdated
self.blooms().close()?; | ||
self.trace_blooms().close()?; | ||
|
||
// Restore the key_value BD |
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.
s/BD/DB/
util/blooms-db/src/db.rs
Outdated
impl DatabaseFiles { | ||
/// Open the blooms db files | ||
pub fn open(path: &PathBuf) -> io::Result<DatabaseFiles> { | ||
// let path = path.as_ref(); |
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.
remove
} | ||
|
||
impl DatabaseFiles { | ||
/// Open the blooms db 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.
s/blooms db files/bloom db 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.
Well it's called blooms-db
:p
util/blooms-db/src/db.rs
Outdated
}) | ||
} | ||
|
||
pub fn flush(&mut self) -> io::Result<()> { |
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 this have to be pub
? It'd be nice if flushing was taken care of internally if&when needed.
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.
We should probably flush on drop, but also keep the explicit flushing.
util/blooms-db/src/db.rs
Outdated
self.top = File::open(self.path.join("top.bdb"))?; | ||
self.mid = File::open(self.path.join("mid.bdb"))?; | ||
self.bot = File::open(self.path.join("bot.bdb"))?; | ||
self.db_files = Some(DatabaseFiles::open(&self.path)?); | ||
Ok(()) | ||
} | ||
|
||
/// Insert consecutive blooms into database starting with positon from. |
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.
s/…starting with position from/…starting at the given position/
Ok(()) | ||
} | ||
|
||
pub fn iterator_from(&mut self, pos: Positions) -> io::Result<DatabaseFilesIterator> { |
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.
Just a curiosity: This method looks a little like the std::io::Seek
trait. Would it be possible to refactor things so that Positions
become Position
and consist of single u64
(which is then shifted properly to form the three variants needed for top, middle and bottom, kind of what happens in the insert_blooms
method) and then impl seek
for DatabaseFilesIterator
? Not sure what we'd gain, and not in scope for this bug-fix PR but interested in your thoughts! :)
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 not actually quite sure how this blooms-db
work so I'd say it's (as you said) out-of-scop for this PR, but @debris might have an opinion on this
util/blooms-db/src/db.rs
Outdated
for (index, bloom) in (from..).into_iter().zip(blooms.map(Into::into)) { | ||
let pos = Positions::from_index(index); | ||
|
||
// constant forks make lead to increased ration of false positives in bloom filters |
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.
s/constant forks make lead to increased ration of /Constant forks may lead to increased ratio of/
util/blooms-db/src/db.rs
Outdated
|
||
// constant forks make lead to increased ration of false positives in bloom filters | ||
// since we do not rebuild top or mid level, but we should not be worried about that | ||
// most of the time events at block n(a) occur also on block n(b) or n+1(b) |
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.
s/most of the times/because most of the time/
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.
LGTM. Nice find :)
util/blooms-db/src/db.rs
Outdated
}) | ||
} | ||
|
||
pub fn flush(&mut self) -> io::Result<()> { |
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.
We should probably flush on drop, but also keep the explicit flushing.
util/blooms-db/src/db.rs
Outdated
if let Some(ref mut db_files) = self.db_files { | ||
db_files.flush()?; | ||
} | ||
self.db_files = None; |
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.
If we impl Drop
for DatabaseFiles
we can avoid the explicit flush above right?
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.
Yep !
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.
Few grumbles/questions:
- Rust's
std::fs::File
design is to automatically close the file onDrop
. Would we want to remove theOption
/reopen here -- just drop the value and then recreate a new handle? - I think there may be a simpler fix for this, in https://github.com/paritytech/parity-ethereum/pull/9491/files#diff-9d32ce4d31852f1010ba2899d38f245dL75, we can just first drop all
self.top
,self.mid
,self.bot
handles beforeopen
files again. I think the issue is just that Rust tries to calldrop
afterFile::open
, but we should calldrop
before it.
util/blooms-db/src/db.rs
Outdated
/// Database path | ||
path: PathBuf, | ||
} | ||
|
||
impl Database { | ||
/// Opens blooms database. | ||
pub fn open<P>(path: P) -> io::Result<Database> where P: AsRef<Path> { | ||
let path = path.as_ref(); | ||
let path: PathBuf = path.as_ref().to_owned(); |
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.
Why is this changed to take owned value? Path
also has join
which may just be enough.
@sorpaas So the issue is that (on Windows) we need to first close the handles to the |
mid: File::open(path.join("mid.bdb"))?, | ||
bot: File::open(path.join("bot.bdb"))?, | ||
path: path.to_owned(), | ||
db_files: Some(DatabaseFiles::open(&path)?), |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
util/blooms-db/src/db.rs
Outdated
} | ||
|
||
pub fn iterator_from(&mut self, pos: Positions) -> io::Result<DatabaseFilesIterator> { | ||
Ok(DatabaseFilesIterator{ |
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.
Missing a whitespace between DatabaseFilesIterator
and {
.
Understood. Indeed we need |
* Close Blooms DB files before DB restoration * PR Grumbles I * PR Grumble * Grumble
* parity-version: bump beta to 2.0.4 * [light/jsonrpc] Provide the actual account for `eth_coinbase` RPC and unify error handeling for light and full client (#9383) * Provide the actual `account` for eth_coinbase The previous implementation always provided the `zero address` on `eth_coinbase` RPC. Now, instead the actual address is returned on success or an error when no account(s) is found! * full client `eth_coinbase` return err In the full-client return an error when no account is found instead of returning the `zero address` * Remove needless blocks on single import * Remove needless `static` lifetime on const * Fix `rpc_eth_author` test * parity: print correct keys path on startup (#9501) * aura: don't report skipped primaries when empty steps are enabled (#9435) * Only check warp syncing for eth_getWorks (#9484) * Only check warp syncing for eth_getWorks * Use SyncStatus::is_snapshot_syncing * Fix Snapshot restoration failure on Windows (#9491) * Close Blooms DB files before DB restoration * PR Grumbles I * PR Grumble * Grumble
Fixes #9106
The issue would only arise on Windows: the files used for the Blooms database were not properly closed before restoring the snapshot DB. Thus windows would fail to move the directories around.
In addition to this PR, having paritytech/parity-common#53 and debris/fs-swap#8 would be great!