Fix fork choice#10837
Conversation
`is_from_route_finalized` check before switching to parent
tomusdrw
left a comment
There was a problem hiding this comment.
Looks good!
But I really think we need to write a bunch of tests to make sure it's working correctly. Some cases I have in mind - (X) means that X is finalised.
Case 1:
(A) - A1 - A2 - A3[to]
- B1 - B2[from]
Case 2:
A - A1 - (A2) - A3[from]
- B1 - B2[to]
Case 3:
A - (A1)[to] - A2[from]
Case 4:
A - (A1)[from] - A2[to]
I believe Case 4 will incorrectly return is_from_route_finalized: false, but so was the previous code, so we should either carefuly check the consequences and change the behaviour or document it properly and make sure it's will not cause us trouble in the future.
|
The test failure here is fixable by a rebase. |
* master: refactor: whisper: Add type aliases and update rustdocs in message.rs (#10812) Break circular dependency between Client and Engine (part 1) (#10833) tests: Relates to #10655: Test instructions for Readme (#10835) refactor: Related #9459 - evmbin: replace untyped json! macro with fully typed serde serialization using Rust structs (#10657) idiomatic changes to PodState (#10834) Allow --nat extip:your.host.here.org (#10830) When updating the client or when called from RPC, sleep should mean sleep (#10814) Remove excessive warning (#10831) Fix typo in README.md (#10828) ethcore does not use byteorder (#10829) Better logging when backfilling ancient blocks fail (#10796) depends: Update wordlist to v1.3 (#10823) cargo update -p smallvec (#10822) replace memzero with zeroize crate (#10816) Don't repeat the logic from Default impl (#10813) removed additional_params method (#10818) Add Constantinople eips to the dev (instant_seal) config (#10809)
|
@tomusdrw I added tests for |
| } | ||
|
|
||
| /// Add a block with randomly generated transactions. | ||
| #[inline] |
There was a problem hiding this comment.
This is a test helper yes? Is it performance sensitive?
There was a problem hiding this comment.
Yeah I think it's only used for tests. I just followed the structure of the other similar methods, so I'm not sure whether inline is needed here.
| let metadata = get_metadata(); | ||
| let block_number = parent_number + 1; | ||
| let transactions = metadata.transactions; | ||
| let transactions_root = ordered_trie_root(transactions.iter().map(|tx| { |
There was a problem hiding this comment.
You sure you need to loop over all txs and encode them like this, and why as a stream and not rlp::encode? Honest question, I really don't know!
There was a problem hiding this comment.
yeh, .map(rlp::encode) produces the same result and is shorter
debris
left a comment
There was a problem hiding this comment.
lgtm! there is just one minor idiomatic fix to do in a test :)
| let metadata = get_metadata(); | ||
| let block_number = parent_number + 1; | ||
| let transactions = metadata.transactions; | ||
| let transactions_root = ordered_trie_root(transactions.iter().map(|tx| { |
There was a problem hiding this comment.
yeh, .map(rlp::encode) produces the same result and is shorter
| assert_eq!(bc.best_block_hash(), a2_hash); | ||
|
|
||
| mark_finalized(a1_hash, &db, &bc); | ||
| assert!(!bc.tree_route(a1_hash, a2_hash).unwrap().is_from_route_finalized); |
There was a problem hiding this comment.
Can we document this counter intuitive behavior in the function docs? A small NOTE would suffice, that is_from_route_finalized works only if from and to are on different forks (i.e. have common ancestor or one is not an ancestor of the other)
There was a problem hiding this comment.
Yep, I added a comment to the tree_route method.
| @@ -55,18 +55,26 @@ dependencies = [ | |||
|
|
|||
| [[package]] | |||
| name = "aho-corasick" | |||
| version = "0.6.8" | |||
| version = "0.6.10" | |||
There was a problem hiding this comment.
did you run cargo update? :)
it would make backporting harder, so please revert
There was a problem hiding this comment.
Hm, I just deleted the lock file and re-built the project...
There was a problem hiding this comment.
instead of deleting, can you checkout Cargo.lock from master and build it with it?
git checkout master Cargo.lock
cargo check
There was a problem hiding this comment.
Yeah sure, sorry about that. Done.
| log = "0.4" | ||
| parity-bytes = "0.1" | ||
| parking_lot = "0.8" | ||
| rand = "0.6" |
There was a problem hiding this comment.
No, actually the generator.rs module is not for tests only
* master: Run cargo fix on a few of the worst offenders (#10854) removed redundant fork choice abstraction (#10849) Extract state-db from ethcore (#10858) Fix fork choice (#10837) Move more code into state-account (#10840) Remove compiler warning (#10865) [ethash] use static_assertions crate (#10860)
* master: Run cargo fix on a few of the worst offenders (#10854) removed redundant fork choice abstraction (#10849) Extract state-db from ethcore (#10858) Fix fork choice (#10837) Move more code into state-account (#10840) Remove compiler warning (#10865) [ethash] use static_assertions crate (#10860)
|
Is this included in any of the already released versions (the last one atm is 2.5.6)? If not yet, which version is it scheduled to be included into? |
|
@phahulin it was included in 2.6.0 (beta) so it is available on the 2.6 branch releases - I'm not sure if it was backported to stable at any point as well though... |
* Fix fork choice: `is_from_route_finalized` check before switching to parent * Add tests for `tree_route` with finalization * Fix Cargo dependencies * Add comment on `tree_route` for finalization. Refactor a test. * Fix compilation error * Checkout Cargo.lock from master
* Fix fork choice: `is_from_route_finalized` check before switching to parent * Add tests for `tree_route` with finalization * Fix Cargo dependencies * Add comment on `tree_route` for finalization. Refactor a test. * Fix compilation error * Checkout Cargo.lock from master
* add more tx tests (#11038) * Fix parallel transactions race-condition (#10995) * Add blake2_f precompile (#11017) * [trace] introduce trace failed to Ext (#11019) * Edit publish-onchain.sh to use https (#11016) * Fix deadlock in network-devp2p (#11013) * EIP 1108: Reduce alt_bn128 precompile gas costs (#11008) * xDai chain support and nodes list update (#10989) * EIP 2028: transaction gas lowered from 68 to 16 (#10987) * EIP-1344 Add CHAINID op-code (#10983) * manual publish jobs for releases, no changes for nightlies (#10977) * [blooms-db] Fix benchmarks (#10974) * Verify transaction against its block during import (#10954) * Better error message for rpc gas price errors (#10931) * Fix fork choice (#10837) * Fix compilation on recent nightlies (#10991)
* add more tx tests (#11038) * Fix parallel transactions race-condition (#10995) * Add blake2_f precompile (#11017) * [trace] introduce trace failed to Ext (#11019) * Edit publish-onchain.sh to use https (#11016) * Fix deadlock in network-devp2p (#11013) * EIP 1108: Reduce alt_bn128 precompile gas costs (#11008) * xDai chain support and nodes list update (#10989) * EIP 2028: transaction gas lowered from 68 to 16 (#10987) * EIP-1344 Add CHAINID op-code (#10983) * manual publish jobs for releases, no changes for nightlies (#10977) * [blooms-db] Fix benchmarks (#10974) * Verify transaction against its block during import (#10954) * Better error message for rpc gas price errors (#10931) * tx-pool: accept local tx with higher gas price when pool full (#10901) * Fix fork choice (#10837) * Cleanup unused vm dependencies (#10787) * Fix compilation on recent nightlies (#10991)
Fixes #10085
It seems that
is_from_route_finalizedwas computed for the parent's block finalization at each iteration infn tree_route. Thus if a fork happened, and the common ancestor was finalized, thefrombranch would be marked asfinalizedalthough it wasn't, and the switch to the better branch would never happened.