Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianElvis committed Jan 15, 2025
1 parent ac0ac99 commit a76c32c
Show file tree
Hide file tree
Showing 10 changed files with 272 additions and 299 deletions.
32 changes: 16 additions & 16 deletions bbnclient/bbnclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (bbnClient *BabylonClient) QueryAllFpBtcPubKeys(consumerId string) ([]strin
return pkArr, nil
}

func (bbnClient *BabylonClient) QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error) {
func (bbnClient *BabylonClient) QueryFpPower(fpPubkeyHex string, btcHeight uint32) (uint64, error) {
totalPower := uint64(0)
pagination := &sdkquerytypes.PageRequest{}
// queries the BTCStaking module for all delegations of a finality provider
Expand Down Expand Up @@ -74,7 +74,7 @@ func (bbnClient *BabylonClient) QueryFpPower(fpPubkeyHex string, btcHeight uint6

func (bbnClient *BabylonClient) QueryMultiFpPower(
fpPubkeyHexList []string,
btcHeight uint64,
btcHeight uint32,
) (map[string]uint64, error) {
fpPowerMap := make(map[string]uint64)

Expand All @@ -90,13 +90,13 @@ func (bbnClient *BabylonClient) QueryMultiFpPower(
}

// QueryEarliestActiveDelBtcHeight returns the earliest active BTC staking height
func (bbnClient *BabylonClient) QueryEarliestActiveDelBtcHeight(fpPkHexList []string) (uint64, error) {
allFpEarliestDelBtcHeight := uint64(math.MaxUint64)
func (bbnClient *BabylonClient) QueryEarliestActiveDelBtcHeight(fpPkHexList []string) (uint32, error) {
allFpEarliestDelBtcHeight := uint32(math.MaxUint32)

for _, fpPkHex := range fpPkHexList {
fpEarliestDelBtcHeight, err := bbnClient.QueryFpEarliestActiveDelBtcHeight(fpPkHex)
if err != nil {
return math.MaxUint64, err
return math.MaxUint32, err
}
if fpEarliestDelBtcHeight < allFpEarliestDelBtcHeight {
allFpEarliestDelBtcHeight = fpEarliestDelBtcHeight
Expand All @@ -106,40 +106,40 @@ func (bbnClient *BabylonClient) QueryEarliestActiveDelBtcHeight(fpPkHexList []st
return allFpEarliestDelBtcHeight, nil
}

func (bbnClient *BabylonClient) QueryFpEarliestActiveDelBtcHeight(fpPubkeyHex string) (uint64, error) {
func (bbnClient *BabylonClient) QueryFpEarliestActiveDelBtcHeight(fpPubkeyHex string) (uint32, error) {
pagination := &sdkquerytypes.PageRequest{
Limit: 100,
}

// queries the BTCStaking module for all delegations of a finality provider
resp, err := bbnClient.QueryClient.FinalityProviderDelegations(fpPubkeyHex, pagination)
if err != nil {
return math.MaxUint64, err
return math.MaxUint32, err
}

// queries BtcConfirmationDepth, CovenantQuorum, and the latest BTC header
btccheckpointParams, err := bbnClient.QueryClient.BTCCheckpointParams()
if err != nil {
return math.MaxUint64, err
return math.MaxUint32, err
}

// get the BTC staking params
btcstakingParams, err := bbnClient.QueryClient.BTCStakingParams()
if err != nil {
return math.MaxUint64, err
return math.MaxUint32, err
}

// get the latest BTC header
btcHeader, err := bbnClient.QueryClient.BTCHeaderChainTip()
if err != nil {
return math.MaxUint64, err
return math.MaxUint32, err
}

kValue := btccheckpointParams.GetParams().BtcConfirmationDepth
covQuorum := btcstakingParams.GetParams().CovenantQuorum
latestBtcHeight := btcHeader.GetHeader().Height

earliestBtcHeight := uint64(math.MaxUint64)
earliestBtcHeight := uint32(math.MaxUint32)
for {
// btcDels contains all the queried BTC delegations
for _, btcDels := range resp.BtcDelegatorDelegations {
Expand All @@ -166,7 +166,7 @@ func (bbnClient *BabylonClient) QueryFpEarliestActiveDelBtcHeight(fpPubkeyHex st
// https://github.com/babylonlabs-io/babylon-private/blob/3d8f190c9b0c0795f6546806e3b8582de716cd60/x/btcstaking/types/btc_delegation.go#L90-L111
func (bbnClient *BabylonClient) isDelegationActive(
btcDel *bbntypes.BTCDelegationResponse,
btcHeight uint64,
btcHeight uint32,
) (bool, error) {
btccheckpointParams, err := bbnClient.QueryClient.BTCCheckpointParams()
if err != nil {
Expand All @@ -181,7 +181,7 @@ func (bbnClient *BabylonClient) isDelegationActive(
covQuorum := btcstakingParams.GetParams().CovenantQuorum
ud := btcDel.UndelegationResponse

if len(ud.GetDelegatorUnbondingSigHex()) > 0 {
if ud.DelegatorUnbondingInfoResponse == nil {
return false, nil
}

Expand Down Expand Up @@ -217,14 +217,14 @@ func (bbnClient *BabylonClient) isDelegationActive(
// 1) the staking tx is k-deep in Bitcoin, i.e., start_height + k
// 2) it receives a quorum number of covenant committee signatures
//
// return math.MaxUint64 if the delegation is not active
// return math.MaxUint32 if the delegation is not active
//
// Note: the delegation can be unbounded and that's totally fine and shouldn't affect when the chain was activated
func getDelFirstActiveHeight(btcDel *bbntypes.BTCDelegationResponse, latestBtcHeight, kValue uint64, covQuorum uint32) uint64 {
func getDelFirstActiveHeight(btcDel *bbntypes.BTCDelegationResponse, latestBtcHeight, kValue uint32, covQuorum uint32) uint32 {
activationHeight := btcDel.StartHeight + kValue
// not activated yet
if latestBtcHeight < activationHeight || len(btcDel.CovenantSigs) < int(covQuorum) {
return math.MaxUint64
return math.MaxUint32
}
return activationHeight
}
16 changes: 8 additions & 8 deletions btcclient/btcclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type BlockCountResponse struct {
count int64
}

func (c *BitcoinClient) GetBlockCount() (uint64, error) {
func (c *BitcoinClient) GetBlockCount() (uint32, error) {
callForBlockCount := func() (*BlockCountResponse, error) {
count, err := c.client.GetBlockCount()
if err != nil {
Expand All @@ -61,12 +61,12 @@ func (c *BitcoinClient) GetBlockCount() (uint64, error) {
return 0, fmt.Errorf("unexpected negative block count: %d", blockCount.count)
}

return uint64(blockCount.count), nil
return uint32(blockCount.count), nil
}

func (c *BitcoinClient) GetBlockHashByHeight(height uint64) (*chainhash.Hash, error) {
func (c *BitcoinClient) GetBlockHashByHeight(height uint32) (*chainhash.Hash, error) {
callForBlockHash := func() (*chainhash.Hash, error) {
if height > math.MaxInt64 {
if height > math.MaxInt32 {
return nil, fmt.Errorf("block height %d exceeds maximum int64 value", height)
}
return c.client.GetBlockHash(int64(height))
Expand All @@ -93,14 +93,14 @@ func (c *BitcoinClient) GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.B
return header, nil
}

func (c *BitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error) {
func (c *BitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint32, error) {
// get the height of the most-work fully-validated chain
blockHeight, err := c.GetBlockCount()
if err != nil {
return 0, err
}

lowerBound := uint64(0)
lowerBound := uint32(0)
upperBound := blockHeight

for lowerBound <= upperBound {
Expand All @@ -123,13 +123,13 @@ func (c *BitcoinClient) GetBlockHeightByTimestamp(targetTimestamp uint64) (uint6
// timestamp is in the future (not in the most-work fully-validated chain)
// we return the max uint64 to indicate this
if lowerBound > blockHeight {
return math.MaxUint64, nil
return math.MaxUint32, nil
}

return lowerBound - 1, nil
}

func (c *BitcoinClient) GetBlockTimestampByHeight(height uint64) (uint64, error) {
func (c *BitcoinClient) GetBlockTimestampByHeight(height uint32) (uint64, error) {
// get block hash by height
blockHash, err := c.GetBlockHashByHeight(height)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions btcclient/btcclient_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (

// TODO: 1) not rely on mainnet RPC; 2) add more tests for some other edge cases
func TestBtcClient(t *testing.T) {
var blockHeight uint64
var blockHeight uint32
var err error

// Create logger.
Expand All @@ -26,20 +26,20 @@ func TestBtcClient(t *testing.T) {
// timestmap between block 848682 and 848683
blockHeight, err = btc.GetBlockHeightByTimestamp(uint64(1718840690))
require.Nil(t, err)
require.Equal(t, uint64(848682), blockHeight)
require.Equal(t, uint32(848682), blockHeight)

// the exact timestamp of block 848682
blockHeight, err = btc.GetBlockHeightByTimestamp(uint64(1718839311))
require.Nil(t, err)
require.Equal(t, uint64(848682), blockHeight)
require.Equal(t, uint32(848682), blockHeight)

// the exact timestamp minus one of block 848682
blockHeight, err = btc.GetBlockHeightByTimestamp(uint64(1718839310))
require.Nil(t, err)
require.Equal(t, uint64(848681), blockHeight)
require.Equal(t, uint32(848681), blockHeight)

// a timestamp in the future i.e. year 2056
blockHeight, err = btc.GetBlockHeightByTimestamp(uint64(2718840690))
require.Nil(t, err)
require.Equal(t, uint64(math.MaxUint64), blockHeight)
require.Equal(t, uint32(math.MaxUint32), blockHeight)
}
14 changes: 7 additions & 7 deletions finalitygadget/expected_clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ import (
)

type IBitcoinClient interface {
GetBlockCount() (uint64, error)
GetBlockHashByHeight(height uint64) (*chainhash.Hash, error)
GetBlockCount() (uint32, error)
GetBlockHashByHeight(height uint32) (*chainhash.Hash, error)
GetBlockHeaderByHash(blockHash *chainhash.Hash) (*wire.BlockHeader, error)
GetBlockHeightByTimestamp(targetTimestamp uint64) (uint64, error)
GetBlockTimestampByHeight(height uint64) (uint64, error)
GetBlockHeightByTimestamp(targetTimestamp uint64) (uint32, error)
GetBlockTimestampByHeight(height uint32) (uint64, error)
}

type IBabylonClient interface {
QueryAllFpBtcPubKeys(consumerId string) ([]string, error)
QueryFpPower(fpPubkeyHex string, btcHeight uint64) (uint64, error)
QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint64) (map[string]uint64, error)
QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint64, error)
QueryFpPower(fpPubkeyHex string, btcHeight uint32) (uint64, error)
QueryMultiFpPower(fpPubkeyHexList []string, btcHeight uint32) (map[string]uint64, error)
QueryEarliestActiveDelBtcHeight(fpPubkeyHexList []string) (uint32, error)
}

type ICosmWasmClient interface {
Expand Down
12 changes: 3 additions & 9 deletions finalitygadget/finalitygadget.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,18 +226,12 @@ func (fg *FinalityGadget) QueryIsBlockBabylonFinalized(block *types.Block) (bool
return true, nil
}

// convert the L2 timestamp to BTC height
btcblockHeight, err := fg.btcClient.GetBlockHeightByTimestamp(block.BlockTimestamp)
if err != nil {
return false, err
}

// check whether the btc staking is activated
btcStakingActivatedTimestamp, err := fg.QueryBtcStakingActivatedTimestamp()
if err != nil {
return false, err
}
if btcblockHeight < btcStakingActivatedTimestamp {
if block.BlockTimestamp < btcStakingActivatedTimestamp {
return false, types.ErrBtcStakingNotActivated
}

Expand Down Expand Up @@ -741,10 +735,10 @@ func (fg *FinalityGadget) queryBtcStakingActivationTimestamp() (uint64, error) {
if err != nil {
return math.MaxUint64, err
}
if earliestDelHeight == math.MaxUint64 {
if earliestDelHeight == math.MaxUint32 {
return math.MaxUint64, types.ErrBtcStakingNotActivated
}
fg.logger.Debug("Earliest active delegation height", zap.Uint64("height", earliestDelHeight))
fg.logger.Debug("Earliest active delegation height", zap.Uint32("height", earliestDelHeight))

btcBlockTimestamp, err := fg.btcClient.GetBlockTimestampByHeight(earliestDelHeight)
if err != nil {
Expand Down
10 changes: 5 additions & 5 deletions finalitygadget/finalitygadget_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) {
blockWithHashTrimmed.BlockHash = strings.TrimPrefix(blockWithHashUntrimmed.BlockHash, "0x")

const consumerChainID = "consumer-chain-id"
const BTCHeight = uint64(111)
const BTCHeight = uint32(111)

testCases := []struct {
name string
Expand All @@ -58,7 +58,7 @@ func TestQueryIsBlockBabylonFinalized(t *testing.T) {
allFpPks []string
fpPowers map[string]uint64
votedProviders []string
stakingActivationHeight uint64
stakingActivationHeight uint32
expectResult bool
}{
{
Expand Down Expand Up @@ -749,8 +749,8 @@ func TestQueryBtcStakingActivatedTimestamp(t *testing.T) {
mockDbHandler.EXPECT().GetActivatedTimestamp().Return(uint64(0), types.ErrActivatedTimestampNotFound)
mockCwClient.EXPECT().QueryConsumerId().Return("consumer-chain-id", nil)
mockBBNClient.EXPECT().QueryAllFpBtcPubKeys("consumer-chain-id").Return([]string{"pk1", "pk2"}, nil)
mockBBNClient.EXPECT().QueryEarliestActiveDelBtcHeight([]string{"pk1", "pk2"}).Return(uint64(100), nil)
mockBTCClient.EXPECT().GetBlockTimestampByHeight(uint64(100)).Return(uint64(1234567890), nil)
mockBBNClient.EXPECT().QueryEarliestActiveDelBtcHeight([]string{"pk1", "pk2"}).Return(uint32(100), nil)
mockBTCClient.EXPECT().GetBlockTimestampByHeight(uint32(100)).Return(uint64(1234567890), nil)

timestamp, err = mockFinalityGadget.QueryBtcStakingActivatedTimestamp()
require.NoError(t, err)
Expand All @@ -760,7 +760,7 @@ func TestQueryBtcStakingActivatedTimestamp(t *testing.T) {
mockDbHandler.EXPECT().GetActivatedTimestamp().Return(uint64(0), types.ErrActivatedTimestampNotFound)
mockCwClient.EXPECT().QueryConsumerId().Return("consumer-chain-id", nil)
mockBBNClient.EXPECT().QueryAllFpBtcPubKeys("consumer-chain-id").Return([]string{"pk1", "pk2"}, nil)
mockBBNClient.EXPECT().QueryEarliestActiveDelBtcHeight([]string{"pk1", "pk2"}).Return(uint64(math.MaxUint64), nil)
mockBBNClient.EXPECT().QueryEarliestActiveDelBtcHeight([]string{"pk1", "pk2"}).Return(uint32(math.MaxUint32), nil)

timestamp, err = mockFinalityGadget.QueryBtcStakingActivatedTimestamp()
require.Equal(t, types.ErrBtcStakingNotActivated, err)
Expand Down
Loading

0 comments on commit a76c32c

Please sign in to comment.