Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

finality: move voting power dist update to finality module #216

Merged
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)

### State Machine Breaking

* [#216](https://github.com/babylonlabs-io/babylon/pull/216) move voting power distribution
update algorithm to `x/finality`
* [#207](https://github.com/babylonlabs-io/babylon/pull/207) Rename total voting power
to total bonded sat

Expand Down
8 changes: 0 additions & 8 deletions app/keepers/keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -496,9 +496,6 @@ func (ak *AppKeepers) InitKeepers(
runtime.NewKVStoreService(keys[btcstakingtypes.StoreKey]),
&btclightclientKeeper,
&btcCheckpointKeeper,
// setting the finality keeper as nil for now
// need to set it after finality keeper is initiated
nil,
&ak.IncentiveKeeper,
btcNetParams,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
Expand All @@ -513,11 +510,6 @@ func (ak *AppKeepers) InitKeepers(
ak.CheckpointingKeeper,
authtypes.NewModuleAddress(govtypes.ModuleName).String(),
)
ak.BTCStakingKeeper = *ak.BTCStakingKeeper.SetHooks(btcstakingtypes.NewMultiBtcStakingHooks(ak.FinalityKeeper.Hooks()))
ak.FinalityKeeper = *ak.FinalityKeeper.SetHooks(finalitytypes.NewMultiFinalityHooks(ak.BTCStakingKeeper.Hooks()))
// TODO this introduces circular dependency between the finality module and
// the btcstaking modules, need refactoring
ak.BTCStakingKeeper.FinalityKeeper = ak.FinalityKeeper

// create evidence keeper with router
evidenceKeeper := evidencekeeper.NewKeeper(
Expand Down
3 changes: 1 addition & 2 deletions app/upgrades/v1/mainnet/btcstaking_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,5 @@ const BtcStakingParamStr = `
"slashing_rate": "0.100000000000000000",
"min_unbonding_time_blocks": 0,
"unbonding_fee_sat": "1000",
"min_commission_rate": "0.03",
"max_active_finality_providers": 100
"min_commission_rate": "0.03"
}`
1 change: 1 addition & 0 deletions app/upgrades/v1/mainnet/finality_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package mainnet
// TODO Some default parameters. Consider how to switch those depending on network:
// mainnet, testnet, devnet etc.
const FinalityParamStr = `{
"max_active_finality_providers": 100,
"signed_blocks_window": 100,
"finality_sig_timeout": 3,
"min_signed_per_window": "0.1",
Expand Down
1 change: 0 additions & 1 deletion app/upgrades/v1/testnet/btcstaking_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,5 @@ const BtcStakingParamStr = `
"min_unbonding_time_blocks": 0,
"unbonding_fee_sat": "1000",
"min_commission_rate": "0.03",
"max_active_finality_providers": 100,
"delegation_creation_base_gas_fee": 1000
}`
1 change: 1 addition & 0 deletions app/upgrades/v1/testnet/finality_params.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package testnet
// TODO Some default parameters. Consider how to switch those depending on network:
// mainnet, testnet, devnet etc.
const FinalityParamStr = `{
"max_active_finality_providers": 100,
"signed_blocks_window": 100,
"finality_sig_timeout": 3,
"min_signed_per_window": "0.1",
Expand Down
2 changes: 1 addition & 1 deletion cmd/babylond/cmd/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,6 @@ func TestnetGenesisParams(
genParams.BtcstakingParams.MinSlashingTxFeeSat = minSlashingFee
genParams.BtcstakingParams.MinCommissionRate = minCommissionRate
genParams.BtcstakingParams.SlashingRate = slashingRate
genParams.BtcstakingParams.MaxActiveFinalityProviders = maxActiveFinalityProviders
genParams.BtcstakingParams.MinUnbondingTimeBlocks = uint32(minUnbondingTime)
genParams.BtcstakingParams.UnbondingFeeSat = unbondingFeeSat
if err := genParams.BtcstakingParams.Validate(); err != nil {
Expand All @@ -434,6 +433,7 @@ func TestnetGenesisParams(
genParams.BlockGasLimit = blockGasLimit
genParams.VoteExtensionsEnableHeight = voteExtensionEnableHeight

genParams.FinalityParams.MaxActiveFinalityProviders = maxActiveFinalityProviders
genParams.FinalityParams.SignedBlocksWindow = signedBlocksWindow
genParams.FinalityParams.MinSignedPerWindow = minSignedPerWindow
genParams.FinalityParams.FinalitySigTimeout = finalitySigTimeout
Expand Down
4 changes: 1 addition & 3 deletions proto/babylon/btcstaking/v1/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,8 @@ message Params {
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
// max_active_finality_providers is the maximum number of active finality providers in the BTC staking protocol
uint32 max_active_finality_providers = 13;
// base gas fee for delegation creation
uint64 delegation_creation_base_gas_fee = 14;
uint64 delegation_creation_base_gas_fee = 13;
}

// StoredParams attach information about the version of stored parameters
Expand Down
13 changes: 8 additions & 5 deletions proto/babylon/finality/v1/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,26 @@ option go_package = "github.com/babylonlabs-io/babylon/x/finality/types";
// Params defines the parameters for the module.
message Params {
option (gogoproto.goproto_stringer) = false;

// max_active_finality_providers is the maximum number of active finality providers in the BTC staking protocol
uint32 max_active_finality_providers = 1;
// signed_blocks_window defines the size of the sliding window for tracking finality provider liveness
int64 signed_blocks_window = 1;
int64 signed_blocks_window = 2;
// finality_sig_timeout defines how much time (in terms of blocks) finality providers have to cast a finality
// vote before being judged as missing their voting turn on the given block
int64 finality_sig_timeout = 2;
int64 finality_sig_timeout = 3;
// min_signed_per_window defines the minimum number of blocks that a finality provider is required to sign
// within the sliding window to avoid being jailed
bytes min_signed_per_window = 3 [
bytes min_signed_per_window = 4 [
(cosmos_proto.scalar) = "cosmos.Dec",
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false,
(amino.dont_omitempty) = true
];
// min_pub_rand is the minimum number of public randomness each
// message should commit
uint64 min_pub_rand = 4;
uint64 min_pub_rand = 5;
// jail_duration is the minimum period of time that a finality provider remains jailed
google.protobuf.Duration jail_duration = 5
google.protobuf.Duration jail_duration = 6
[(gogoproto.nullable) = false, (amino.dont_omitempty) = true, (gogoproto.stdduration) = true];
}
2 changes: 1 addition & 1 deletion test/e2e/configurer/chain/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ func (c *Config) TxGovVoteFromAllNodes(propID int, option govv1.VoteOption, over

// BTCHeaderBytesHexJoined join all the btc headers as byte string hex
func (c *Config) BTCHeaderBytesHexJoined() string {
if c.BTCHeaders == nil || len(c.BTCHeaders) == 0 {
if len(c.BTCHeaders) == 0 {
return ""
}

Expand Down
8 changes: 4 additions & 4 deletions test/e2e/configurer/chain/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ func (n *NodeConfig) FinalizeSealedEpochs(startEpoch uint64, lastEpoch uint64) {
func (n *NodeConfig) StoreWasmCode(wasmFile, from string) {
n.LogActionF("storing wasm code from file %s", wasmFile)
cmd := []string{"babylond", "tx", "wasm", "store", wasmFile, fmt.Sprintf("--from=%s", from), "--gas=auto", "--gas-adjustment=1.3"}
n.LogActionF(strings.Join(cmd, " "))
n.LogActionF("Executing command: %s", strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully stored")
Expand All @@ -272,7 +272,7 @@ func (n *NodeConfig) StoreWasmCode(wasmFile, from string) {
func (n *NodeConfig) InstantiateWasmContract(codeId, initMsg, from string) {
n.LogActionF("instantiating wasm contract %s with %s", codeId, initMsg)
cmd := []string{"babylond", "tx", "wasm", "instantiate", codeId, initMsg, fmt.Sprintf("--from=%s", from), "--no-admin", "--label=contract", "--gas=auto", "--gas-adjustment=1.3"}
n.LogActionF(strings.Join(cmd, " "))
n.LogActionF("Executing command: %s", strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully initialized")
Expand All @@ -281,7 +281,7 @@ func (n *NodeConfig) InstantiateWasmContract(codeId, initMsg, from string) {
func (n *NodeConfig) WasmExecute(contract, execMsg, from string) {
n.LogActionF("executing %s on wasm contract %s from %s", execMsg, contract, from)
cmd := []string{"babylond", "tx", "wasm", "execute", contract, execMsg, fmt.Sprintf("--from=%s", from)}
n.LogActionF(strings.Join(cmd, " "))
n.LogActionF("Executing command: %s", strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully executed")
Expand All @@ -291,7 +291,7 @@ func (n *NodeConfig) WasmExecute(contract, execMsg, from string) {
func (n *NodeConfig) WithdrawReward(sType, from string) {
n.LogActionF("withdraw rewards of type %s for tx signer %s", sType, from)
cmd := []string{"babylond", "tx", "incentive", "withdraw-reward", sType, fmt.Sprintf("--from=%s", from)}
n.LogActionF(strings.Join(cmd, " "))
n.LogActionF("Executing command: %s", strings.Join(cmd, " "))
_, _, err := n.containerManager.ExecTxCmd(n.t, n.chainId, n.Name, cmd)
require.NoError(n.t, err)
n.LogActionF("successfully withdrawn")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
package keeper_test
package testutil

import (
"math/rand"
"testing"

"cosmossdk.io/core/header"
"cosmossdk.io/log"
sdkmath "cosmossdk.io/math"
"cosmossdk.io/store"
storemetrics "cosmossdk.io/store/metrics"
"github.com/btcsuite/btcd/btcec/v2"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire"
dbm "github.com/cosmos/cosmos-db"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
Expand All @@ -21,57 +25,84 @@ import (
btclctypes "github.com/babylonlabs-io/babylon/x/btclightclient/types"
"github.com/babylonlabs-io/babylon/x/btcstaking/keeper"
"github.com/babylonlabs-io/babylon/x/btcstaking/types"
epochingtypes "github.com/babylonlabs-io/babylon/x/epoching/types"
fkeeper "github.com/babylonlabs-io/babylon/x/finality/keeper"
ftypes "github.com/babylonlabs-io/babylon/x/finality/types"
)

var (
net = &chaincfg.SimNetParams
btcTipHeight = uint32(30)
btcTipHeight = uint32(30)
timestampedEpoch = uint64(10)
)

type Helper struct {
t testing.TB

Ctx sdk.Context
BTCStakingKeeper *keeper.Keeper
Ctx sdk.Context
BTCStakingKeeper *keeper.Keeper
MsgServer types.MsgServer

FinalityKeeper *fkeeper.Keeper
FMsgServer ftypes.MsgServer

BTCLightClientKeeper *types.MockBTCLightClientKeeper
BTCCheckpointKeeper *types.MockBtcCheckpointKeeper
FinalityKeeper *types.MockFinalityKeeper
BTCStakingHooks *types.MockBtcStakingHooks
MsgServer types.MsgServer
CheckpointingKeeper *ftypes.MockCheckpointingKeeper
Net *chaincfg.Params
}

func NewHelper(
t testing.TB,
btclcKeeper *types.MockBTCLightClientKeeper,
btccKeeper *types.MockBtcCheckpointKeeper,
finalityKeeper *types.MockFinalityKeeper,
) *Helper {
ctrl := gomock.NewController(t)

// mock refundable messages
iKeeper := types.NewMockIncentiveKeeper(ctrl)
iKeeper := ftypes.NewMockIncentiveKeeper(ctrl)
iKeeper.EXPECT().IndexRefundableMsg(gomock.Any(), gomock.Any()).AnyTimes()

k, ctx := keepertest.BTCStakingKeeper(t, btclcKeeper, btccKeeper, finalityKeeper, iKeeper)
ctx = ctx.WithHeaderInfo(header.Info{Height: 1})
ckptKeeper := ftypes.NewMockCheckpointingKeeper(ctrl)
ckptKeeper.EXPECT().GetLastFinalizedEpoch(gomock.Any()).Return(timestampedEpoch).AnyTimes()

db := dbm.NewMemDB()
stateStore := store.NewCommitMultiStore(db, log.NewTestLogger(t), storemetrics.NewNoOpMetrics())

k, _ := keepertest.BTCStakingKeeperWithStore(t, db, stateStore, btclcKeeper, btccKeeper, iKeeper)
msgSrvr := keeper.NewMsgServerImpl(*k)

mockedHooks := types.NewMockBtcStakingHooks(ctrl)
mockedHooks.EXPECT().AfterFinalityProviderActivated(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
k.SetHooks(mockedHooks)
fk, ctx := keepertest.FinalityKeeperWithStore(t, db, stateStore, k, iKeeper, ckptKeeper)
fMsgSrvr := fkeeper.NewMsgServerImpl(*fk)

// set all parameters
err := k.SetParams(ctx, types.DefaultParams())
require.NoError(t, err)
err = fk.SetParams(ctx, ftypes.DefaultParams())
require.NoError(t, err)

ctx = ctx.WithHeaderInfo(header.Info{Height: 1})

return &Helper{
t: t,
Ctx: ctx,
BTCStakingKeeper: k,
t: t,
Ctx: ctx,

BTCStakingKeeper: k,
MsgServer: msgSrvr,

FinalityKeeper: fk,
FMsgServer: fMsgSrvr,

BTCLightClientKeeper: btclcKeeper,
BTCCheckpointKeeper: btccKeeper,
MsgServer: msgSrvr,
CheckpointingKeeper: ckptKeeper,
Net: &chaincfg.SimNetParams,
}
}

func (h *Helper) T() testing.TB {
return h.t
}

func (h *Helper) NoError(err error) {
require.NoError(h.t, err)
}
Expand All @@ -80,6 +111,13 @@ func (h *Helper) Error(err error, msgAndArgs ...any) {
require.Error(h.t, err, msgAndArgs...)
}

func (h *Helper) BeginBlocker() {
err := h.BTCStakingKeeper.BeginBlocker(h.Ctx)
h.NoError(err)
err = h.FinalityKeeper.BeginBlocker(h.Ctx)
h.NoError(err)
}

func (h *Helper) GenAndApplyParams(r *rand.Rand) ([]*btcec.PrivateKey, []*btcec.PublicKey) {
return h.GenAndApplyCustomParams(r, 100, 0)
}
Expand Down Expand Up @@ -110,19 +148,18 @@ func (h *Helper) GenAndApplyCustomParams(
slashingPkScript, err := txscript.PayToAddrScript(slashingAddress)
h.NoError(err)
err = h.BTCStakingKeeper.SetParams(h.Ctx, types.Params{
CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs),
CovenantQuorum: 3,
MinStakingValueSat: 1000,
MaxStakingValueSat: int64(4 * 10e8),
MinStakingTimeBlocks: 10,
MaxStakingTimeBlocks: 10000,
SlashingPkScript: slashingPkScript,
MinSlashingTxFeeSat: 10,
MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.01"),
SlashingRate: sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2),
MaxActiveFinalityProviders: 100,
MinUnbondingTimeBlocks: minUnbondingTime,
UnbondingFeeSat: 1000,
CovenantPks: bbn.NewBIP340PKsFromBTCPKs(covenantPKs),
CovenantQuorum: 3,
MinStakingValueSat: 1000,
MaxStakingValueSat: int64(4 * 10e8),
MinStakingTimeBlocks: 10,
MaxStakingTimeBlocks: 10000,
SlashingPkScript: slashingPkScript,
MinSlashingTxFeeSat: 10,
MinCommissionRate: sdkmath.LegacyMustNewDecFromStr("0.01"),
SlashingRate: sdkmath.LegacyNewDecWithPrec(int64(datagen.RandomInt(r, 41)+10), 2),
MinUnbondingTimeBlocks: minUnbondingTime,
UnbondingFeeSat: 1000,
})
h.NoError(err)
return covenantSKs, covenantPKs
Expand Down Expand Up @@ -470,3 +507,30 @@ func (h *Helper) AddInclusionProof(
status = updatedDel.GetStatus(btcTipHeight, bcParams.CheckpointFinalizationTimeout, bsParams.CovenantQuorum)
require.Equal(h.t, status, types.BTCDelegationStatus_ACTIVE, "the BTC delegation shall be active")
}

func (h *Helper) CommitPubRandList(
r *rand.Rand,
fpSK *btcec.PrivateKey,
fp *types.FinalityProvider,
startHeight uint64,
numPubRand uint64,
timestamped bool,
) *datagen.RandListInfo {
randListInfo, msg, err := datagen.GenRandomMsgCommitPubRandList(r, fpSK, startHeight, numPubRand)
h.NoError(err)

// if timestamped, use the timestamped epoch, otherwise use the next epoch
var epoch uint64
if timestamped {
epoch = timestampedEpoch
} else {
epoch = timestampedEpoch + 1
}

h.CheckpointingKeeper.EXPECT().GetEpoch(gomock.Any()).Return(&epochingtypes.Epoch{EpochNumber: epoch}).Times(1)

_, err = h.FMsgServer.CommitPubRandList(h.Ctx, msg)
h.NoError(err)

return randListInfo
}
Loading
Loading