Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Fix block detail updating #11015

Merged

Conversation

AtkinsChang
Copy link
Contributor

In ethcore client, update of block detail occurs in two locations: BlockChain::mark_finalized and BlockChain::insert_block
https://github.com/paritytech/parity-ethereum/blob/a9cb5722383cb89ebf38ba4ea2fa2073f15d5f8b/ethcore/src/client/client.rs#L527
https://github.com/paritytech/parity-ethereum/blob/a9cb5722383cb89ebf38ba4ea2fa2073f15d5f8b/ethcore/src/client/client.rs#L536-L539
But in BlockChain::prepare_block_details_update (called by insert_block), parent block detail is read from cache/db, this may cause previous modification of BlockChain::mark_finalized be overwritten.
https://github.com/paritytech/parity-ethereum/blob/a9cb5722383cb89ebf38ba4ea2fa2073f15d5f8b/ethcore/blockchain/src/blockchain.rs#L1345-L1348

testcase is added to reproduce this situation

@parity-cla-bot
Copy link

It looks like @AtkinsChang signed our Contributor License Agreement. 👍

Many thanks,

Parity Technologies CLA Bot

@jam10o-new jam10o-new added A0-pleasereview 🤓 Pull request needs code review. B0-patch-stable 🕷 Pull request should also be back-ported to the stable branch. B1-patch-beta 🕷🕷 M4-core ⛓ Core client code / Rust. labels Sep 2, 2019
Copy link
Collaborator

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

I don't think I fully understand the issue.
mark_finalized does update the cache anyway, so prepare_block_details_update should actually read the updated version already.

I'm also not super in favor of the solution, where we special-case the parent block, if that's really an issue isn't there a way to make sure we don't need to do that and rather have the cache in consistent state no matter what order the methods are called in?

@@ -536,6 +540,7 @@ impl Importer {
let route = chain.insert_block(&mut batch, block_data, receipts.clone(), ExtrasInsert {
fork_choice,
is_finalized,
is_parent_finalized,
Copy link
Collaborator

Choose a reason for hiding this comment

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

please fix the indentation

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed in force-pushed commit

@AtkinsChang
Copy link
Contributor Author

mark_finalized updates the pending_block_details
prepare_block_details_update reads from block_details so the previous is_finalized update is overwritten
try the testcase in second commit 784e159

Handling parent is the special case that it reads data updated previously in the same transaction so I use this.

I can change to another solution like add a 2-layered cache read and replace
https://github.com/paritytech/parity-ethereum/blob/a9cb5722383cb89ebf38ba4ea2fa2073f15d5f8b/ethcore/blockchain/src/blockchain.rs#L1347
with

let mut parent_details = self.db.key_value().read_with_two_layer_cache(db::COL_EXTRA, &self.pending_block_details, &self.block_details, hash)

if you prefer this

@tomusdrw
Copy link
Collaborator

tomusdrw commented Sep 2, 2019

mark_finalized updates the pending_block_details
prepare_block_details_update reads from block_details so the previous is_finalized update is overwritten

I see now, thanks for explanations.

The Blockchain API indeed seems very fragile, I feel we can run into more issues if we commit multiple block at once in a single batch (see insert_block) - all the updates to block_details will only end up in pending_block_details cache, not block_details cache, so we will just keep overwriting the same stuff.

Imagine we are importing a A -> B and A -> B' in single batch, we should end up with two children entries in A, but we will only have one.

I think I'm more inclined to the double cache approach, and go through all methods that work on a batch to make sure we are always taking pending_blocks_details cache into account whenever we are preparing the ExtrasUpdate.
In prinicple there is another issue, where you have two concurrent batches present - the blockchain API doesn't really prevent that, but I think we never do that in practice (so I don't think we need to address it here).

Do you also feel the issues I've raised above are valid?

@AtkinsChang
Copy link
Contributor Author

AtkinsChang commented Sep 2, 2019

Yup, it may cause data inconsistency for two concurrent batch. We should make it more like transaction in RMDB to provide hardened Blockchain API

And aside from this issue, there are also issues for warp sync that cause wrong block details.

Copy link
Collaborator

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

Looks good, but my gut feeling tells me it would be good to update all other cases where we are in a batch context and try to fetch block_details to use this newly added method:
https://github.com/paritytech/parity-ethereum/blob/d1827ea563fd2ef3708473475d05ef603d30a765/ethcore/blockchain/src/blockchain.rs#L809
https://github.com/paritytech/parity-ethereum/blob/d1827ea563fd2ef3708473475d05ef603d30a765/ethcore/blockchain/src/blockchain.rs#L1061
https://github.com/paritytech/parity-ethereum/blob/d1827ea563fd2ef3708473475d05ef603d30a765/ethcore/blockchain/src/blockchain.rs#L1168
https://github.com/paritytech/parity-ethereum/blob/d1827ea563fd2ef3708473475d05ef603d30a765/ethcore/blockchain/src/blockchain.rs#L1667

Even though some places are probably safe (we read total_difficulty that is not really altered anywhere), I'd use this method for consistency and to make the code more future-proof.

@AtkinsChang
Copy link
Contributor Author

@tomusdrw Updated as your suggestion

Copy link
Collaborator

@tomusdrw tomusdrw left a comment

Choose a reason for hiding this comment

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

👌

@ordian ordian added this to the 2.7 milestone Sep 3, 2019
@ordian ordian added A8-looksgood 🦄 Pull request is reviewed well. and removed A0-pleasereview 🤓 Pull request needs code review. labels Sep 3, 2019
@dvdplm
Copy link
Collaborator

dvdplm commented Sep 3, 2019

@AtkinsChang good stuff, thanks! Before merging we're going to run a few tests from this branch just to make sure we don't mess up.
/cc @adilimroz

@adilimroz
Copy link

@dvdplm Ran syncs with the mentioned commits. It all looks good to me.

Copy link
Collaborator

@dvdplm dvdplm left a comment

Choose a reason for hiding this comment

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

Minor nitpicks and some documentation questions.

ethcore/db/src/db.rs Outdated Show resolved Hide resolved
ethcore/blockchain/src/blockchain.rs Outdated Show resolved Hide resolved
ethcore/blockchain/src/blockchain.rs Show resolved Hide resolved
ethcore/blockchain/src/blockchain.rs Outdated Show resolved Hide resolved
@AtkinsChang
Copy link
Contributor Author

Thanks for review
fixed in amended commit

@dvdplm dvdplm merged commit a89bbfe into openethereum:master Sep 5, 2019
dvdplm added a commit that referenced this pull request Sep 9, 2019
* master:
  fix: remove unused error-chain (#11028)
  fix: remove needless use of itertools (#11029)
  Convert `std::test` benchmarks to use Criterion (#10999)
  Fix block detail updating (#11015)
  [trace] introduce trace failed to Ext (#11019)
  cli: update usage and version headers (#10924)
  [private-tx] remove unused rand (#11024)
dvdplm added a commit that referenced this pull request Sep 10, 2019
…he-right-place

* master:
  cleanup json crate (#11027)
  [spec] add istanbul test spec (#11033)
  [json-spec] make blake2 pricing spec more readable (#11034)
  Add blake2_f precompile (#11017)
  Add new line after writing block to hex file. (#10984)
  fix: remove unused error-chain (#11028)
  fix: remove needless use of itertools (#11029)
  Convert `std::test` benchmarks to use Criterion (#10999)
  Fix block detail updating (#11015)
  [trace] introduce trace failed to Ext (#11019)
  cli: update usage and version headers (#10924)
  [private-tx] remove unused rand (#11024)
dvdplm added a commit that referenced this pull request Sep 13, 2019
* master: (70 commits)
  ethcore: remove `test-helper feat` from build (#11047)
  Include test-helpers from ethjson (#11045)
  [ethcore]: cleanup dependencies (#11043)
  add more tx tests (#11038)
  Fix parallel transactions race-condition (#10995)
  [ethcore]: make it compile without `test-helpers` feature (#11036)
  Benchmarks for block verification (#11035)
  Move snapshot related traits to their proper place (#11012)
  cleanup json crate (#11027)
  [spec] add istanbul test spec (#11033)
  [json-spec] make blake2 pricing spec more readable (#11034)
  Add blake2_f precompile (#11017)
  Add new line after writing block to hex file. (#10984)
  fix: remove unused error-chain (#11028)
  fix: remove needless use of itertools (#11029)
  Convert `std::test` benchmarks to use Criterion (#10999)
  Fix block detail updating (#11015)
  [trace] introduce trace failed to Ext (#11019)
  cli: update usage and version headers (#10924)
  [private-tx] remove unused rand (#11024)
  ...
This was referenced Nov 6, 2019
niklasad1 pushed a commit that referenced this pull request Nov 8, 2019
* Add finality parameter to `null engine`

* Add testcase for finalization marking in `ethcore` client

* Add double cache read for db

* Prevent lost update of block details

* Read with pending update for block details in batch
s3krit pushed a commit that referenced this pull request Nov 11, 2019
* ropsten #6631425 foundation #8798209 (#11201)
* [stable] builtin, istanbul and mordor testnet backports (#11234)
  * ethcore-builtin (#10850)
  * [builtin]: support `multiple prices and activations` in chain spec (#11039)
  * [chain specs]: activate `Istanbul` on mainnet (#11228)
  * ethcore/res: add mordor testnet configuration (#11200)
* Update list of bootnodes for xDai chain (#11236)
* ethcore: remove `test-helper feat` from build (#11047)
* Secret store: fix Instant::now() related race in net_keep_alive (#11155) (#11159)
* [stable]: backport #10691 and #10683 (#11143)
  * Fix compiler warning (that will become an error) (#10683)
  * Refactor Clique stepping (#10691)
* Add Constantinople eips to the dev (instant_seal) config (#10809)
* Add cargo-remote dir to .gitignore (?)
* Insert explicit warning into the panic hook (#11225)
* Fix docker centos build (#11226)
* Update MIX bootnodes. (#11203)
* Use provided usd-per-eth value if an endpoint is specified (#11209)
* Add new line after writing block to hex file. (#10984)
* Type annotation for next_key() matching of json filter options (#11192) (but no `FilterOption` in 2.5 so…)
* Upgrade jsonrpc to latest (#11206)
* [CI] check evmbin build (#11096)
* Correct EIP-712 encoding (#11092)
* [client]: Fix for incorrectly dropped consensus messages (#11086)
* Fix block detail updating (#11015)
* Switching sccache from local to Redis (#10971)
* Made ecrecover implementation trait public (#11188)
* [dependencies]: jsonrpc `14.0.1` (#11183)
* [receipt]: add `sender` & `receiver` to `RichReceipts` (#11179)
* [ethcore/builtin]: do not panic in blake2pricer on short input (#11180)
* util Host: fix a double Read Lock bug in fn Host::session_readable() (#11175)
* ethcore client: fix a double Read Lock bug in fn Client::logs() (#11172)
* Change how RPCs eth_call and eth_estimateGas handle "Pending" (#11127)
* Cleanup stratum a bit (#11161)
* Upgrade to jsonrpc v14 (#11151)
* SecretStore: expose restore_key_public in HTTP API (#10241)
s3krit pushed a commit that referenced this pull request Nov 11, 2019
* [CI] check evmbin build (#11096)
* Correct EIP-712 encoding (#11092)
* [client]: Fix for incorrectly dropped consensus messages (#11082) (#11086)
* Update hardcoded headers (foundation, classic, kovan, xdai, ewc, ...) (#11053)
* Add cargo-remote dir to .gitignore (?)
* Update light client headers: ropsten 6631425 foundation 8798209 (#11201)
* Update list of bootnodes for xDai chain (#11236)
* ethcore/res: add mordor testnet configuration (#11200)
* [chain specs]: activate Istanbul on mainnet (#11228)
* [builtin]: support multiple prices and activations in chain spec (#11039)
* [receipt]: add sender & receiver to RichReceipts (#11179)
* [ethcore/builtin]: do not panic in blake2pricer on short input (#11180)
* Made ecrecover implementation trait public (#11188)
* Fix docker centos build (#11226)
* Update MIX bootnodes. (#11203)
* Insert explicit warning into the panic hook (#11225)
* Use provided usd-per-eth value if an endpoint is specified (#11209)
* Cleanup stratum a bit (#11161)
* Add Constantinople EIPs to the dev (instant_seal) config (#10809) (already backported)
* util Host: fix a double Read Lock bug in fn Host::session_readable() (#11175)
* ethcore client: fix a double Read Lock bug in fn Client::logs() (#11172)
* Type annotation for next_key() matching of json filter options (#11192)
* Upgrade jsonrpc to latest (#11206)
* [dependencies]: jsonrpc 14.0.1 (#11183)
* Upgrade to jsonrpc v14 (#11151)
* Switching sccache from local to Redis (#10971)
* Snapshot restoration overhaul (#11219)
* Add new line after writing block to hex file. (#10984)
* Pause pruning while snapshotting (#11178)
* Change how RPCs eth_call and eth_estimateGas handle "Pending" (#11127)
* Fix block detail updating (#11015)
* Make InstantSeal Instant again #11186
* Filter out some bad ropsten warp snapshots (#11247)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A8-looksgood 🦄 Pull request is reviewed well. B0-patch-stable 🕷 Pull request should also be back-ported to the stable branch. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants