Skip to content

Commit

Permalink
feat: check BTC staking activation height instead of relying on votin…
Browse files Browse the repository at this point in the history
  • Loading branch information
bap2pecs authored Jul 31, 2024
1 parent 0d2a0da commit 41fcda1
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 34 deletions.
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.21

require (
github.com/andybalholm/brotli v1.1.0
github.com/babylonchain/babylon-finality-gadget v0.1.3-alpha.0.20240725201932-fe0411e65930
github.com/babylonlabs-io/babylon-finality-gadget v0.0.0-20240731203740-07d2ddabc4fb
github.com/btcsuite/btcd v0.24.2
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0
github.com/cockroachdb/pebble v1.1.0
Expand Down Expand Up @@ -74,7 +74,7 @@ require (
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/99designs/keyring v1.2.1 // indirect
github.com/CosmWasm/wasmd v0.51.0 // indirect
github.com/CosmWasm/wasmvm/v2 v2.0.0 // indirect
github.com/CosmWasm/wasmvm/v2 v2.0.1 // indirect
github.com/DataDog/datadog-go v3.2.0+incompatible // indirect
github.com/DataDog/zstd v1.5.5 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
Expand Down Expand Up @@ -106,7 +106,7 @@ require (
github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect
github.com/cockroachdb/redact v1.1.5 // indirect
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect
github.com/cometbft/cometbft v0.38.6 // indirect
github.com/cometbft/cometbft v0.38.7 // indirect
github.com/cometbft/cometbft-db v0.9.1 // indirect
github.com/consensys/bavard v0.1.13 // indirect
github.com/containerd/cgroups v1.1.0 // indirect
Expand All @@ -120,7 +120,7 @@ require (
github.com/cosmos/gogoproto v1.4.12 // indirect
github.com/cosmos/iavl v1.1.2 // indirect
github.com/cosmos/ibc-go/modules/capability v1.0.0 // indirect
github.com/cosmos/ibc-go/v8 v8.2.0 // indirect
github.com/cosmos/ibc-go/v8 v8.3.0 // indirect
github.com/cosmos/ics23/go v0.10.0 // indirect
github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect
github.com/cosmos/relayer/v2 v2.5.2 // indirect
Expand Down Expand Up @@ -378,7 +378,7 @@ require (
)

replace (
github.com/babylonchain/babylon => github.com/babylonchain/babylon-private v0.8.6-0.20240705135310-e91ff7f60ead
github.com/babylonchain/babylon => github.com/babylonlabs-io/babylon-private v0.9.0-rc.2.0.20240717044248-3d8f190c9b0c
github.com/cockroachdb/pebble => github.com/cockroachdb/pebble v0.0.0-20231018212520-f6cde3fc2fa4
github.com/ethereum/go-ethereum => github.com/ethereum-optimism/op-geth v1.101315.3-rc.1
github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
Expand Down
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,8 @@ github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/CosmWasm/wasmd v0.51.0 h1:3A2o20RrdF7P1D3Xb+R7A/pHbbHWsYCDXrHLa7S0SC8=
github.com/CosmWasm/wasmd v0.51.0/go.mod h1:7TSaj5HoolghujuVWeExqmcUKgpcYWEySGLSODbnnwY=
github.com/CosmWasm/wasmvm/v2 v2.0.0 h1:IqNCI2G0mvs7K6ej17/I28805rVqnu+Y1cWDqIdwb08=
github.com/CosmWasm/wasmvm/v2 v2.0.0/go.mod h1:su9lg5qLr7adV95eOfzjZWkGiky8WNaNIHDr7Fpu7Ck=
github.com/CosmWasm/wasmvm/v2 v2.0.1 h1:0YCQ7MKGNri7NFeRp75erPJXrqyCtH4gdc9jMstyMzk=
github.com/CosmWasm/wasmvm/v2 v2.0.1/go.mod h1:su9lg5qLr7adV95eOfzjZWkGiky8WNaNIHDr7Fpu7Ck=
github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dXCilEuNEeAn20fdD4=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
Expand Down Expand Up @@ -292,10 +292,10 @@ github.com/aws/aws-sdk-go v1.44.122/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX
github.com/aws/aws-sdk-go v1.44.312 h1:llrElfzeqG/YOLFFKjg1xNpZCFJ2xraIi3PqSuP+95k=
github.com/aws/aws-sdk-go v1.44.312/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
github.com/babylonchain/babylon-finality-gadget v0.1.3-alpha.0.20240725201932-fe0411e65930 h1:AEhnrx3+H30mTwGDYSwNHP/DbbH1+QgHU5KC8TW6+oY=
github.com/babylonchain/babylon-finality-gadget v0.1.3-alpha.0.20240725201932-fe0411e65930/go.mod h1:RG4+gysH91XhqxvmJf2uDtLtFHNZNW3Jg8BkjKdnGvA=
github.com/babylonchain/babylon-private v0.8.6-0.20240705135310-e91ff7f60ead h1:LyyrFtdSbx0a5ZLHA/qMNMjAxZltfnNJgj5+uEgqZdI=
github.com/babylonchain/babylon-private v0.8.6-0.20240705135310-e91ff7f60ead/go.mod h1:Tdi+29Y+DzCaaz0V0sBRXF1tXXLnH6JHJsOG8uktWLU=
github.com/babylonlabs-io/babylon-finality-gadget v0.0.0-20240731203740-07d2ddabc4fb h1:p5y2YqO6y7ORPiJ/L3v1FPb3RKwXjkbuVq6jnI8LlL4=
github.com/babylonlabs-io/babylon-finality-gadget v0.0.0-20240731203740-07d2ddabc4fb/go.mod h1:JDmZ9JfYh0DgYs6r6mxEonRNDN+0XQf/7RErIbg/sH0=
github.com/babylonlabs-io/babylon-private v0.9.0-rc.2.0.20240717044248-3d8f190c9b0c h1:9TT1e9+OheEOU/7B6Uaz5RiYCUtSX7LokayNfkYzFdE=
github.com/babylonlabs-io/babylon-private v0.9.0-rc.2.0.20240717044248-3d8f190c9b0c/go.mod h1:eVovUiLvCvHRpXV7f8KzC4FND1UryaZmZc3bEdBvB8w=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
Expand Down Expand Up @@ -406,8 +406,8 @@ github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZ
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo=
github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI=
github.com/cometbft/cometbft v0.38.6 h1:QSgpCzrGWJ2KUq1qpw+FCfASRpE27T6LQbfEHscdyOk=
github.com/cometbft/cometbft v0.38.6/go.mod h1:8rSPxzUJYquCN8uuBgbUHOMg2KAwvr7CyUw+6ukO4nw=
github.com/cometbft/cometbft v0.38.7 h1:ULhIOJ9+LgSy6nLekhq9ae3juX3NnQUMMPyVdhZV6Hk=
github.com/cometbft/cometbft v0.38.7/go.mod h1:HIyf811dFMI73IE0F7RrnY/Fr+d1+HuJAgtkEpQjCMY=
github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M=
github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U=
github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ=
Expand Down Expand Up @@ -447,8 +447,8 @@ github.com/cosmos/iavl v1.1.2 h1:zL9FK7C4L/P4IF1Dm5fIwz0WXCnn7Bp1M2FxH0ayM7Y=
github.com/cosmos/iavl v1.1.2/go.mod h1:jLeUvm6bGT1YutCaL2fIar/8vGUE8cPZvh/gXEWDaDM=
github.com/cosmos/ibc-go/modules/capability v1.0.0 h1:r/l++byFtn7jHYa09zlAdSeevo8ci1mVZNO9+V0xsLE=
github.com/cosmos/ibc-go/modules/capability v1.0.0/go.mod h1:D81ZxzjZAe0ZO5ambnvn1qedsFQ8lOwtqicG6liLBco=
github.com/cosmos/ibc-go/v8 v8.2.0 h1:7oCzyy1sZCcgpeQLnHxC56brsSz3KWwQGKXalXwXFzE=
github.com/cosmos/ibc-go/v8 v8.2.0/go.mod h1:wj3qx75iC/XNnsMqbPDCIGs0G6Y3E/lo3bdqCyoCy+8=
github.com/cosmos/ibc-go/v8 v8.3.0 h1:fdW2S7NjZYFhSwmCaFjjyDv80kI1ePOJDQmco4qrnD0=
github.com/cosmos/ibc-go/v8 v8.3.0/go.mod h1:izwHZvn9lKrBn8xWj0aXWut6HKcwHMPD3uyuvOJoPSA=
github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM=
github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0=
github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM=
Expand Down
52 changes: 35 additions & 17 deletions op-node/rollup/finality/finalizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import (
"github.com/ethereum-optimism/optimism/op-node/rollup/engine"
"github.com/ethereum-optimism/optimism/op-service/eth"

"github.com/babylonchain/babylon-finality-gadget/sdk/btcclient"
sdkclient "github.com/babylonchain/babylon-finality-gadget/sdk/client"
sdkcfg "github.com/babylonchain/babylon-finality-gadget/sdk/config"
"github.com/babylonchain/babylon-finality-gadget/sdk/cwclient"
"github.com/babylonlabs-io/babylon-finality-gadget/sdk/btcclient"
sdkclient "github.com/babylonlabs-io/babylon-finality-gadget/sdk/client"
sdkcfg "github.com/babylonlabs-io/babylon-finality-gadget/sdk/config"
"github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient"
)

// defaultFinalityLookback defines the amount of L1<>L2 relations to track for finalization purposes, one per L1 block.
Expand Down Expand Up @@ -77,6 +77,7 @@ type FinalizerL2Interface interface {

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

type Finalizer struct {
Expand Down Expand Up @@ -239,14 +240,21 @@ func (fi *Finalizer) tryFinalize() {
fi.mu.Lock()
defer fi.mu.Unlock()

gadgetActivatedTimestamp, err := fi.babylonFinalityClient.QueryBtcStakingActivatedTimestamp()
if err != nil && !errors.Is(err, sdkclient.ErrBtcStakingNotActivated) {
fi.emitter.Emit(rollup.CriticalErrorEvent{Err: fmt.Errorf("failed to query BTC staking activated timestamp: %w", err)})
return
}

// overwritten if we finalize
finalizedL2 := fi.lastFinalizedL2 // may be zeroed if nothing was finalized since startup.
var finalizedDerivedFrom eth.BlockID
// go through the latest inclusion data, and find the last L2 block that was derived from a finalized L1 block
fi.log.Debug("try finalize", "finality_data", fi.finalityData, "last_finalized_l2", finalizedL2)
for _, fd := range fi.finalityData {
if fd.L2Block.Number > finalizedL2.Number && fd.L1Block.Number <= fi.finalizedL1.Number {
lastFinalizedBlock := fi.findLastFinalizedL2BlockWithConsecutiveQuorom(fd.L2Block.Number, finalizedL2.Number)
lastFinalizedBlock := fi.findLastBtcFinalizedL2Block(
fd.L2Block.Number, finalizedL2.Number, gadgetActivatedTimestamp)

// set finalized block(s)
if lastFinalizedBlock != nil {
Expand Down Expand Up @@ -297,7 +305,7 @@ func (fi *Finalizer) tryFinalize() {
}

/*
* findLastFinalizedL2BlockWithConsecutiveQuorom tries to find the last finalized L2 block with consecutive quorom
* findLastBtcFinalizedL2Block tries to find the last finalized L2 block with consecutive quorom
*
* If there are any L2 blocks that are not finalized, then we can't finalize the later ones.
* This is because we need to finalize the L2 blocks in order to guarantee consecutive quorom.
Expand All @@ -310,13 +318,15 @@ func (fi *Finalizer) tryFinalize() {
*
* If there is an error, it returns immediately with the last finalized L2 block that has no error.
*/
func (fi *Finalizer) findLastFinalizedL2BlockWithConsecutiveQuorom(
func (fi *Finalizer) findLastBtcFinalizedL2Block(
fdL2BlockNumber uint64, // candidate L2 block number to finalize
finalizedL2Number uint64, // last finalized L2 block number
gadgetActivatedTimestamp uint64, // BTC staking activated timestamp
) *eth.L2BlockRef {
blockCount := int(fdL2BlockNumber - finalizedL2Number)
l2Blocks := make(map[uint64]eth.L2BlockRef)
queryBlocks := make([]*cwclient.L2Block, blockCount)
queryBlocks := make([]*cwclient.L2Block, 0, blockCount)
var largestNonActivatedBlock *eth.L2BlockRef

for i := 0; i < blockCount; i++ {
blockNumber := uint64(i) + finalizedL2Number + uint64(1)
Expand All @@ -333,11 +343,17 @@ func (fi *Finalizer) findLastFinalizedL2BlockWithConsecutiveQuorom(
}
l2Blocks[blockNumber] = l2Block

queryBlocks[i] = &cwclient.L2Block{
// only query blocks after the gadget is activated
if l2Block.Time < gadgetActivatedTimestamp {
largestNonActivatedBlock = &l2Block
continue
}

queryBlocks = append(queryBlocks, &cwclient.L2Block{
BlockHeight: l2Block.Number,
BlockHash: l2Block.Hash.String(),
BlockTimestamp: l2Block.Time,
}
})
fi.log.Debug(
"added block to babylon gadget's query params",
"block_height", queryBlocks[i].BlockHeight,
Expand All @@ -346,12 +362,15 @@ func (fi *Finalizer) findLastFinalizedL2BlockWithConsecutiveQuorom(
)
}

// btc staking is not activated yet, so we don't need to check quorum to finalize the blocks
if len(queryBlocks) == 0 {
return largestNonActivatedBlock
}

lastFinalizedBlockNumber, err := fi.babylonFinalityClient.QueryBlockRangeBabylonFinalized(queryBlocks)
fi.log.Debug("QueryBlockRangeBabylonFinalized", "lastFinalizedBlockNumber", lastFinalizedBlockNumber)

// TODO: we shouldn't skip on no voting power.
// https://github.com/babylonchain/babylon-finality-gadget/issues/59
if err != nil && !errors.Is(err, sdkclient.ErrNoFpHasVotingPower) {
if err != nil {
// on CriticalError, the chain will get stuck because
// op-e2e/actions/l2_verifier.go will detect it and panic
fi.emitter.Emit(rollup.CriticalErrorEvent{Err: fmt.Errorf(
Expand All @@ -363,11 +382,10 @@ func (fi *Finalizer) findLastFinalizedL2BlockWithConsecutiveQuorom(
}

if lastFinalizedBlockNumber != nil {
if block, ok := l2Blocks[*lastFinalizedBlockNumber]; ok {
return &block
}
res := l2Blocks[*lastFinalizedBlockNumber]
return &res
}
return nil
return largestNonActivatedBlock
}

// onDerivedSafeBlock buffers the L1 block the safe head was fully derived from,
Expand Down
13 changes: 11 additions & 2 deletions op-node/rollup/finality/finalizer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/log"

"github.com/babylonchain/babylon-finality-gadget/sdk/cwclient"
"github.com/babylonchain/babylon-finality-gadget/testutil/mocks"
"github.com/babylonlabs-io/babylon-finality-gadget/sdk/cwclient"
"github.com/babylonlabs-io/babylon-finality-gadget/testutil/mocks"
"github.com/ethereum-optimism/optimism/op-node/rollup"
"github.com/ethereum-optimism/optimism/op-node/rollup/derive"
"github.com/ethereum-optimism/optimism/op-node/rollup/engine"
Expand Down Expand Up @@ -210,6 +210,7 @@ func TestEngineQueue_Finalize(t *testing.T) {
defer ctl.Finish()
sdkClient := mocks.NewMockISdkClient(ctl)
fi.babylonFinalityClient = sdkClient
mockActivatedTimestamp(sdkClient)
mockQueryBlockRangeBabylonFinalizedWithTimes(sdkClient, 1, refA1, refB0, refB1, refC0, refC1)

// now say C1 was included in D and became the new safe head
Expand Down Expand Up @@ -253,6 +254,7 @@ func TestEngineQueue_Finalize(t *testing.T) {
defer ctl.Finish()
sdkClient := mocks.NewMockISdkClient(ctl)
fi.babylonFinalityClient = sdkClient
mockActivatedTimestamp(sdkClient)
mockQueryBlockRangeBabylonFinalizedWithTimes(sdkClient, 2, refA1, refB0, refB1, refC0, refC1)

// now say C1 was included in D and became the new safe head
Expand Down Expand Up @@ -300,6 +302,7 @@ func TestEngineQueue_Finalize(t *testing.T) {
defer ctl.Finish()
sdkClient := mocks.NewMockISdkClient(ctl)
fi.babylonFinalityClient = sdkClient
mockActivatedTimestamp(sdkClient)

fi.OnEvent(engine.SafeDerivedEvent{Safe: refC1, DerivedFrom: refD})
fi.OnEvent(derive.DeriverIdleEvent{Origin: refD})
Expand Down Expand Up @@ -399,6 +402,7 @@ func TestEngineQueue_Finalize(t *testing.T) {
defer ctl.Finish()
sdkClient := mocks.NewMockISdkClient(ctl)
fi.babylonFinalityClient = sdkClient
mockActivatedTimestamp(sdkClient)
mockQueryBlockRangeBabylonFinalizedWithTimes(sdkClient, 1, refA1, refB0, refB1)

// now say B1 was included in C and became the new safe head
Expand Down Expand Up @@ -442,6 +446,7 @@ func TestEngineQueue_Finalize(t *testing.T) {
ctl := gomock.NewController(t)
defer ctl.Finish()
sdkClient := mocks.NewMockISdkClient(ctl)
mockActivatedTimestamp(sdkClient)
fi.babylonFinalityClient = sdkClient

// now say B1 was included in C and became the new safe head
Expand Down Expand Up @@ -550,3 +555,7 @@ func mockQueryBlockRangeBabylonFinalizedWithTimes(sdkClient *mocks.MockISdkClien
}
sdkClient.EXPECT().QueryBlockRangeBabylonFinalized(queryBlocks).Return(&refs[len(refs)-1].Number, nil).Times(times)
}

func mockActivatedTimestamp(sdkClient *mocks.MockISdkClient) {
sdkClient.EXPECT().QueryBtcStakingActivatedTimestamp().Return(uint64(0), nil).AnyTimes()
}

0 comments on commit 41fcda1

Please sign in to comment.