# Suggested Fee Recipient The _fee recipient_ is an Ethereum address nominated by a beacon chain validator to receive tips from user transactions. Given that all mainnet and testnets have gone through [The Merge](https://ethereum.org/en/roadmap/merge/), if you run validators on a network, you are strongly recommended to nominate a fee recipient for your validators. Failing to nominate a fee recipient will result in losing the tips from transactions. ## Background During post-merge block production, the Beacon Node (BN) will provide a `suggested_fee_recipient` to the execution node. This is a 20-byte Ethereum address which the execution node might choose to set as the recipient of other fees or rewards. There is no guarantee that an execution node will use the `suggested_fee_recipient` to collect fees, it may use any address it chooses. It is assumed that an honest execution node _will_ use the `suggested_fee_recipient`, but users should note this trust assumption. The `suggested_fee_recipient` can be provided to the VC, which will transmit it to the BN. The BN also has a choice regarding the fee recipient it passes to the execution node, creating another noteworthy trust assumption. To be sure _you_ control your fee recipient value, run your own BN and execution node (don't use third-party services). ## How to configure a suggested fee recipient The Lighthouse VC provides two methods for setting the `suggested_fee_recipient` (also known simply as the "fee recipient") to be passed to the execution layer during block production. The Lighthouse BN also provides a method for defining this value, should the VC not transmit a value. Assuming trustworthy nodes, the priority for the three methods is: 1. `validator_definitions.yml` 1. `--suggested-fee-recipient` provided to the VC. 1. `--suggested-fee-recipient` provided to the BN. > **NOTE**: It is **not** recommended to _only_ set the fee recipient on the beacon node, as this results > in sub-optimal block proposals. See [this issue](https://github.com/sigp/lighthouse/issues/3432) > for details. ### 1. Setting the fee recipient in the `validator_definitions.yml` Users can set the fee recipient in `validator_definitions.yml` with the `suggested_fee_recipient` key. This option is recommended for most users, where each validator has a fixed fee recipient. Below is an example of the validator_definitions.yml with `suggested_fee_recipient` values: ``` --- - enabled: true voting_public_key: "0x87a580d31d7bc69069b55f5a01995a610dd391a26dc9e36e81057a17211983a79266800ab8531f21f1083d7d84085007" type: local_keystore voting_keystore_path: /home/paul/.lighthouse/validators/0x87a580d31d7bc69069b55f5a01995a610dd391a26dc9e36e81057a17211983a79266800ab8531f21f1083d7d84085007/voting-keystore.json voting_keystore_password_path: /home/paul/.lighthouse/secrets/0x87a580d31d7bc69069b55f5a01995a610dd391a26dc9e36e81057a17211983a79266800ab8531f21f1083d7d84085007 suggested_fee_recipient: "0x6cc8dcbca744a6e4ffedb98e1d0df903b10abd21" - enabled: false voting_public_key: "0xa5566f9ec3c6e1fdf362634ebec9ef7aceb0e460e5079714808388e5d48f4ae1e12897fed1bea951c17fa389d511e477" type: local_keystore voting_keystore_path: /home/paul/.lighthouse/validators/0xa5566f9ec3c6e1fdf362634ebec9ef7aceb0e460e5079714808388e5d48f4ae1e12897fed1bea951c17fa389d511e477/voting-keystore.json voting_keystore_password: myStrongpa55word123&$ suggested_fee_recipient: "0xa2e334e71511686bcfe38bb3ee1ad8f6babcc03d" ``` ### 2. Using the "--suggested-fee-recipient" flag on the validator client The `--suggested-fee-recipient` can be provided to the VC to act as a default value for all validators where a `suggested_fee_recipient` is not loaded from another method. Provide a 0x-prefixed address, e.g. ``` lighthouse vc --suggested-fee-recipient 0x25c4a76E7d118705e7Ea2e9b7d8C59930d8aCD3b ... ``` ### 3. Using the "--suggested-fee-recipient" flag on the beacon node The `--suggested-fee-recipient` can be provided to the BN to act as a default value when the validator client does not transmit a `suggested_fee_recipient` to the BN. ``` lighthouse bn --suggested-fee-recipient 0x25c4a76E7d118705e7Ea2e9b7d8C59930d8aCD3b ... ``` **This value should be considered an emergency fallback**. You should set the fee recipient in the validator client in order for the execution node to be given adequate notice of block proposal. ## Setting the fee recipient dynamically using the keymanager API When the [validator client API](api_vc.md) is enabled, the [standard keymanager API](https://ethereum.github.io/keymanager-APIs/) includes an endpoint for setting the fee recipient dynamically for a given public key. When used, the fee recipient will be saved in `validator_definitions.yml` so that it persists across restarts of the validator client. | Property | Specification | |-------------------|--------------------------------------------| | Path | `/eth/v1/validator/{pubkey}/feerecipient` | | Method | POST | | Required Headers | [`Authorization`](./api_vc_auth_header.md) | | Typical Responses | 202, 404 | ### Example Request Body ```json { "ethaddress": "0x1D4E51167DBDC4789a014357f4029ff76381b16c" } ``` Command: ```bash DATADIR=$HOME/.lighthouse/mainnet PUBKEY=0xa9735061c84fc0003657e5bd38160762b7ef2d67d280e00347b1781570088c32c06f15418c144949f5d736b1d3a6c591 FEE_RECIPIENT=0x1D4E51167DBDC4789a014357f4029ff76381b16c curl -X POST \ -H "Authorization: Bearer $(cat ${DATADIR}/validators/api-token.txt)" \ -H "Content-Type: application/json" \ -d "{ \"ethaddress\": \"${FEE_RECIPIENT}\" }" \ http://localhost:5062/eth/v1/validator/${PUBKEY}/feerecipient | jq ``` Note that an authorization header is required to interact with the API. This is specified with the header `-H "Authorization: Bearer $(cat ${DATADIR}/validators/api-token.txt)"` which read the API token to supply the authentication. Refer to [Authorization Header](./api_vc_auth_header.md) for more information. If you are having permission issue with accessing the API token file, you can modify the header to become `-H "Authorization: Bearer $(sudo cat ${DATADIR}/validators/api-token.txt)"`. #### Successful Response (202) ```json null ``` A `null` response indicates that the request is successful. ### Querying the fee recipient The same path with a `GET` request can be used to query the fee recipient for a given public key at any time. | Property | Specification | |-------------------|--------------------------------------------| | Path | `/eth/v1/validator/{pubkey}/feerecipient` | | Method | GET | | Required Headers | [`Authorization`](./api_vc_auth_header.md) | | Typical Responses | 200, 404 | Command: ```bash DATADIR=$HOME/.lighthouse/mainnet PUBKEY=0xa9735061c84fc0003657e5bd38160762b7ef2d67d280e00347b1781570088c32c06f15418c144949f5d736b1d3a6c591 curl -X GET \ -H "Authorization: Bearer $(cat ${DATADIR}/validators/api-token.txt)" \ -H "Content-Type: application/json" \ http://localhost:5062/eth/v1/validator/${PUBKEY}/feerecipient | jq ``` #### Successful Response (200) ```json { "data": { "pubkey": "0xa9735061c84fc0003657e5bd38160762b7ef2d67d280e00347b1781570088c32c06f15418c144949f5d736b1d3a6c591", "ethaddress": "0x1d4e51167dbdc4789a014357f4029ff76381b16c" } } ``` ### Removing the fee recipient The same path with a `DELETE` request can be used to remove the fee recipient for a given public key at any time. This is useful if you want the fee recipient to fall back to the validator client (or beacon node) default. | Property | Specification | |-------------------|--------------------------------------------| | Path | `/eth/v1/validator/{pubkey}/feerecipient` | | Method | DELETE | | Required Headers | [`Authorization`](./api_vc_auth_header.md) | | Typical Responses | 204, 404 | Command: ```bash DATADIR=$HOME/.lighthouse/mainnet PUBKEY=0xa9735061c84fc0003657e5bd38160762b7ef2d67d280e00347b1781570088c32c06f15418c144949f5d736b1d3a6c591 curl -X DELETE \ -H "Authorization: Bearer $(cat ${DATADIR}/validators/api-token.txt)" \ -H "Content-Type: application/json" \ http://localhost:5062/eth/v1/validator/${PUBKEY}/feerecipient | jq ``` #### Successful Response (204) ```json null ``` ## FAQ ### Why do I have to nominate an Ethereum address as the fee recipient? You might wonder why the validator can't just accumulate transactions fees in the same way that it accumulates other staking rewards. The reason for this is that transaction fees are computed and validated by the execution node, and therefore need to be paid to an address that exists on the execution chain. Validators use BLS keys which do not correspond to Ethereum addresses, so they have no "presence" on the execution chain. Therefore, it's necessary for each validator to nominate a fee recipient address.