sigp / lighthouse

Ethereum consensus client in Rust
https://lighthouse.sigmaprime.io/
Apache License 2.0
2.91k stars 738 forks source link

On-chain exits remaining in node pool #4189

Closed mcdee closed 1 year ago

mcdee commented 1 year ago

Description

Node does not clear voluntary exits from pool once the validator is exiting.

curl -s http://localhost:5051/eth/v1/beacon/pool/voluntary_exits | jq -c '.data[] | select(.message.validator_index == "122622")' | jq .
{
  "message": {
    "epoch": "194119",
    "validator_index": "122622"
  },
  "signature": "0x93a9424dd5408c06b96142d893109a948749217042545c49db104501f9d265f8e6ca5da47a19bd75fd8f636ec530abf80e22f5f8b874f62dcf381db3b9aeb05535da904aaaf424b62820e345e3f7695e6f2105dfa69f622c980067c96bd80b7d"
}

curl -s http://localhost:5051/eth/v1/beacon/states/head/validators/122622 | jq
{
  "execution_optimistic": false,
  "data": {
    "index": "122622",
    "balance": "35250997039",
    "status": "active_exiting",
    "validator": {
      "pubkey": "0x972330aa3387c394018ac6f90877a9b5bcfc561e03a963b76c34a8cd7386291dd9bc1b0c94abcd2e415b717cd02631af",
      "withdrawal_credentials": "0x0077a266d9d7e1ea61b54d5d306bd57bca32ea8fb945f0e2caf818ab6eba5006",
      "effective_balance": "32000000000",
      "slashed": false,
      "activation_eligibility_epoch": "32098",
      "activation_epoch": "32114",
      "exit_epoch": "196264",
      "withdrawable_epoch": "196520"
    }
  }
}

This results in many exits remaining in the pool:

curl -s http://localhost:5051/eth/v1/beacon/pool/voluntary_exits | jq -c '.data | length'
17624

Version

Lighthouse v4.0.1-a53830f
BLS library: blst-modern
SHA256 hardware acceleration: true
Allocator: jemalloc
Specs: mainnet (true), minimal (false), gnosis (true)

Present Behaviour

Lighthouse appears to keep voluntary exits in its pool even after they have been included on-chain.

Expected Behaviour

The exit should be removed from the pool.

Steps to resolve

michaelsproul commented 1 year ago

They're pruned once the validator's exit_epoch is finalized:

https://github.com/sigp/lighthouse/blob/a53830fd60a119bf3f659b253360af8027128e83/beacon_node/operation_pool/src/lib.rs#L507-L519

This validator's exit epoch is still in the future (196264), so it will be pruned once that epoch arrives next week.

The reason we prune like this (as the code comment says) is for simplicity. The ideal pruning criteria would be when the block that the exit is included in is finalized, but that's not readily available from the BeaconState – we would need to iterate the chain history, which is slow(er).

Having a few thousand of these in memory isn't an issue, they're small, and block packing will quickly skip over them when it sees they are no longer relevant to include at the head of the chain.

mcdee commented 1 year ago

It does make it hard to know which exits have been included on-chain (albeit not finalized), which makes it tricky when checking pool sizes over time and across instances, but understand the rationale here so closing the issue.