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

core/types: fix immutability guarantees in Block #27844

Merged
merged 1 commit into from
Aug 4, 2023

Conversation

fjl
Copy link
Contributor

@fjl fjl commented Aug 3, 2023

This change rearranges the accessor methods in block.go and fixes some minor issues with the copy-on-write logic of block data. As a refresher, the rules around block immutability are as follows:

  • We copy all data when the block is constructed. This makes the references held inside the block independent of whatever value was passed in.

  • We copy all header data on access. This is because any change to the header would mess up the cached hash and size values in the block. Calling code is expected to take advantage of this to avoid over-allocating!

  • When new body data is attached to the block, we create a shallow copy of the block. This ensures block modifications are race-free.

  • We do not copy body data on access because it does not affect the caches, and also because it would be too expensive.

The change corrects these issues:

  • Block.WithWithdrawals did not create a shallow copy of the block.

  • Block.WithBody copied the header unnecessarily, and did not preserve withdrawals.

However, the bugs did not affect any code in go-ethereum because blocks are always created using NewBlockWithHeader().WithBody().WithWithdrawals().

This change rearranges the accessor methods in block.go and fixes some minor issues with
the copy-on-write logic of block data. As a refresher, the rules around block immutability
are as follows:

- We copy all data when the block is constructed. This makes the references held
  inside the block independent of whatever value was passed in.

- We copy all header data on access. This is because any change to the header would mess
  up the cached hash and size values in the block. Calling code is expected to take
  advantage of this to avoid over-allocating!

- When new body data is attached to the block, we create a shallow copy of the block.
  This ensures block modifications are race-free.

- We do not copy body data on access because it does not affect the caches, and also
  because it would be too expensive.

The change corrects these issues:

- Block.WithWithdrawals did not create a shallow copy of the block.

- Block.WithBody copied the header unnecessarily, and did not preserve withdrawals.

However, the bugs did not affect any code in go-ethereum because blocks are *always*
created using NewBlockWithHeader().WithBody().WithWithdrawals().
@fjl fjl merged commit df54435 into ethereum:master Aug 4, 2023
1 check passed
@fjl fjl added this to the 1.12.1 milestone Aug 4, 2023
devopsbo3 pushed a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
This change rearranges the accessor methods in block.go and fixes some minor issues with
the copy-on-write logic of block data. Fixed issues:

- Block.WithWithdrawals did not create a shallow copy of the block.

- Block.WithBody copied the header unnecessarily, and did not preserve withdrawals.

However, the bugs did not affect any code in go-ethereum because blocks are *always*
created using NewBlockWithHeader().WithBody().WithWithdrawals()
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
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.

2 participants