diff --git a/chain-spec/chain/chain_spec.go b/chain-spec/chain/chain_spec.go index 353e21cac9..13229c4c47 100644 --- a/chain-spec/chain/chain_spec.go +++ b/chain-spec/chain/chain_spec.go @@ -20,11 +20,21 @@ package chain +import ( + "github.com/berachain/beacon-kit/primitives/common" + "github.com/berachain/beacon-kit/primitives/math" +) + +type ( + // ChainSpec defines an interface for chain-specific parameters. + //nolint:revive // We can remove this once we have cleaned up generics. + ChainSpec = Spec[common.DomainType, math.Epoch, math.Slot, any] +) + // Spec defines an interface for accessing chain-specific parameters. type Spec[ DomainTypeT ~[4]byte, EpochT ~uint64, - ExecutionAddressT ~[20]byte, SlotT ~uint64, CometBFTConfigT any, ] interface { @@ -99,7 +109,7 @@ type Spec[ // Eth1-related values. // DepositContractAddress returns the deposit contract address. - DepositContractAddress() ExecutionAddressT + DepositContractAddress() common.ExecutionAddress // MaxDepositsPerBlock returns the maximum number of deposit operations per // block. @@ -206,49 +216,58 @@ type Spec[ // EVMInflationAddress returns the address on the EVM which will receive // the inflation amount of native EVM balance through a withdrawal every // block. - EVMInflationAddress() ExecutionAddressT + EVMInflationAddress() common.ExecutionAddress // EVMInflationPerBlock returns the amount of native EVM balance (in Gwei) // to be minted to the EVMInflationAddress via a withdrawal every block. EVMInflationPerBlock() uint64 } +// HeightDependentParams contains parameters that may change depending on the block height. +type HeightDependentParams struct { + Height uint64 + MaxEffectiveBalance uint64 + ValidatorSetCap uint64 + EVMInflationPerBlock uint64 +} + // chainSpec is a concrete implementation of the ChainSpec interface, holding // the actual data. type chainSpec[ DomainTypeT ~[4]byte, EpochT ~uint64, - ExecutionAddressT ~[20]byte, SlotT ~uint64, CometBFTConfigT any, ] struct { // Data contains the actual chain-specific parameter values. - Data SpecData[DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT] + Data SpecData[DomainTypeT, EpochT, SlotT, CometBFTConfigT] + // HeightParams contains parameters that depend on the block height + HeightParams []HeightDependentParams + // heightTracker tracks the current block height + heightTracker *heightTracker } -// NewChainSpec creates a new instance of a ChainSpec with the provided data. +// NewChainSpec creates a new ChainSpec. func NewChainSpec[ DomainTypeT ~[4]byte, EpochT ~uint64, - ExecutionAddressT ~[20]byte, SlotT ~uint64, CometBFTConfigT any, -](data SpecData[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, -]) (Spec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, +](data SpecData[DomainTypeT, EpochT, SlotT, CometBFTConfigT]) (Spec[ + DomainTypeT, + EpochT, + SlotT, + CometBFTConfigT, ], error) { - c := &chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, - ]{ - Data: data, - } - return c, c.validate() + return &chainSpec[DomainTypeT, EpochT, SlotT, CometBFTConfigT]{ + Data: data, + heightTracker: newHeightTracker(), + }, nil } // validate ensures that the chain spec is valid, returning error if it is not. func (c *chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) validate() error { if c.MaxWithdrawalsPerPayload() <= 1 { return ErrInsufficientMaxWithdrawalsPerPayload @@ -266,64 +285,62 @@ func (c *chainSpec[ // MinDepositAmount returns the minimum deposit amount required. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MinDepositAmount() uint64 { return c.Data.MinDepositAmount } // MaxEffectiveBalance returns the maximum effective balance. -func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, +func (c *chainSpec[ + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MaxEffectiveBalance(isPostUpgrade bool) uint64 { - if isPostUpgrade { - return c.Data.MaxEffectiveBalancePostUpgrade - } - - return c.Data.MaxEffectiveBalancePreUpgrade + currentHeight := c.getCurrentHeight() + params := c.GetParamsForHeight(currentHeight) + return params.MaxEffectiveBalance } // EjectionBalance returns the balance below which a validator is ejected. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) EjectionBalance() uint64 { return c.Data.EjectionBalance } // EffectiveBalanceIncrement returns the increment of effective balance. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) EffectiveBalanceIncrement() uint64 { return c.Data.EffectiveBalanceIncrement } func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) HysteresisQuotient() uint64 { return c.Data.HysteresisQuotient } func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) HysteresisDownwardMultiplier() uint64 { return c.Data.HysteresisDownwardMultiplier } func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) HysteresisUpwardMultiplier() uint64 { return c.Data.HysteresisUpwardMultiplier } // SlotsPerEpoch returns the number of slots per epoch. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) SlotsPerEpoch() uint64 { return c.Data.SlotsPerEpoch } // SlotsPerHistoricalRoot returns the number of slots per historical root. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) SlotsPerHistoricalRoot() uint64 { return c.Data.SlotsPerHistoricalRoot } @@ -331,49 +348,49 @@ func (c chainSpec[ // MinEpochsToInactivityPenalty returns the minimum number of epochs before an // inactivity penalty is applied. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MinEpochsToInactivityPenalty() uint64 { return c.Data.MinEpochsToInactivityPenalty } // DomainTypeProposer returns the domain for beacon proposer signatures. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DomainTypeProposer() DomainTypeT { return c.Data.DomainTypeProposer } // DomainTypeAttester returns the domain for beacon attester signatures. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DomainTypeAttester() DomainTypeT { return c.Data.DomainTypeAttester } // DomainTypeRandao returns the domain for RANDAO reveal signatures. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DomainTypeRandao() DomainTypeT { return c.Data.DomainTypeRandao } // DomainTypeDeposit returns the domain for deposit contract signatures. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DomainTypeDeposit() DomainTypeT { return c.Data.DomainTypeDeposit } // DomainTypeVoluntaryExit returns the domain for voluntary exit signatures. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DomainTypeVoluntaryExit() DomainTypeT { return c.Data.DomainTypeVoluntaryExit } // DomainTypeSelectionProof returns the domain for selection proof signatures. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DomainTypeSelectionProof() DomainTypeT { return c.Data.DomainTypeSelectionProof } @@ -381,35 +398,35 @@ func (c chainSpec[ // DomainTypeAggregateAndProof returns the domain for aggregate and proof // signatures. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DomainTypeAggregateAndProof() DomainTypeT { return c.Data.DomainTypeAggregateAndProof } // DomainTypeApplicationMask returns the domain for the application mask. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DomainTypeApplicationMask() DomainTypeT { return c.Data.DomainTypeApplicationMask } // DepositContractAddress returns the address of the deposit contract. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, -]) DepositContractAddress() ExecutionAddressT { + DomainTypeT, EpochT, SlotT, CometBFTConfigT, +]) DepositContractAddress() common.ExecutionAddress { return c.Data.DepositContractAddress } // MaxDepositsPerBlock returns the maximum number of deposits per block. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MaxDepositsPerBlock() uint64 { return c.Data.MaxDepositsPerBlock } // DepositEth1ChainID returns the chain ID of the execution chain. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DepositEth1ChainID() uint64 { return c.Data.DepositEth1ChainID } @@ -417,70 +434,70 @@ func (c chainSpec[ // Eth1FollowDistance returns the distance between the eth1 chain and the beacon // chain. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) Eth1FollowDistance() uint64 { return c.Data.Eth1FollowDistance } // TargetSecondsPerEth1Block returns the target time between eth1 blocks. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) TargetSecondsPerEth1Block() uint64 { return c.Data.TargetSecondsPerEth1Block } // DenebPlusForEpoch returns the epoch of the Deneb+ fork. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) DenebPlusForkEpoch() EpochT { return c.Data.DenebPlusForkEpoch } // ElectraForkEpoch returns the epoch of the Electra fork. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) ElectraForkEpoch() EpochT { return c.Data.ElectraForkEpoch } // EpochsPerHistoricalVector returns the number of epochs per historical vector. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) EpochsPerHistoricalVector() uint64 { return c.Data.EpochsPerHistoricalVector } // EpochsPerSlashingsVector returns the number of epochs per slashings vector. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) EpochsPerSlashingsVector() uint64 { return c.Data.EpochsPerSlashingsVector } // HistoricalRootsLimit returns the limit of historical roots. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) HistoricalRootsLimit() uint64 { return c.Data.HistoricalRootsLimit } // ValidatorRegistryLimit returns the limit of the validator registry. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) ValidatorRegistryLimit() uint64 { return c.Data.ValidatorRegistryLimit } // InactivityPenaltyQuotient returns the inactivity penalty quotient. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) InactivityPenaltyQuotient() uint64 { return c.Data.InactivityPenaltyQuotient } // ProportionalSlashingMultiplier returns the proportional slashing multiplier. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) ProportionalSlashingMultiplier() uint64 { return c.Data.ProportionalSlashingMultiplier } @@ -488,7 +505,7 @@ func (c chainSpec[ // MaxWithdrawalsPerPayload returns the maximum number of withdrawals per // payload. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MaxWithdrawalsPerPayload() uint64 { return c.Data.MaxWithdrawalsPerPayload } @@ -496,7 +513,7 @@ func (c chainSpec[ // MaxValidatorsPerWithdrawalsSweep returns the maximum number of validators per // withdrawals sweep. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MaxValidatorsPerWithdrawalsSweep(isPostUpgrade bool) uint64 { if isPostUpgrade { return c.Data.MaxValidatorsPerWithdrawalsSweepPostUpgrade @@ -508,7 +525,7 @@ func (c chainSpec[ // MinEpochsForBlobsSidecarsRequest returns the minimum number of epochs for // blobs sidecars request. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MinEpochsForBlobsSidecarsRequest() uint64 { return c.Data.MinEpochsForBlobsSidecarsRequest } @@ -516,28 +533,28 @@ func (c chainSpec[ // MaxBlobCommitmentsPerBlock returns the maximum number of blob commitments per // block. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MaxBlobCommitmentsPerBlock() uint64 { return c.Data.MaxBlobCommitmentsPerBlock } // MaxBlobsPerBlock returns the maximum number of blobs per block. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) MaxBlobsPerBlock() uint64 { return c.Data.MaxBlobsPerBlock } // FieldElementsPerBlob returns the number of field elements per blob. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) FieldElementsPerBlob() uint64 { return c.Data.FieldElementsPerBlob } // BytesPerBlob returns the number of bytes per blob. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) BytesPerBlob() uint64 { return c.Data.BytesPerBlob } @@ -545,31 +562,69 @@ func (c chainSpec[ // GetCometBFTConfigForSlot returns the CometBFT configuration for the given // slot. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) GetCometBFTConfigForSlot(_ SlotT) CometBFTConfigT { return c.Data.CometValues } // ValidatorSetCap retrieves the maximum number of // validators allowed in the active set. -func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, +func (c *chainSpec[ + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) ValidatorSetCap() uint64 { - return c.Data.ValidatorSetCap + currentHeight := c.getCurrentHeight() + params := c.GetParamsForHeight(currentHeight) + return params.ValidatorSetCap } // EVMInflationAddress returns the address on the EVM which will receive the // inflation amount of native EVM balance through a withdrawal every block. func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, -]) EVMInflationAddress() ExecutionAddressT { + DomainTypeT, EpochT, SlotT, CometBFTConfigT, +]) EVMInflationAddress() common.ExecutionAddress { return c.Data.EVMInflationAddress } // EVMInflationPerBlock returns the amount of native EVM balance (in Gwei) to // be minted to the EVMInflationAddress via a withdrawal every block. -func (c chainSpec[ - DomainTypeT, EpochT, ExecutionAddressT, SlotT, CometBFTConfigT, +func (c *chainSpec[ + DomainTypeT, EpochT, SlotT, CometBFTConfigT, ]) EVMInflationPerBlock() uint64 { - return c.Data.EVMInflationPerBlock + currentHeight := c.getCurrentHeight() + params := c.GetParamsForHeight(currentHeight) + return params.EVMInflationPerBlock +} + +// GetParamsForHeight returns the parameters for the specified block height. +func (cs *chainSpec[DT, ET, ST, CT]) GetParamsForHeight(height uint64) HeightDependentParams { + var params HeightDependentParams + + // Find the latest active parameters for the current height + for _, p := range cs.HeightParams { + if p.Height <= height { + params = p + } + } + + // If parameters are not found, use default values + if params.Height == 0 { + params = HeightDependentParams{ + Height: 0, + MaxEffectiveBalance: cs.Data.MaxEffectiveBalancePreUpgrade, + ValidatorSetCap: cs.Data.ValidatorSetCap, + EVMInflationPerBlock: cs.Data.EVMInflationPerBlock, + } + } + + return params +} + +// getCurrentHeight returns the current block height. +func (c *chainSpec[DT, ET, ST, CT]) getCurrentHeight() uint64 { + return c.heightTracker.GetCurrentHeight() +} + +// SetCurrentHeight sets the current block height +func (c *chainSpec[DT, ET, ST, CT]) SetCurrentHeight(height uint64) { + c.heightTracker.SetCurrentHeight(height) } diff --git a/chain-spec/chain/height_tracker.go b/chain-spec/chain/height_tracker.go new file mode 100644 index 0000000000..9aa8ed9461 --- /dev/null +++ b/chain-spec/chain/height_tracker.go @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BUSL-1.1 +// +// Copyright (C) 2024, Berachain Foundation. All rights reserved. +// Use of this software is governed by the Business Source License included +// in the LICENSE file of this repository and at www.mariadb.com/bsl11. + +package chain + +import ( + "sync/atomic" +) + +// heightTracker tracks the current block height. +type heightTracker struct { + currentHeight atomic.Uint64 +} + +// newHeightTracker creates a new instance of heightTracker +func newHeightTracker() *heightTracker { + return &heightTracker{} +} + +// GetCurrentHeight returns the current block height +func (ht *heightTracker) GetCurrentHeight() uint64 { + return ht.currentHeight.Load() +} + +// SetCurrentHeight sets the current block height +func (ht *heightTracker) SetCurrentHeight(height uint64) { + ht.currentHeight.Store(height) +} diff --git a/config/spec/boonet.go b/config/spec/boonet.go index a018549c11..8607b3d2c2 100644 --- a/config/spec/boonet.go +++ b/config/spec/boonet.go @@ -30,7 +30,6 @@ import ( func BoonetChainSpec() (chain.Spec[ common.DomainType, math.Epoch, - common.ExecutionAddress, math.Slot, any, ], error) { @@ -44,22 +43,46 @@ func BoonetChainSpec() (chain.Spec[ "0x289274787bAF083C15A45a174b7a8e44F0720660", ) - // BERA per block minting. + // Basic parameters boonetSpec.EVMInflationPerBlock = 2.5e9 - - // ValidatorSetCap is 256 on the Boonet chain. boonetSpec.ValidatorSetCap = 256 - - // MaxValidatorsPerWithdrawalsSweep is 43 because we expect at least 46 - // validators in the total validators set. We choose a prime number smaller - // than the minimum amount of total validators possible. boonetSpec.MaxValidatorsPerWithdrawalsSweepPostUpgrade = 43 - - // MaxEffectiveBalancePostUpgrade is 5 million BERA after the boonet - // upgrade. - // - //nolint:mnd // ok. boonetSpec.MaxEffectiveBalancePostUpgrade = 5_000_000 * 1e9 - return chain.NewChainSpec(boonetSpec) + spec, err := chain.NewChainSpec(boonetSpec) + if err != nil { + return nil, err + } + + // Adding parameters for different block heights + heightParams := []chain.HeightDependentParams{ + { + Height: 0, + MaxEffectiveBalance: 32e9, + ValidatorSetCap: 256, + EVMInflationPerBlock: 2.5e9, + }, + { + Height: BoonetFork1Height, + MaxEffectiveBalance: 64e9, + ValidatorSetCap: 512, + EVMInflationPerBlock: 3e9, + }, + { + Height: BoonetFork2Height, + MaxEffectiveBalance: 128e9, + ValidatorSetCap: 1024, + EVMInflationPerBlock: 3.5e9, + }, + { + Height: BoonetFork3Height, + MaxEffectiveBalance: 5_000_000 * 1e9, + ValidatorSetCap: 2048, + EVMInflationPerBlock: 4e9, + }, + } + + spec.(*chain.ChainSpec[common.DomainType, math.Epoch, math.Slot, any]).HeightParams = heightParams + + return spec, nil } diff --git a/consensus/cometbft/service/finalize_block.go b/consensus/cometbft/service/finalize_block.go index 3c0c40b925..799d3cf97b 100644 --- a/consensus/cometbft/service/finalize_block.go +++ b/consensus/cometbft/service/finalize_block.go @@ -165,3 +165,15 @@ func (s *Service[_]) validateFinalizeBlockHeight( return nil } + +func (s *Service[LoggerT]) FinalizeBlock( + ctx context.Context, + req *cmtabci.FinalizeBlockRequest, +) (*cmtabci.FinalizeBlockResponse, error) { + // Updating the current block height in the chain specification + if spec, ok := s.Blockchain.ChainSpec().(interface{ SetCurrentHeight(uint64) }); ok { + spec.SetCurrentHeight(uint64(req.Height)) + } + + return s.finalizeBlock(ctx, req) +}