Skip to content

Commit

Permalink
Merge pull request #7 from babylonlabs-io/feat/finality-gadget-client
Browse files Browse the repository at this point in the history
feat: finality gadget client
  • Loading branch information
parketh authored Aug 8, 2024
2 parents 75f4cdc + d833af3 commit 6a3698f
Show file tree
Hide file tree
Showing 12 changed files with 268 additions and 1,542 deletions.
7 changes: 7 additions & 0 deletions .envrc.example
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ export L1_BLOCK_TIME=12
export L2_CHAIN_ID=42069
export L2_BLOCK_TIME=2

##################################################
# babylon Configuration #
##################################################

# Babylonchain finality gadget
export BBN_FINALITY_GADGET_RPC=

##################################################
# op-node Configuration #
##################################################
Expand Down
153 changes: 2 additions & 151 deletions go.mod

Large diffs are not rendered by default.

1,270 changes: 2 additions & 1,268 deletions go.sum

Large diffs are not rendered by default.

46 changes: 19 additions & 27 deletions op-chain-ops/genesis/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,8 @@ type L2VaultsDeployConfig struct {
L1FeeVaultWithdrawalNetwork WithdrawalNetwork `json:"l1FeeVaultWithdrawalNetwork"`
// SequencerFeeVaultWithdrawalNetwork represents the withdrawal network for the SequencerFeeVault.
SequencerFeeVaultWithdrawalNetwork WithdrawalNetwork `json:"sequencerFeeVaultWithdrawalNetwork"`
// BabylonFinalityGadgetChainID is the Chain ID of the Babylon chain for the Babylon finality gadget
BabylonFinalityGadgetChainID string `json:"babylonFinalityGadgetChainID"`
// BabylonFinalityGadgetContractAddress is the contract address for the Babylon finality gadget on Babylon chain.
BabylonFinalityGadgetContractAddress string `json:"babylonFinalityGadgetContractAddress"`
// BabylonFinalityGadgetBitcoinRpc is the Bitcoin RPC URL for the Babylon finality gadget.
BabylonFinalityGadgetBitcoinRpc string `json:"babylonFinalityGadgetBitcoinRpc"`
// BabylonFinalityGadgetRpc is the RPC URL for the Babylon finality gadget.
BabylonFinalityGadgetRpc string `json:"babylonFinalityGadgetRpc"`
}

var _ ConfigChecker = (*L2VaultsDeployConfig)(nil)
Expand Down Expand Up @@ -870,27 +866,23 @@ func (d *DeployConfig) RollupConfig(l1StartBlock *types.Block, l2GenesisBlockHas
GasLimit: uint64(d.L2GenesisBlockGasLimit),
},
},
BlockTime: d.L2BlockTime,
MaxSequencerDrift: d.MaxSequencerDrift,
SeqWindowSize: d.SequencerWindowSize,
ChannelTimeout: d.ChannelTimeout,
L1ChainID: new(big.Int).SetUint64(d.L1ChainID),
L2ChainID: new(big.Int).SetUint64(d.L2ChainID),
BatchInboxAddress: d.BatchInboxAddress,
DepositContractAddress: d.OptimismPortalProxy,
L1SystemConfigAddress: d.SystemConfigProxy,
RegolithTime: d.RegolithTime(l1StartBlock.Time()),
CanyonTime: d.CanyonTime(l1StartBlock.Time()),
DeltaTime: d.DeltaTime(l1StartBlock.Time()),
EcotoneTime: d.EcotoneTime(l1StartBlock.Time()),
FjordTime: d.FjordTime(l1StartBlock.Time()),
InteropTime: d.InteropTime(l1StartBlock.Time()),
PlasmaConfig: plasma,
BabylonConfig: &rollup.BabylonConfig{
ChainID: d.BabylonFinalityGadgetChainID,
ContractAddress: d.BabylonFinalityGadgetContractAddress,
BitcoinRpc: d.BabylonFinalityGadgetBitcoinRpc,
},
BlockTime: d.L2BlockTime,
MaxSequencerDrift: d.MaxSequencerDrift,
SeqWindowSize: d.SequencerWindowSize,
ChannelTimeout: d.ChannelTimeout,
L1ChainID: new(big.Int).SetUint64(d.L1ChainID),
L2ChainID: new(big.Int).SetUint64(d.L2ChainID),
BatchInboxAddress: d.BatchInboxAddress,
DepositContractAddress: d.OptimismPortalProxy,
L1SystemConfigAddress: d.SystemConfigProxy,
RegolithTime: d.RegolithTime(l1StartBlock.Time()),
CanyonTime: d.CanyonTime(l1StartBlock.Time()),
DeltaTime: d.DeltaTime(l1StartBlock.Time()),
EcotoneTime: d.EcotoneTime(l1StartBlock.Time()),
FjordTime: d.FjordTime(l1StartBlock.Time()),
InteropTime: d.InteropTime(l1StartBlock.Time()),
PlasmaConfig: plasma,
BabylonFinalityGadgetRpc: d.BabylonFinalityGadgetRpc,
}, nil
}

Expand Down
38 changes: 17 additions & 21 deletions op-e2e/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,27 +578,23 @@ func (cfg SystemConfig) Start(t *testing.T, _opts ...SystemConfigOption) (*Syste
L2Time: uint64(cfg.DeployConfig.L1GenesisBlockTimestamp),
SystemConfig: e2eutils.SystemConfigFromDeployConfig(cfg.DeployConfig),
},
BlockTime: cfg.DeployConfig.L2BlockTime,
MaxSequencerDrift: cfg.DeployConfig.MaxSequencerDrift,
SeqWindowSize: cfg.DeployConfig.SequencerWindowSize,
ChannelTimeout: cfg.DeployConfig.ChannelTimeout,
L1ChainID: cfg.L1ChainIDBig(),
L2ChainID: cfg.L2ChainIDBig(),
BatchInboxAddress: cfg.DeployConfig.BatchInboxAddress,
DepositContractAddress: cfg.DeployConfig.OptimismPortalProxy,
L1SystemConfigAddress: cfg.DeployConfig.SystemConfigProxy,
RegolithTime: cfg.DeployConfig.RegolithTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
CanyonTime: cfg.DeployConfig.CanyonTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
DeltaTime: cfg.DeployConfig.DeltaTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
EcotoneTime: cfg.DeployConfig.EcotoneTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
FjordTime: cfg.DeployConfig.FjordTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
InteropTime: cfg.DeployConfig.InteropTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
ProtocolVersionsAddress: cfg.L1Deployments.ProtocolVersionsProxy,
BabylonConfig: &rollup.BabylonConfig{
ChainID: cfg.DeployConfig.BabylonFinalityGadgetChainID,
ContractAddress: cfg.DeployConfig.BabylonFinalityGadgetContractAddress,
BitcoinRpc: cfg.DeployConfig.BabylonFinalityGadgetBitcoinRpc,
},
BlockTime: cfg.DeployConfig.L2BlockTime,
MaxSequencerDrift: cfg.DeployConfig.MaxSequencerDrift,
SeqWindowSize: cfg.DeployConfig.SequencerWindowSize,
ChannelTimeout: cfg.DeployConfig.ChannelTimeout,
L1ChainID: cfg.L1ChainIDBig(),
L2ChainID: cfg.L2ChainIDBig(),
BatchInboxAddress: cfg.DeployConfig.BatchInboxAddress,
DepositContractAddress: cfg.DeployConfig.OptimismPortalProxy,
L1SystemConfigAddress: cfg.DeployConfig.SystemConfigProxy,
RegolithTime: cfg.DeployConfig.RegolithTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
CanyonTime: cfg.DeployConfig.CanyonTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
DeltaTime: cfg.DeployConfig.DeltaTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
EcotoneTime: cfg.DeployConfig.EcotoneTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
FjordTime: cfg.DeployConfig.FjordTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
InteropTime: cfg.DeployConfig.InteropTime(uint64(cfg.DeployConfig.L1GenesisBlockTimestamp)),
ProtocolVersionsAddress: cfg.L1Deployments.ProtocolVersionsProxy,
BabylonFinalityGadgetRpc: cfg.DeployConfig.BabylonFinalityGadgetRpc,
}
}
defaultConfig := makeRollupConfig()
Expand Down
26 changes: 26 additions & 0 deletions op-node/rollup/finality/expected_clients.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package finality

import "github.com/babylonlabs-io/finality-gadget/types"

type IFinalityGadgetClient interface {
/// QueryIsBlockBabylonFinalized checks if the given L2 block is finalized by the Babylon finality gadget
QueryIsBlockBabylonFinalized(block *types.Block) (bool, error)

/// QueryBlockRangeBabylonFinalized searches for a row of consecutive finalized blocks in the block range, and returns
QueryBlockRangeBabylonFinalized(blocks []*types.Block) (*uint64, error)

/// QueryBtcStakingActivatedTimestamp returns the timestamp when the BTC staking is activated
QueryBtcStakingActivatedTimestamp() (uint64, error)

/// QueryIsBlockFinalizedByHeight returns the btc finalization status of a block at given height by querying the local db
QueryIsBlockFinalizedByHeight(height uint64) (bool, error)

/// QueryIsBlockFinalizedByHash returns the btc finalization status of a block at given hash by querying the local db
QueryIsBlockFinalizedByHash(hash string) (bool, error)

/// QueryLatestFinalizedBlock returns the latest finalized block by querying the local db
QueryLatestFinalizedBlock() (*types.Block, error)

// Closes the client
Close() error
}
34 changes: 9 additions & 25 deletions op-node/rollup/finality/finalizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,8 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup/event"
"github.com/ethereum-optimism/optimism/op-service/eth"

"github.com/babylonlabs-io/finality-gadget/sdk/btcclient"
sdkclient "github.com/babylonlabs-io/finality-gadget/sdk/client"
sdkcfg "github.com/babylonlabs-io/finality-gadget/sdk/config"
"github.com/babylonlabs-io/finality-gadget/sdk/cwclient"
fgclient "github.com/babylonlabs-io/finality-gadget/client"
fgtypes "github.com/babylonlabs-io/finality-gadget/types"
)

// defaultFinalityLookback defines the amount of L1<>L2 relations to track for finalization purposes, one per L1 block.
Expand Down Expand Up @@ -76,11 +74,6 @@ type FinalizerL2Interface interface {
L2BlockRefByNumber(context.Context, uint64) (eth.L2BlockRef, error)
}

type BabylonFinalityClient interface {
QueryBlockRangeBabylonFinalized(queryBlocks []*cwclient.L2Block) (*uint64, error)
QueryBtcStakingActivatedTimestamp() (uint64, error)
}

type Finalizer struct {
mu sync.Mutex

Expand Down Expand Up @@ -111,27 +104,18 @@ type Finalizer struct {
l2Fetcher FinalizerL2Interface

// babylonFinalityClient is the Babylon DA SDK client
babylonFinalityClient BabylonFinalityClient
babylonFinalityClient IFinalityGadgetClient
}

func NewFinalizer(ctx context.Context, log log.Logger, cfg *rollup.Config, l1Fetcher FinalizerL1Interface, l2Fetcher FinalizerL2Interface) *Finalizer {
lookback := calcFinalityLookback(cfg)

// Initialize the Babylon Finality client
btcConfig := btcclient.DefaultBTCConfig()
btcConfig.RPCHost = cfg.BabylonConfig.BitcoinRpc
config := &sdkcfg.Config{
ChainID: cfg.BabylonConfig.ChainID,
ContractAddr: cfg.BabylonConfig.ContractAddress,
BTCConfig: btcConfig,
}
// Initialize the Babylon finality gadget client
log.Debug(
"creating Babylon Finality client",
"chain_id", config.ChainID,
"contract_address", config.ContractAddr,
"btc_rpc_host", config.BTCConfig.RPCHost,
"rpc_addr", cfg.BabylonFinalityGadgetRpc,
)
babylonFinalityClient, err := sdkclient.NewClient(config)
babylonFinalityClient, err := fgclient.NewFinalityGadgetGrpcClient(cfg.BabylonFinalityGadgetRpc)
if err != nil {
log.Error("failed to initialize Babylon Finality client", "error", err)
return nil
Expand Down Expand Up @@ -248,7 +232,7 @@ func (fi *Finalizer) tryFinalize() {
defer fi.mu.Unlock()

gadgetActivatedTimestamp, err := fi.babylonFinalityClient.QueryBtcStakingActivatedTimestamp()
if err != nil && !errors.Is(err, sdkclient.ErrBtcStakingNotActivated) {
if err != nil && !errors.Is(err, fgtypes.ErrBtcStakingNotActivated) {
fi.emitter.Emit(rollup.CriticalErrorEvent{Err: fmt.Errorf("failed to query BTC staking activated timestamp: %w", err)})
return
}
Expand Down Expand Up @@ -332,7 +316,7 @@ func (fi *Finalizer) findLastBtcFinalizedL2Block(
) *eth.L2BlockRef {
blockCount := int(fdL2BlockNumber - finalizedL2Number)
l2Blocks := make(map[uint64]eth.L2BlockRef)
queryBlocks := make([]*cwclient.L2Block, 0, blockCount)
queryBlocks := make([]*fgtypes.Block, 0, blockCount)
var largestNonActivatedBlock *eth.L2BlockRef

for i := 0; i < blockCount; i++ {
Expand All @@ -356,7 +340,7 @@ func (fi *Finalizer) findLastBtcFinalizedL2Block(
continue
}

queryBlocks = append(queryBlocks, &cwclient.L2Block{
queryBlocks = append(queryBlocks, &fgtypes.Block{
BlockHeight: l2Block.Number,
BlockHash: l2Block.Hash.String(),
BlockTimestamp: l2Block.Time,
Expand Down
Loading

0 comments on commit 6a3698f

Please sign in to comment.