Skip to content

Commit

Permalink
btcstaking: avoid using ctx in APIs (#172)
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianElvis authored Jan 11, 2024
1 parent f8598a6 commit 5ace728
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 23 deletions.
23 changes: 2 additions & 21 deletions x/btcstaking/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,28 +136,9 @@ func (k Keeper) FinalityProviderCurrentPower(ctx context.Context, req *types.Que
return nil, status.Errorf(codes.InvalidArgument, "failed to unmarshal finality provider BTC PK hex: %v", err)
}

sdkCtx := sdk.UnwrapSDKContext(ctx)
power := uint64(0)
curHeight := uint64(sdkCtx.HeaderInfo().Height)

// if voting power table is recorded at the current height, use this voting power
if k.HasVotingPowerTable(sdkCtx, curHeight) {
power = k.GetVotingPower(sdkCtx, fpBTCPK.MustMarshal(), curHeight)
} else {
// NOTE: it's possible that the voting power is not recorded at the current height,
// e.g., `EndBlock` is not reached yet
// in this case, we use the last height

// ensure curHeight > 0 thus won't over flow
if curHeight == 0 {
return &types.QueryFinalityProviderCurrentPowerResponse{Height: 0, VotingPower: 0}, nil
}

curHeight -= 1
power = k.GetVotingPower(sdkCtx, fpBTCPK.MustMarshal(), curHeight)
}
height, power := k.GetCurrentVotingPower(ctx, *fpBTCPK)

return &types.QueryFinalityProviderCurrentPowerResponse{Height: curHeight, VotingPower: power}, nil
return &types.QueryFinalityProviderCurrentPowerResponse{Height: height, VotingPower: power}, nil
}

// ActiveFinalityProvidersAtHeight returns the active finality providers at the provided height
Expand Down
5 changes: 3 additions & 2 deletions x/btcstaking/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,12 @@ func FuzzFinalityProviderCurrentVotingPower(f *testing.F) {
require.Equal(t, randomHeight, resp.Height)
require.Equal(t, randomPower, resp.VotingPower)

// but no more
// test the case when the finality provider has 0 voting power
ctx = datagen.WithCtxHeight(ctx, randomHeight+2)
keeper.SetVotingPower(ctx, fp.BtcPk.MustMarshal(), randomHeight+2, 0)
resp, err = keeper.FinalityProviderCurrentPower(ctx, req)
require.NoError(t, err)
require.Equal(t, randomHeight+1, resp.Height)
require.Equal(t, randomHeight+2, resp.Height)
require.Equal(t, uint64(0), resp.VotingPower)
})
}
Expand Down
33 changes: 33 additions & 0 deletions x/btcstaking/keeper/voting_power_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,39 @@ func (k Keeper) GetVotingPower(ctx context.Context, fpBTCPK []byte, height uint6
return sdk.BigEndianToUint64(powerBytes)
}

// GetCurrentVotingPower gets the voting power of a given finality provider at the current height
// NOTE: it's possible that the voting power table is 1 block behind CometBFT, e.g., when `BeginBlock`
// hasn't executed yet
func (k Keeper) GetCurrentVotingPower(ctx context.Context, fpBTCPK []byte) (uint64, uint64) {
// find the last recorded voting power table via iterator
storeAdapter := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
store := prefix.NewStore(storeAdapter, types.VotingPowerKey)
iter := store.ReverseIterator(nil, nil)
defer iter.Close()

// no voting power table is known yet, return 0
if !iter.Valid() {
return 0, 0
}

// there is known voting power table, find the last height
lastHeight := sdk.BigEndianToUint64(iter.Key())
storeAtHeight := prefix.NewStore(store, sdk.Uint64ToBigEndian(lastHeight))

// if the finality provider is not known, return 0 voting power
if !k.HasFinalityProvider(ctx, fpBTCPK) {
return lastHeight, 0
}

// find the voting power of this finality provider
powerBytes := storeAtHeight.Get(fpBTCPK)
if len(powerBytes) == 0 {
return lastHeight, 0
}

return lastHeight, sdk.BigEndianToUint64(powerBytes)
}

// HasVotingPowerTable checks if the voting power table exists at a given height
func (k Keeper) HasVotingPowerTable(ctx context.Context, height uint64) bool {
store := k.votingPowerStore(ctx, height)
Expand Down

0 comments on commit 5ace728

Please sign in to comment.