Skip to content

fix: Rollback: wrong modification of state.LastHeightValidatorsChanged while rollback at a special height (backport #2136)#2611

Merged
melekes merged 1 commit intov0.37.xfrom
mergify/bp/v0.37.x/pr-2136
Mar 14, 2024
Merged

fix: Rollback: wrong modification of state.LastHeightValidatorsChanged while rollback at a special height (backport #2136)#2611
melekes merged 1 commit intov0.37.xfrom
mergify/bp/v0.37.x/pr-2136

Conversation

@mergify
Copy link
Contributor

@mergify mergify bot commented Mar 14, 2024

closes: #2137 #1074

Description

Rollback at a specific height causes the node to fail to start. This is caused by the error code:

valChangeHeight = rollbackHeight + 1

According to the definition of the State struct as below

// we set s.LastHeightValidatorsChanged = s.LastBlockHeight + 1 + 1

LastHeightValidatorsChanged satisfy the following condition under any circumstances
1 <= state.LastHeightValidatorsChanged <= state.LastBlockHeight + 1 + 1

this condition can also be confirmed by looking at the code in func (store dbStore) save(state State, key []byte) error

if err := store.saveValidatorsInfo(nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators, batch); err != nil {

state.LastHeightValidatorsChanged is with nextHeight + 1(state.LastBlockHeight + 1 + 1) corresponds.

When we rollback from block height state.LastHeightValidatorsChanged - 1 to height state.LastHeightValidatorsChanged - 2, newState.LastHeightValidatorsChanged would be wrong to modified into the state.LastHeightValidatorsChanged - 1

Issue

Let me give an example to describe the issue:

example

... => [block 242 (5validators)] ==state1(5validators)==> [block 243 (5validators)] ==state2(4validators)==> [block 244 (4validators)] => ...

  1. Assume that the current height of the block is 243, current state is state2 and state2.LastHeightValidatorsChanged == 244, validatorSet changed to 4 validators in the block 244 and state2

  2. Rollback to block 242 and state1, the target rollbackHeight == 242

  3. Since the error code,

    valChangeHeight = rollbackHeight + 1

    state1.LastHeightValidatorsChanged was changed to 243 incorrectly and it should be 244

  4. After rollbacked to block 242, node could not start properly

Solution

See code for details.

PR checklist

  • Tests written/updated
  • Changelog entry added in .changelog (we use unclog to manage our changelog)
  • Updated relevant documentation (docs/ or spec/) and code comments
  • Title follows the Conventional Commits spec

This is an automatic backport of pull request #2136 done by [Mergify](https://mergify.com).

…nged` while rollback at a special height (#2136)

closes: #2137 #1074

## Description
Rollback at a specific height causes the node to fail to start. This is
caused by the error code:

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/rollback.go#L71

According to the definition of the `State` struct as below

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/state.go#L63
`LastHeightValidatorsChanged` satisfy the following condition under any
circumstances
1 <= `state.LastHeightValidatorsChanged` <= `state.LastBlockHeight + 1 +
1`

this condition can also be confirmed by looking at the code in `func
(store dbStore) save(state State, key []byte) error`

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/store.go#L229

`state.LastHeightValidatorsChanged` is with `nextHeight +
1`(`state.LastBlockHeight + 1 + 1`) corresponds.

When we rollback from block height `state.LastHeightValidatorsChanged -
1` to height `state.LastHeightValidatorsChanged - 2`,
`newState.LastHeightValidatorsChanged` would be wrong to modified into
the `state.LastHeightValidatorsChanged - 1`

## Issue
Let me give an example to describe the issue:

### example
> ... => [block 242 (5validators)] ==state1(5validators)==> [block 243
(5validators)] ==state2(4validators)==> [block 244 (4validators)] => ...

1. Assume that the current height of the block is 243, current state is
`state2` and `state2.LastHeightValidatorsChanged` == 244, validatorSet
changed to 4 validators in the block 244 and state2

2. Rollback to block 242 and state1, the target `rollbackHeight` == 242

3. Since the error code,
https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/rollback.go#L71
`state1.LastHeightValidatorsChanged` was changed to 243 incorrectly and
it should be 244

4. After rollbacked to block 242, node could not start properly

## Solution
See code for details.

#### PR checklist

- [x] Tests written/updated
- [ ] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [x] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

Co-authored-by: Andy Nogueira <me@andynogueira.dev>
Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
(cherry picked from commit 269219c)
@melekes melekes merged commit 479c109 into v0.37.x Mar 14, 2024
@melekes melekes deleted the mergify/bp/v0.37.x/pr-2136 branch March 14, 2024 04:00
czarcas7ic pushed a commit to osmosis-labs/cometbft that referenced this pull request Mar 25, 2024
…nged` while rollback at a special height (backport cometbft#2136) (cometbft#2611)

closes: cometbft#2137 cometbft#1074

## Description
Rollback at a specific height causes the node to fail to start. This is
caused by the error code:

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/rollback.go#L71

According to the definition of the `State` struct as below

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/state.go#L63
`LastHeightValidatorsChanged` satisfy the following condition under any
circumstances
1 <= `state.LastHeightValidatorsChanged` <= `state.LastBlockHeight + 1 +
1`

this condition can also be confirmed by looking at the code in `func
(store dbStore) save(state State, key []byte) error`

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/store.go#L229

`state.LastHeightValidatorsChanged` is with `nextHeight +
1`(`state.LastBlockHeight + 1 + 1`) corresponds.


When we rollback from block height `state.LastHeightValidatorsChanged -
1` to height `state.LastHeightValidatorsChanged - 2`,
`newState.LastHeightValidatorsChanged` would be wrong to modified into
the `state.LastHeightValidatorsChanged - 1`
 

## Issue
Let me give an example to describe the issue:

### example
> ... => [block 242 (5validators)] ==state1(5validators)==> [block 243
(5validators)] ==state2(4validators)==> [block 244 (4validators)] => ...
 
1. Assume that the current height of the block is 243, current state is
`state2` and `state2.LastHeightValidatorsChanged` == 244, validatorSet
changed to 4 validators in the block 244 and state2

2. Rollback to block 242 and state1, the target `rollbackHeight` == 242

3. Since the error code,
https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/rollback.go#L71
`state1.LastHeightValidatorsChanged` was changed to 243 incorrectly and
it should be 244

4. After rollbacked to block 242, node could not start properly

## Solution
See code for details.


#### PR checklist

- [x] Tests written/updated
- [ ] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [x] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec
<hr>This is an automatic backport of pull request cometbft#2136 done by
[Mergify](https://mergify.com).

Co-authored-by: Ethan <cosinlinker@gmail.com>
ivanshukhov pushed a commit to planq-network/cometbft that referenced this pull request Apr 3, 2024
…nged` while rollback at a special height (backport cometbft#2136) (cometbft#2611)

closes: cometbft#2137 cometbft#1074

## Description
Rollback at a specific height causes the node to fail to start. This is
caused by the error code:

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/rollback.go#L71

According to the definition of the `State` struct as below

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/state.go#L63
`LastHeightValidatorsChanged` satisfy the following condition under any
circumstances
1 <= `state.LastHeightValidatorsChanged` <= `state.LastBlockHeight + 1 +
1`

this condition can also be confirmed by looking at the code in `func
(store dbStore) save(state State, key []byte) error`

https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/store.go#L229

`state.LastHeightValidatorsChanged` is with `nextHeight +
1`(`state.LastBlockHeight + 1 + 1`) corresponds.


When we rollback from block height `state.LastHeightValidatorsChanged -
1` to height `state.LastHeightValidatorsChanged - 2`,
`newState.LastHeightValidatorsChanged` would be wrong to modified into
the `state.LastHeightValidatorsChanged - 1`
 

## Issue
Let me give an example to describe the issue:

### example
> ... => [block 242 (5validators)] ==state1(5validators)==> [block 243
(5validators)] ==state2(4validators)==> [block 244 (4validators)] => ...
 
1. Assume that the current height of the block is 243, current state is
`state2` and `state2.LastHeightValidatorsChanged` == 244, validatorSet
changed to 4 validators in the block 244 and state2

2. Rollback to block 242 and state1, the target `rollbackHeight` == 242

3. Since the error code,
https://github.com/cometbft/cometbft/blob/635d0b596c7300c98caa57e7aab26a7a4579ab97/internal/state/rollback.go#L71
`state1.LastHeightValidatorsChanged` was changed to 243 incorrectly and
it should be 244

4. After rollbacked to block 242, node could not start properly

## Solution
See code for details.


#### PR checklist

- [x] Tests written/updated
- [ ] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [x] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [x] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec
<hr>This is an automatic backport of pull request cometbft#2136 done by
[Mergify](https://mergify.com).

Co-authored-by: Ethan <cosinlinker@gmail.com>
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