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

fix: update sync_headers_in_reverse logic to match lotus #4291

Merged
merged 18 commits into from
Jun 5, 2024

Conversation

hanabi1224
Copy link
Contributor

@hanabi1224 hanabi1224 commented May 7, 2024

Summary of changes

Changes introduced in this pull request:

  • Update sync_headers_in_reverse logic to match lotus
  • Avoid re-validating the current head when the local chain is not a fork
  • Avoid some unnecessary clones

Log(importing a snapshot whose head is not a fork, it no longer re-validates the head):

2024-05-07T12:55:50.070707Z  INFO forest_filecoin::chain_sync::chain_muxer: Local node is behind the network, starting BOOTSTRAP from LOCAL_HEAD = 1591906 -> NETWORK_HEAD = 1592005
2024-05-07T12:55:52.146710Z  INFO forest_filecoin::chain_sync::tipset_syncer: Validating tipset: EPOCH = 1591907, N blocks = 2

lotus code(func (syncer *Syncer) collectHeaders): https://github.com/filecoin-project/lotus/blob/master/chain/sync.go#L684
Some highlights:

...
// we want to sync all the blocks until the height above our
// best tipset so far
untilHeight := known.Height() + 1
...
loop:
	for blockSet[len(blockSet)-1].Height() > untilHeight {
             ...
        }
...
if base.IsChildOf(knownParent) {
		// common case: receiving a block that's potentially part of the same tipset as our best block
		return blockSet, nil
	}

	// We have now ascertained that this is *not* a 'fast forward'
	log.Warnf("(fork detected) synced header chain (%s - %d) does not link to our best block (%s - %d)", incoming.Cids(), incoming.Height(), known.Cids(), known.Height())
	fork, err := syncer.syncFork(ctx, base, known, ignoreCheckpoint)

Reference issue to close (if applicable)

Closes #4113

Other information and links

Change checklist

  • I have performed a self-review of my own code,
  • I have made corresponding changes to the documentation,
  • I have added tests that prove my fix is effective or that my feature works (if possible),
  • I have made sure the CHANGELOG is up-to-date. All user-facing changes should be reflected in this document.

@hanabi1224 hanabi1224 force-pushed the hm/update-sync-headers-to-match-lotus branch from 994a715 to 2affcee Compare May 7, 2024 13:09
@hanabi1224 hanabi1224 force-pushed the hm/update-sync-headers-to-match-lotus branch from 2affcee to 23366b9 Compare May 7, 2024 13:27
@hanabi1224 hanabi1224 marked this pull request as ready for review May 7, 2024 13:30
@hanabi1224 hanabi1224 requested a review from a team as a code owner May 7, 2024 13:30
@hanabi1224 hanabi1224 requested review from lemmih and sudo-shashank and removed request for a team May 7, 2024 13:30
// FIXME: The height check might go beyond what is meant by
// "parent", but many parts of the code rely on the tipset's
// height for their processing logic at the moment to obviate it.
&& self.epoch() > other.epoch()
Copy link
Contributor

Choose a reason for hiding this comment

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

q: what you want to say here is that there is just a sanity check, correct? Just an extra measure to make sure the relationship is somewhat correct?

Copy link
Contributor Author

@hanabi1224 hanabi1224 May 7, 2024

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have any code that depends on this check? I think we reject blocks that do not have sensible epochs at an earlier stage. I think we can just remove this extra check.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we have any code that depends on this check? I think we reject blocks that do not have sensible epochs at an earlier stage. I think we can just remove this extra check.

@lemmih No other code depends on this check. Removed.

let oldest_tipset = parent_tipsets.last().clone();
// Determine if the local chain was a fork.
// If it was, then sync the fork tipset range by iteratively walking back
let oldest_tipset = parent_tipsets.last();
Copy link
Contributor

@ruseinov ruseinov May 7, 2024

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, actually parent is quite confusing here, renamed parent_tipsets to pending_tipsets(_for_sync), and oldest_tipset to oldest_pending_tipset

Copy link
Contributor

@lemmih lemmih left a comment

Choose a reason for hiding this comment

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

Logic appears to be sound (though still hard to follow).

// FIXME: The height check might go beyond what is meant by
// "parent", but many parts of the code rely on the tipset's
// height for their processing logic at the moment to obviate it.
&& self.epoch() > other.epoch()
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we have any code that depends on this check? I think we reject blocks that do not have sensible epochs at an earlier stage. I think we can just remove this extra check.

@sudo-shashank sudo-shashank removed their request for review May 13, 2024 11:45
Copy link
Contributor

@aatifsyed aatifsyed left a comment

Choose a reason for hiding this comment

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

AIUI this is transpilation of some go code.
If so, WIBNI you checked in a comment to the reference code, so readers can understand why it is the way it is.

Comment on lines +409 to +410
// Note: the extra `&& self.epoch() > other.epoch()` check in lotus is dropped
// See <https://github.com/filecoin-project/lotus/blob/01ec22974942fb7328a1e665704c6cfd75d93372/chain/types/tipset.go#L258>
Copy link
Contributor

Choose a reason for hiding this comment

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

excellent comment

parent_tipsets.extend(fork_tipsets);
break;
}
info!("Fork detected, searching for a common ancestor between the local chain and the network chain");
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: this log message is basically the same as the comment above, you can probably delete the comment

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.

@hanabi1224
Copy link
Contributor Author

WIBNI you checked in a comment to the reference code, so readers can understand why it is the way it is.

@aatifsyed link added!

@hanabi1224 hanabi1224 enabled auto-merge June 5, 2024 13:44
@hanabi1224 hanabi1224 added this pull request to the merge queue Jun 5, 2024
Merged via the queue into main with commit d7c9b6e Jun 5, 2024
27 checks passed
@hanabi1224 hanabi1224 deleted the hm/update-sync-headers-to-match-lotus branch June 5, 2024 14:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Exporting a snapshot with depth=900 might not be sufficient to bootstrap a forest or lotus node
4 participants