Skip to content

Commit

Permalink
feat(ADR-024): Introduce epoch number in public randomness commit (#12)
Browse files Browse the repository at this point in the history
  • Loading branch information
gitferry committed Aug 27, 2024
1 parent 9a37d60 commit c806a3d
Show file tree
Hide file tree
Showing 39 changed files with 493 additions and 353 deletions.
2 changes: 1 addition & 1 deletion app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,6 @@ func (ak *AppKeepers) InitKeepers(
runtime.NewKVStoreService(keys[btcstakingtypes.StoreKey]),
&btclightclientKeeper,
&btcCheckpointKeeper,
&checkpointingKeeper,
btcNetParams,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
Expand All @@ -535,6 +534,7 @@ func (ak *AppKeepers) InitKeepers(
runtime.NewKVStoreService(keys[finalitytypes.StoreKey]),
ak.BTCStakingKeeper,
ak.IncentiveKeeper,
ak.CheckpointingKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
ak.BTCStakingKeeper = *ak.BTCStakingKeeper.SetHooks(btcstakingtypes.NewMultiBtcStakingHooks(ak.FinalityKeeper.Hooks()))
Expand Down
2 changes: 2 additions & 0 deletions proto/babylon/finality/v1/finality.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ message PubRandCommit {
// commitment is the value of the commitment
// currently, it is the root of the merkle tree constructed by the public randomness
bytes commitment = 3;
// epoch_num defines the epoch number that the commit falls into
uint64 epoch_num = 4;
}

// Evidence is the evidence that a finality provider has signed finality
Expand Down
2 changes: 2 additions & 0 deletions proto/babylon/finality/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ message PubRandCommitResponse {
uint64 num_pub_rand = 1;
// commitment is the value of the commitment
bytes commitment = 2;
// epoch_num defines the epoch number that the commit falls into
uint64 epoch_num = 3;
}

// QueryListPubRandCommitRequest is the request type for the
Expand Down
61 changes: 40 additions & 21 deletions test/e2e/btc_staking_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
bbn "github.com/babylonlabs-io/babylon/types"
btcctypes "github.com/babylonlabs-io/babylon/x/btccheckpoint/types"
bstypes "github.com/babylonlabs-io/babylon/x/btcstaking/types"
ckpttypes "github.com/babylonlabs-io/babylon/x/checkpointing/types"
ftypes "github.com/babylonlabs-io/babylon/x/finality/types"
itypes "github.com/babylonlabs-io/babylon/x/incentive/types"
)
Expand Down Expand Up @@ -272,6 +273,8 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat
// get activated height
activatedHeight := nonValidatorNode.QueryActivatedHeight()
s.Positive(activatedHeight)
_, err = nonValidatorNode.QueryCurrentHeight()
s.NoError(err)

/*
commit a number of public randomness since activatedHeight
Expand All @@ -288,23 +291,47 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat
msgCommitPubRandList.Sig,
)

// no reward gauge for finality provider and delegation yet
fpBabylonAddr, err := sdk.AccAddressFromBech32(cacheFP.Addr)
s.NoError(err)

_, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr)
s.ErrorContains(err, itypes.ErrRewardGaugeNotFound.Error())
delBabylonAddr := fpBabylonAddr

// finalize epochs from 1 to the current epoch
currentEpoch, err := nonValidatorNode.QueryCurrentEpoch()
s.NoError(err)

// wait until the end epoch is sealed
s.Eventually(func() bool {
resp, err := nonValidatorNode.QueryRawCheckpoint(currentEpoch)
if err != nil {
return false
}
return resp.Status == ckpttypes.Sealed
}, time.Minute, time.Second*5)
nonValidatorNode.FinalizeSealedEpochs(1, currentEpoch)
lastFinalizedEpoch := uint64(0)

// ensure the committed epoch is finalized
s.Eventually(func() bool {
lastFinalizedEpoch, err = nonValidatorNode.QueryLastFinalizedEpoch()
if err != nil {
return false
}
return lastFinalizedEpoch >= currentEpoch
}, time.Minute, time.Second)

// ensure public randomness list is eventually committed
nonValidatorNode.WaitForNextBlock()
var prCommitMap map[uint64]*ftypes.PubRandCommitResponse
s.Eventually(func() bool {
prCommitMap = nonValidatorNode.QueryListPubRandCommit(cacheFP.BtcPk)
return len(prCommitMap) > 0
}, time.Minute, time.Second*5)
s.Equal(prCommitMap[activatedHeight].NumPubRand, msgCommitPubRandList.NumPubRand)
s.Equal(prCommitMap[activatedHeight].Commitment, msgCommitPubRandList.Commitment)

// no reward gauge for finality provider and delegation yet
fpBabylonAddr, err := sdk.AccAddressFromBech32(cacheFP.Addr)
s.NoError(err)

_, err = nonValidatorNode.QueryRewardGauge(fpBabylonAddr)
s.ErrorContains(err, itypes.ErrRewardGaugeNotFound.Error())
delBabylonAddr := fpBabylonAddr
s.LessOrEqual(prCommitMap[activatedHeight].EpochNum, lastFinalizedEpoch)

/*
submit finality signature
Expand All @@ -324,20 +351,12 @@ func (s *BTCStakingTestSuite) Test3CommitPublicRandomnessAndSubmitFinalitySignat
nonValidatorNode.AddFinalitySig(cacheFP.BtcPk, activatedHeight, &randListInfo.PRList[idx], *randListInfo.ProofList[idx].ToProto(), appHash, eotsSig)

// ensure vote is eventually cast
nonValidatorNode.WaitForNextBlock()
var votes []bbn.BIP340PubKey
var finalizedBlocks []*ftypes.IndexedBlock
s.Eventually(func() bool {
votes = nonValidatorNode.QueryVotesAtHeight(activatedHeight)
return len(votes) > 0
finalizedBlocks = nonValidatorNode.QueryListBlocks(ftypes.QueriedBlockStatus_FINALIZED)
return len(finalizedBlocks) > 0
}, time.Minute, time.Second*5)
s.Equal(1, len(votes))
s.Equal(votes[0].MarshalHex(), cacheFP.BtcPk.MarshalHex())
// once the vote is cast, ensure block is finalised
finalizedBlock := nonValidatorNode.QueryIndexedBlock(activatedHeight)
s.NotEmpty(finalizedBlock)
s.Equal(appHash.Bytes(), finalizedBlock.AppHash)
finalizedBlocks := nonValidatorNode.QueryListBlocks(ftypes.QueriedBlockStatus_FINALIZED)
s.NotEmpty(finalizedBlocks)
s.Equal(activatedHeight, finalizedBlocks[0].Height)
s.Equal(appHash.Bytes(), finalizedBlocks[0].AppHash)

// ensure finality provider has received rewards after the block is finalised
Expand Down
17 changes: 16 additions & 1 deletion test/e2e/configurer/chain/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ func (n *NodeConfig) QueryListSnapshots() ([]*cmtabcitypes.Snapshot, error) {
func (n *NodeConfig) QueryRawCheckpoint(epoch uint64) (*ct.RawCheckpointWithMetaResponse, error) {
path := fmt.Sprintf("babylon/checkpointing/v1/raw_checkpoint/%d", epoch)
bz, err := n.QueryGRPCGateway(path, url.Values{})
require.NoError(n.t, err)
if err != nil {
return nil, err
}

var checkpointingResponse ct.QueryRawCheckpointResponse
if err := util.Cdc.UnmarshalJSON(bz, &checkpointingResponse); err != nil {
Expand Down Expand Up @@ -208,6 +210,19 @@ func (n *NodeConfig) QueryRawCheckpoints(pagination *query.PageRequest) (*ct.Que
return &checkpointingResponse, nil
}

func (n *NodeConfig) QueryLastFinalizedEpoch() (uint64, error) {
queryParams := url.Values{}
queryParams.Add("status", fmt.Sprintf("%d", ct.Finalized))

bz, err := n.QueryGRPCGateway(fmt.Sprintf("/babylon/checkpointing/v1/last_raw_checkpoint/%d", ct.Finalized), queryParams)
require.NoError(n.t, err)
var res ct.QueryLastCheckpointWithStatusResponse
if err := util.Cdc.UnmarshalJSON(bz, &res); err != nil {
return 0, err
}
return res.RawCheckpoint.EpochNum, nil
}

func (n *NodeConfig) QueryBtcBaseHeader() (*blc.BTCHeaderInfoResponse, error) {
bz, err := n.QueryGRPCGateway("babylon/btclightclient/v1/baseheader", url.Values{})
require.NoError(n.t, err)
Expand Down
2 changes: 0 additions & 2 deletions testutil/keeper/btcstaking.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ func BTCStakingKeeper(
t testing.TB,
btclcKeeper types.BTCLightClientKeeper,
btccKeeper types.BtcCheckpointKeeper,
ckptKeeper types.CheckpointingKeeper,
) (*keeper.Keeper, sdk.Context) {
storeKey := storetypes.NewKVStoreKey(types.StoreKey)

Expand All @@ -44,7 +43,6 @@ func BTCStakingKeeper(
runtime.NewKVStoreService(storeKey),
btclcKeeper,
btccKeeper,
ckptKeeper,
&chaincfg.SimNetParams,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
Expand Down
3 changes: 2 additions & 1 deletion testutil/keeper/finality.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/babylonlabs-io/babylon/x/finality/types"
)

func FinalityKeeper(t testing.TB, bsKeeper types.BTCStakingKeeper, iKeeper types.IncentiveKeeper) (*keeper.Keeper, sdk.Context) {
func FinalityKeeper(t testing.TB, bsKeeper types.BTCStakingKeeper, iKeeper types.IncentiveKeeper, cKeeper types.CheckpointingKeeper) (*keeper.Keeper, sdk.Context) {
storeKey := storetypes.NewKVStoreKey(types.StoreKey)

db := dbm.NewMemDB()
Expand All @@ -38,6 +38,7 @@ func FinalityKeeper(t testing.TB, bsKeeper types.BTCStakingKeeper, iKeeper types
runtime.NewKVStoreService(storeKey),
bsKeeper,
iKeeper,
cKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)

Expand Down
5 changes: 3 additions & 2 deletions x/btcstaking/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package btcstaking_test
import (
"testing"

"github.com/stretchr/testify/require"

keepertest "github.com/babylonlabs-io/babylon/testutil/keeper"
"github.com/babylonlabs-io/babylon/testutil/nullify"
"github.com/babylonlabs-io/babylon/x/btcstaking"
"github.com/babylonlabs-io/babylon/x/btcstaking/types"
"github.com/stretchr/testify/require"
)

func TestGenesis(t *testing.T) {
Expand All @@ -16,7 +17,7 @@ func TestGenesis(t *testing.T) {
Params: []*types.Params{&p},
}

k, ctx := keepertest.BTCStakingKeeper(t, nil, nil, nil)
k, ctx := keepertest.BTCStakingKeeper(t, nil, nil)
btcstaking.InitGenesis(ctx, *k, genesisState)
got := btcstaking.ExportGenesis(ctx, *k)
require.NotNil(t, got)
Expand Down
6 changes: 3 additions & 3 deletions x/btcstaking/keeper/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import (
"testing"
"time"

"github.com/golang/mock/gomock"

"github.com/babylonlabs-io/babylon/testutil/datagen"
btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types"
bsmodule "github.com/babylonlabs-io/babylon/x/btcstaking"
"github.com/babylonlabs-io/babylon/x/btcstaking/types"
"github.com/golang/mock/gomock"
)

func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) {
Expand All @@ -23,8 +24,7 @@ func benchBeginBlock(b *testing.B, numFPs int, numDelsUnderFP int) {
defer ctrl.Finish()
btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl)
btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl)
ckptKeeper := types.NewMockCheckpointingKeeper(ctrl)
h := NewHelper(b, btclcKeeper, btccKeeper, ckptKeeper)
h := NewHelper(b, btclcKeeper, btccKeeper)
// set all parameters
covenantSKs, _ := h.GenAndApplyParams(r)
changeAddress, err := datagen.GenRandomBTCAddress(r, h.Net)
Expand Down
7 changes: 4 additions & 3 deletions x/btcstaking/keeper/btc_height_index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import (
"math/rand"
"testing"

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"

"github.com/babylonlabs-io/babylon/testutil/datagen"
keepertest "github.com/babylonlabs-io/babylon/testutil/keeper"
btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types"
"github.com/babylonlabs-io/babylon/x/btcstaking/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
)

func FuzzBTCHeightIndex(f *testing.F) {
Expand All @@ -22,7 +23,7 @@ func FuzzBTCHeightIndex(f *testing.F) {

// mock BTC light client
btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl)
keeper, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, nil, nil)
keeper, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, nil)

// randomise Babylon height and BTC height
babylonHeight := datagen.RandomInt(r, 100)
Expand Down
19 changes: 8 additions & 11 deletions x/btcstaking/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func FuzzActivatedHeight(f *testing.F) {
r := rand.New(rand.NewSource(seed))

// Setup keeper and context
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil)
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil)
ctx = sdk.UnwrapSDKContext(ctx)

// not activated yet
Expand All @@ -51,7 +51,7 @@ func FuzzFinalityProviders(f *testing.F) {
r := rand.New(rand.NewSource(seed))

// Setup keeper and context
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil)
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil)
ctx = sdk.UnwrapSDKContext(ctx)

// Generate random finality providers and add them to kv store
Expand Down Expand Up @@ -116,7 +116,7 @@ func FuzzFinalityProvider(f *testing.F) {
f.Fuzz(func(t *testing.T, seed int64) {
r := rand.New(rand.NewSource(seed))
// Setup keeper and context
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil)
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil)
ctx = sdk.UnwrapSDKContext(ctx)

// Generate random finality providers and add them to kv store
Expand Down Expand Up @@ -172,8 +172,7 @@ func FuzzPendingBTCDelegations(f *testing.F) {
btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl)
btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl)
btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes()
ckptKeeper := types.NewMockCheckpointingKeeper(ctrl)
keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper)
keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper)

// covenant and slashing addr
covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r)
Expand Down Expand Up @@ -275,7 +274,7 @@ func FuzzFinalityProviderPowerAtHeight(f *testing.F) {
r := rand.New(rand.NewSource(seed))

// Setup keeper and context
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil)
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil)

// random finality provider
fp, err := datagen.GenRandomFinalityProvider(r)
Expand Down Expand Up @@ -324,7 +323,7 @@ func FuzzFinalityProviderCurrentVotingPower(f *testing.F) {
r := rand.New(rand.NewSource(seed))

// Setup keeper and context
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil, nil)
keeper, ctx := testkeeper.BTCStakingKeeper(t, nil, nil)

// random finality provider
fp, err := datagen.GenRandomFinalityProvider(r)
Expand Down Expand Up @@ -376,8 +375,7 @@ func FuzzActiveFinalityProvidersAtHeight(f *testing.F) {
btclcKeeper.EXPECT().GetTipInfo(gomock.Any()).Return(&btclctypes.BTCHeaderInfo{Height: 10}).AnyTimes()
btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl)
btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes()
ckptKeeper := types.NewMockCheckpointingKeeper(ctrl)
keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper)
keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper)

// covenant and slashing addr
covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r)
Expand Down Expand Up @@ -496,8 +494,7 @@ func FuzzFinalityProviderDelegations(f *testing.F) {
btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl)
btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl)
btccKeeper.EXPECT().GetParams(gomock.Any()).Return(btcctypes.DefaultParams()).AnyTimes()
ckptKeeper := types.NewMockCheckpointingKeeper(ctrl)
keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper, ckptKeeper)
keeper, ctx := testkeeper.BTCStakingKeeper(t, btclcKeeper, btccKeeper)

// covenant and slashing addr
covenantSKs, covenantPKs, covenantQuorum := datagen.GenCovenantCommittee(r)
Expand Down
3 changes: 1 addition & 2 deletions x/btcstaking/keeper/incentive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ func FuzzRecordVotingPowerDistCache(f *testing.F) {
// mock BTC light client and BTC checkpoint modules
btclcKeeper := types.NewMockBTCLightClientKeeper(ctrl)
btccKeeper := types.NewMockBtcCheckpointKeeper(ctrl)
ckptKeeper := types.NewMockCheckpointingKeeper(ctrl)
h := NewHelper(t, btclcKeeper, btccKeeper, ckptKeeper)
h := NewHelper(t, btclcKeeper, btccKeeper)

// set all parameters
covenantSKs, _ := h.GenAndApplyParams(r)
Expand Down
7 changes: 0 additions & 7 deletions x/btcstaking/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ type (

btclcKeeper types.BTCLightClientKeeper
btccKeeper types.BtcCheckpointKeeper
ckptKeeper types.CheckpointingKeeper

hooks types.BtcStakingHooks

Expand All @@ -38,7 +37,6 @@ func NewKeeper(

btclcKeeper types.BTCLightClientKeeper,
btccKeeper types.BtcCheckpointKeeper,
ckptKeeper types.CheckpointingKeeper,

btcNet *chaincfg.Params,
authority string,
Expand All @@ -49,7 +47,6 @@ func NewKeeper(

btclcKeeper: btclcKeeper,
btccKeeper: btccKeeper,
ckptKeeper: ckptKeeper,

hooks: nil,

Expand Down Expand Up @@ -86,7 +83,3 @@ func (k Keeper) BeginBlocker(ctx context.Context) error {

return nil
}

func (k Keeper) GetLastFinalizedEpoch(ctx context.Context) uint64 {
return k.ckptKeeper.GetLastFinalizedEpoch(ctx)
}
Loading

0 comments on commit c806a3d

Please sign in to comment.