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

Proposer LMD Score Boosting #2353

Closed
wants to merge 12 commits into from
Closed

Conversation

adiasg
Copy link
Contributor

@adiasg adiasg commented Apr 23, 2021

Edit: Renamed from "Fix LMD balancing attack" to "Proposer LMD Score Boosting"

This PR implements a fix for the LMD balancing attacks, as described here.

Proposer Score Boost

A new "proposer score boost" has been introduced, which boosts the LMD score of blocks that are received in a timely manner. The boost increases the score of the block by committee_weight // 4 for that slot. If a block for slot X is received in the first SECONDS_PER_SLOT // ATTESTATION_OFFSET_QUOTIENT (= 4) seconds of the slot, then the block receives the boost for the duration of slot X. After slot X is over, the boost is removed and the usual LMD score calculations from only attestations are done.

The boost is not applied to blocks that are not received in the first SECONDS_PER_SLOT // ATTESTATION_OFFSET_QUOTIENT seconds of their slots, and this PR does not affect LMD score calculations for such blocks.

lmd-proposer-score-fix

In the above example:

  • block B is received in a timely manner and qualifies for the boost. B's score is boosted for only slot X.
  • block C is not received in a timely manner and does not qualify for the boost.

Summary of Changes

  • Parameters:
    • Added new parameter ATTESTATION_OFFSET_QUOTIENT, which is used to specify the time at which attestations are produced within a slot
  • Store:
    • Added new field store.proposer_score_boost, which is a special LatestMessage that stores the boost
  • Fork Choice:
    • Updated get_latest_attesting_balance to take into account store.proposer_score_boost
    • Updated on_block & on_tick to appropriately set/reset store.proposer_score_boost
  • Testing:
    • Added test for store.proposer_score_boost accounting
    • Updated existing tests to work correctly after introducing proposer score boosting

@adiasg adiasg marked this pull request as ready for review April 23, 2021 21:45
@adiasg adiasg added scope:fork-choice scope:security General protocol security-related items labels Apr 23, 2021
@adiasg
Copy link
Contributor Author

adiasg commented Apr 23, 2021

Note: First merge PR #2292 into dev, then merge this into dev

@joachimneu
Copy link

Following the general approach of balancing, a recent attack dispenses with adversarial network delay and can be found in Appendix I of this manuscript.

@adiasg
Copy link
Contributor Author

adiasg commented May 14, 2021

This fix makes the synchrony assumption of latency < SECONDS_PER_SLOT // ATTESTATION_OFFSET_QUOTIENT (= 4) seconds, and hence prevents the new variant of the attack under synchronous network conditions.

In general, this fix prevents attacks that rely on balancing different forks by utilizing the LMD fork choice score. This is because a few consecutive honest proposers are able to force a single winner from such balanced forks.

@joachimneu
Copy link

If I am not mistaken, then the analysis here misses two aspects:

  • The adversary only needs to release sway votes for honestly led slots, not for adversarially led slots.
  • Adversarial votes can affect a 2x change in score, due to LMD.

If this is so, then an adversary controlling 1/9 = ~0.11 fraction of stake can attack the protocol with the fix for Wp = 1/4*W.

@michaelsproul
Copy link
Contributor

I think the boost also incentivises proposers to orphan late blocks which they've seen, which could be beneficial as late blocks continue to cause issues on mainnet.

In the case where the proposer for slot X publishes their block late, the proposer at slot X + 1 might want to orphan it, even if they've received it and their fork choice selects it as the head. If block X has <W/4 votes then the proposer for slot X + 1 can propose a (timely) block of their own with the same parent as block X, which will then outrank block X thanks to the W/4 boost. If they do this they stand to gain extra rewards from the inclusion of attestations from slot X.

I'd argue that this ability to aggressively orphan late blocks is actually a good thing because it sends a clear signal to the previous proposer that their block was low quality. At the moment we often see late blocks without many votes making it into the canonical chain because they are seen by the next proposer before the start of the next slot. In the pathological case consider a block published 8 seconds into the slot which receives no attestations but still arrives at all nodes before the next slot.

Late blocks hamper consensus and penalise attesters as they invalidate head (and sometimes target) votes for slot X, due to honest attesters voting for X's parent. If we orphan them then at least we improve agreement on target (if X % 32 == 0), and reward the correct-target attesters. Post-Altair there's no way to salvage the head vote rewards for the slot X attesters, as they either voted for a skipped slot and failed the timeliness condition (if block X is orphaned), or voted for the wrong head (if block X is not orphaned).

My hope is that if clients adopt the orphaning logic then it will pressure late block publishers into getting their act together. I suspect that at the moment their metrics don't detect the late blocks they're publishing because late blocks are still rewarded when they make it into the chain. The philosophical question is whether or not it's worth explicitly going against what fork choice says the head should be in order to implement the aggressive orphaning, or whether fork choice should be extended with a notion of a "proposer head" that allows us to count this behaviour as honest.

@adiasg adiasg changed the title Fix LMD balancing attack Proposer LMD Score Boosting Nov 15, 2021
@adiasg
Copy link
Contributor Author

adiasg commented Nov 19, 2021

Closed in favor of #2730. This PR was based on # #2292 and had major conflicts with dev.
#2730 now does not have the (block, epoch)-fork choice from #2292.

@adiasg adiasg closed this Nov 19, 2021
bors bot pushed a commit to sigp/lighthouse that referenced this pull request Dec 13, 2022
## Proposed Changes

With proposer boosting implemented (#2822) we have an opportunity to re-org out late blocks.

This PR adds three flags to the BN to control this behaviour:

* `--disable-proposer-reorgs`: turn aggressive re-orging off (it's on by default).
* `--proposer-reorg-threshold N`: attempt to orphan blocks with less than N% of the committee vote. If this parameter isn't set then N defaults to 20% when the feature is enabled.
* `--proposer-reorg-epochs-since-finalization N`: only attempt to re-org late blocks when the number of epochs since finalization is less than or equal to N. The default is 2 epochs, meaning re-orgs will only be attempted when the chain is finalizing optimally.

For safety Lighthouse will only attempt a re-org under very specific conditions:

1. The block being proposed is 1 slot after the canonical head, and the canonical head is 1 slot after its parent. i.e. at slot `n + 1` rather than building on the block from slot `n` we build on the block from slot `n - 1`.
2. The current canonical head received less than N% of the committee vote. N should be set depending on the proposer boost fraction itself, the fraction of the network that is believed to be applying it, and the size of the largest entity that could be hoarding votes.
3. The current canonical head arrived after the attestation deadline from our perspective. This condition was only added to support suppression of forkchoiceUpdated messages, but makes intuitive sense.
4. The block is being proposed in the first 2 seconds of the slot. This gives it time to propagate and receive the proposer boost.


## Additional Info

For the initial idea and background, see: ethereum/consensus-specs#2353 (comment)

There is also a specification for this feature here: ethereum/consensus-specs#3034

Co-authored-by: Michael Sproul <micsproul@gmail.com>
Co-authored-by: pawan <pawandhananjay@gmail.com>
bors bot pushed a commit to sigp/lighthouse that referenced this pull request Dec 13, 2022
## Proposed Changes

With proposer boosting implemented (#2822) we have an opportunity to re-org out late blocks.

This PR adds three flags to the BN to control this behaviour:

* `--disable-proposer-reorgs`: turn aggressive re-orging off (it's on by default).
* `--proposer-reorg-threshold N`: attempt to orphan blocks with less than N% of the committee vote. If this parameter isn't set then N defaults to 20% when the feature is enabled.
* `--proposer-reorg-epochs-since-finalization N`: only attempt to re-org late blocks when the number of epochs since finalization is less than or equal to N. The default is 2 epochs, meaning re-orgs will only be attempted when the chain is finalizing optimally.

For safety Lighthouse will only attempt a re-org under very specific conditions:

1. The block being proposed is 1 slot after the canonical head, and the canonical head is 1 slot after its parent. i.e. at slot `n + 1` rather than building on the block from slot `n` we build on the block from slot `n - 1`.
2. The current canonical head received less than N% of the committee vote. N should be set depending on the proposer boost fraction itself, the fraction of the network that is believed to be applying it, and the size of the largest entity that could be hoarding votes.
3. The current canonical head arrived after the attestation deadline from our perspective. This condition was only added to support suppression of forkchoiceUpdated messages, but makes intuitive sense.
4. The block is being proposed in the first 2 seconds of the slot. This gives it time to propagate and receive the proposer boost.


## Additional Info

For the initial idea and background, see: ethereum/consensus-specs#2353 (comment)

There is also a specification for this feature here: ethereum/consensus-specs#3034

Co-authored-by: Michael Sproul <micsproul@gmail.com>
Co-authored-by: pawan <pawandhananjay@gmail.com>
bors bot pushed a commit to sigp/lighthouse that referenced this pull request Dec 13, 2022
## Proposed Changes

With proposer boosting implemented (#2822) we have an opportunity to re-org out late blocks.

This PR adds three flags to the BN to control this behaviour:

* `--disable-proposer-reorgs`: turn aggressive re-orging off (it's on by default).
* `--proposer-reorg-threshold N`: attempt to orphan blocks with less than N% of the committee vote. If this parameter isn't set then N defaults to 20% when the feature is enabled.
* `--proposer-reorg-epochs-since-finalization N`: only attempt to re-org late blocks when the number of epochs since finalization is less than or equal to N. The default is 2 epochs, meaning re-orgs will only be attempted when the chain is finalizing optimally.

For safety Lighthouse will only attempt a re-org under very specific conditions:

1. The block being proposed is 1 slot after the canonical head, and the canonical head is 1 slot after its parent. i.e. at slot `n + 1` rather than building on the block from slot `n` we build on the block from slot `n - 1`.
2. The current canonical head received less than N% of the committee vote. N should be set depending on the proposer boost fraction itself, the fraction of the network that is believed to be applying it, and the size of the largest entity that could be hoarding votes.
3. The current canonical head arrived after the attestation deadline from our perspective. This condition was only added to support suppression of forkchoiceUpdated messages, but makes intuitive sense.
4. The block is being proposed in the first 2 seconds of the slot. This gives it time to propagate and receive the proposer boost.


## Additional Info

For the initial idea and background, see: ethereum/consensus-specs#2353 (comment)

There is also a specification for this feature here: ethereum/consensus-specs#3034

Co-authored-by: Michael Sproul <micsproul@gmail.com>
Co-authored-by: pawan <pawandhananjay@gmail.com>
macladson pushed a commit to macladson/lighthouse that referenced this pull request Jan 5, 2023
## Proposed Changes

With proposer boosting implemented (sigp#2822) we have an opportunity to re-org out late blocks.

This PR adds three flags to the BN to control this behaviour:

* `--disable-proposer-reorgs`: turn aggressive re-orging off (it's on by default).
* `--proposer-reorg-threshold N`: attempt to orphan blocks with less than N% of the committee vote. If this parameter isn't set then N defaults to 20% when the feature is enabled.
* `--proposer-reorg-epochs-since-finalization N`: only attempt to re-org late blocks when the number of epochs since finalization is less than or equal to N. The default is 2 epochs, meaning re-orgs will only be attempted when the chain is finalizing optimally.

For safety Lighthouse will only attempt a re-org under very specific conditions:

1. The block being proposed is 1 slot after the canonical head, and the canonical head is 1 slot after its parent. i.e. at slot `n + 1` rather than building on the block from slot `n` we build on the block from slot `n - 1`.
2. The current canonical head received less than N% of the committee vote. N should be set depending on the proposer boost fraction itself, the fraction of the network that is believed to be applying it, and the size of the largest entity that could be hoarding votes.
3. The current canonical head arrived after the attestation deadline from our perspective. This condition was only added to support suppression of forkchoiceUpdated messages, but makes intuitive sense.
4. The block is being proposed in the first 2 seconds of the slot. This gives it time to propagate and receive the proposer boost.


## Additional Info

For the initial idea and background, see: ethereum/consensus-specs#2353 (comment)

There is also a specification for this feature here: ethereum/consensus-specs#3034

Co-authored-by: Michael Sproul <micsproul@gmail.com>
Co-authored-by: pawan <pawandhananjay@gmail.com>
Woodpile37 pushed a commit to Woodpile37/lighthouse that referenced this pull request Jan 6, 2024
With proposer boosting implemented (sigp#2822) we have an opportunity to re-org out late blocks.

This PR adds three flags to the BN to control this behaviour:

* `--disable-proposer-reorgs`: turn aggressive re-orging off (it's on by default).
* `--proposer-reorg-threshold N`: attempt to orphan blocks with less than N% of the committee vote. If this parameter isn't set then N defaults to 20% when the feature is enabled.
* `--proposer-reorg-epochs-since-finalization N`: only attempt to re-org late blocks when the number of epochs since finalization is less than or equal to N. The default is 2 epochs, meaning re-orgs will only be attempted when the chain is finalizing optimally.

For safety Lighthouse will only attempt a re-org under very specific conditions:

1. The block being proposed is 1 slot after the canonical head, and the canonical head is 1 slot after its parent. i.e. at slot `n + 1` rather than building on the block from slot `n` we build on the block from slot `n - 1`.
2. The current canonical head received less than N% of the committee vote. N should be set depending on the proposer boost fraction itself, the fraction of the network that is believed to be applying it, and the size of the largest entity that could be hoarding votes.
3. The current canonical head arrived after the attestation deadline from our perspective. This condition was only added to support suppression of forkchoiceUpdated messages, but makes intuitive sense.
4. The block is being proposed in the first 2 seconds of the slot. This gives it time to propagate and receive the proposer boost.

For the initial idea and background, see: ethereum/consensus-specs#2353 (comment)

There is also a specification for this feature here: ethereum/consensus-specs#3034

Co-authored-by: Michael Sproul <micsproul@gmail.com>
Co-authored-by: pawan <pawandhananjay@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
scope:fork-choice scope:security General protocol security-related items
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants