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: correctly handle null blocks when detecting an expensive fork #7210

Merged
merged 4 commits into from
Aug 31, 2021

Conversation

Stebalien
Copy link
Member

Also improve/fix documentation to reflect the actual tipset that's passed into upgrades.

And update some comments.

fixes #7192

@codecov
Copy link

codecov bot commented Aug 27, 2021

Codecov Report

Merging #7210 (91da70f) into master (714635c) will decrease coverage by 0.01%.
The diff coverage is 82.35%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #7210      +/-   ##
==========================================
- Coverage   39.13%   39.12%   -0.02%     
==========================================
  Files         608      608              
  Lines       64602    64620      +18     
==========================================
  Hits        25283    25283              
- Misses      34930    34943      +13     
- Partials     4389     4394       +5     
Impacted Files Coverage Δ
chain/stmgr/execute.go 74.09% <ø> (ø)
chain/stmgr/utils.go 36.98% <ø> (ø)
chain/stmgr/call.go 67.48% <78.57%> (+1.48%) ⬆️
chain/stmgr/forks.go 46.98% <100.00%> (+1.16%) ⬆️
chain/actors/builtin/paych/paych.go 16.88% <0.00%> (-5.20%) ⬇️
chain/types/tipset_key.go 85.96% <0.00%> (-3.51%) ⬇️
node/hello/hello.go 63.21% <0.00%> (-3.45%) ⬇️
storage/wdpost_sched.go 75.24% <0.00%> (-1.99%) ⬇️
chain/vm/vm.go 59.47% <0.00%> (-1.12%) ⬇️
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 714635c...91da70f. Read the comment docs.

Also improve/fix documentation to reflect the _actual_ tipset that's
passed into upgrades.

And update some comments.

fixes #7192
chain/stmgr/forks.go Outdated Show resolved Hide resolved
@@ -99,7 +99,6 @@ func (sm *StateManager) ApplyBlocks(ctx context.Context, parentEpoch abi.ChainEp
}
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: not at all your bug but reading the above code it looks like line 82's error message is wrong and confusing and makes sense to fix now.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd rather not touch that for now. I don't think that error is consensus critical, but I'd rather not touch it.

chain/stmgr/forks.go Show resolved Hide resolved
@@ -140,25 +149,33 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri
// run the fork logic in `sm.TipSetState`. We need the _current_
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a good reason why Call happens against tipset parent state and CallWithGas happens against tipset state? As far as I understand is what requires the introduction of hasExpensiveForkBetween. Beyond removing extra work it would also just be nice to standardize these two similar calls

Copy link
Member Author

Choose a reason for hiding this comment

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

CallWithGas applies the message on-top-of the tipset to provide better gas estimation, I think. By executing it on-top-of the last tipset, instead of on-top-of the parent tipset state, we get the best gas estimates.

I'd prefer to always use the parent state, but I'm not sure what might break. I'm especially concerned that, e.g., it might (rarely) cause issues with window post:

  1. See we're at height X.
  2. Try to push the proof message.
  3. Fail because the window isn't open yet.

func (sm *StateManager) hasExpensiveFork(ctx context.Context, height abi.ChainEpoch) bool {
// Returns true if executing the current tipset would trigger an expensive fork.
//
// - If the tipset is the genesis, this function always returns false.
Copy link
Contributor

Choose a reason for hiding this comment

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

As written now this invariant depends on the sm.expensiveUpgrades table which in reasonable scenarios could potentially contain "expensive" upgrades if say we did all migrations at the genesis epoch.

It might be better to override the table to always return false on 0 to maintain this invariant. Any network doing this would probably be doing very little work in the expensive migration since nothing has happened in state yet.

Also all existing callers seem to implicitly assume that this is the case anyway by only checking heights > 0 so why not make it official.

Copy link
Member Author

Choose a reason for hiding this comment

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

Because the function is called hasExpensiveFork, not hasExpensiveForkOrIsGenesis 😄. Basically, I don't want to surprise users.

At the moment, genesis matters to all callers because there's really no other option. But I'd like to keep that as an explicit decision.

Copy link
Member Author

Choose a reason for hiding this comment

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

But I've fixed the issue in Call where I wasn't handling this consistently.

@@ -292,14 +307,20 @@ func TestForkRefuseCall(t *testing.T) {
GasFeeCap: types.NewInt(0),
}

nullStart := abi.ChainEpoch(testForkHeight - nullsBefore)
nullLength := abi.ChainEpoch(nullsBefore + nullsAfter)

for i := 0; i < 50; i++ {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not your bug: I don't love that testForkHeight is a global and that this test relies on knowing that its value is 40 in order to actually test anything. Maybe make testForkHeight not a global, or change 50 to something like 2 * testForkHeight?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well, being a global is intentional. But yeah, 50 being hard-coded is a problem.

@magik6k
Copy link
Contributor

magik6k commented Aug 31, 2021

Lint fails

chain/stmgr/forks.go:215:32: `occuring` is a misspelling of `occurring` (misspell)
// migration. NOTE: migrations occuring _at_ the target height are not included, as they're executed

@Stebalien Stebalien merged commit 6a02237 into master Aug 31, 2021
@Stebalien Stebalien deleted the fix/fork-check branch August 31, 2021 18:01
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.

TestForkRefuseCall has a flake
3 participants