Skip to content

Commit

Permalink
feat: implement BEP-333(BNB Chain Fusion) (#381)
Browse files Browse the repository at this point in the history
* feat: bc fusion hardfork implementation (#358)

* fix: panic issue when doing refundStake and closeCorssChainChannel (#362)

* fix: handleMsgSideChainUndelegate should not pass prefixCtx

* fix: nil pointer when doing ibc method in endblock

* fix: add logs to sunset fork events and immediate sidechain undelegation (#364)

* fix: revert immediate sidechain undelegation and handle undelegation in endblock (#365)

* fix: disable ClaimMsg after FinalSunsetFork (#366)

* feat: add `MsgSideChainStakeMigration` and `StakeMigrationApp` (#367)

* feat: add `MsgSideChainStakeMigration` and `StakeMigrationApp`

* add missing tag

* fix `handleMsgSideChainStakeMigration`

* fix review comments

* rename `MsgTypeSideChainStakeMigration`

* add fee param for `MsgSideChainStakeMigration`

* fix: add missing register for new msg (#368)

* fix: error within `CreateRawIBCPackageByIdWithFee` (#369)

* fix: decimal for BCFusionStopGovThreshold (#370)

* fix: panic when totally unbound the validator in voting period (#371)

* fix: add missing event (#372)

* fix: wrong json tag (#373)

* fix: add missing tag of relayer fee in `handleMsgSideChainStakeMigration` (#376)

* feat: add IsAutoUnDelegate field to CrossStakeDistributeUndelegatedSynPackage and  prevent too many failed in auto refund (#377)

* feat: add IsAutoUnDelegate field to CrossStakeDistributeUndelegatedSynPackage

* fix: disable undelegate after SecondSunsetFork and prevent too many failed in auto refund

* chore: add more logs

* revert: cross stake changes

* fix: error handling in refund

* fix: transferPackage

* fix: CrossStakeDistributeUndelegatedSynPackageV2

* fix: reset context every time in refund loop (#378)

* fix: do not charge relayerFee for auto cross undelegate after SecondSunsetFork (#379)

* fix: do not charge relayerFee for auto cross undelegate after SecondSunsetFork

* fix: FeeCalculator

* chore: add logs for processed refunding count (#380)

* fix: close mirror, mirrorSync channel after FinalSunsetFork (#382)

* fix: disable MsgEditSideChainValidator after FirstSunsetFork and refine codes (#383)

* fix: change StakeMigrationRelayFee to 0.002BNB (#384)

* fix: appHash mismatch causes by channelsMap (#385)

---------

Co-authored-by: Roshan <[email protected]>
  • Loading branch information
j75689 and pythonberg1997 authored Feb 26, 2024
1 parent 5a7b238 commit 46d2616
Show file tree
Hide file tree
Showing 39 changed files with 907 additions and 91 deletions.
1 change: 1 addition & 0 deletions types/stake.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type ValidatorSet interface {
ValidatorByConsAddr(Context, ConsAddress) Validator // get a particular validator by consensus address
ValidatorByVoteAddr(Context, []byte) Validator // get a particular validator by vote address
TotalPower(Context) Dec // total power of the validator set
GetAllStatusVotingPower(ctx Context) Dec // total voting power of the validator set

// slash the validator and delegators of the validator, specifying offence height, offence power, and slash fraction
Slash(Context, ConsAddress, int64, int64, Dec)
Expand Down
8 changes: 8 additions & 0 deletions types/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ const (
FixDoubleSignChainId = "FixDoubleSignChainId"
BEP126 = "BEP126" //https://github.com/binance-chain/BEPs/pull/126
BEP255 = "BEP255" // https://github.com/bnb-chain/BEPs/pull/255

FirstSunsetFork = "FirstSunsetFork"
SecondSunsetFork = "SecondSunsetFork"
FinalSunsetFork = "FinalSunsetFork"
)

var (
BCFusionStopGovThreshold int64 = 5_000_000_00000000 // 5M BNB
)

var MainNetConfig = UpgradeConfig{
Expand Down
3 changes: 3 additions & 0 deletions x/gov/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ func NewHandler(keeper Keeper) sdk.Handler {
case MsgSideChainDeposit:
return handleMsgSideChainDeposit(ctx, keeper, msg)
case MsgSideChainSubmitProposal:
if sdk.IsUpgrade(sdk.SecondSunsetFork) {
return sdk.ErrMsgNotSupported("").Result()
}
return handleMsgSideChainSubmitProposal(ctx, keeper, msg)
case MsgSideChainVote:
return handleMsgSideChainVote(ctx, keeper, msg)
Expand Down
14 changes: 10 additions & 4 deletions x/gov/handler_sidechain.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@ import (
)

func handleMsgSideChainSubmitProposal(ctx sdk.Context, keeper Keeper, msg MsgSideChainSubmitProposal) sdk.Result {
if msg.ProposalType == ProposalTypeText && !sdk.IsUpgrade(sdk.BEP173) {
return ErrInvalidProposalType(keeper.codespace, msg.ProposalType).Result()
}

ctx, err := keeper.ScKeeper.PrepareCtxForSideChain(ctx, msg.SideChainId)
if err != nil {
return ErrInvalidSideChainId(keeper.codespace, msg.SideChainId).Result()
}
if sdk.IsUpgrade(sdk.FirstSunsetFork) {
vp := keeper.vs.GetAllStatusVotingPower(ctx)
if vp.LTE(sdk.NewDecFromInt(sdk.BCFusionStopGovThreshold)) {
return sdk.ErrMsgNotSupported("").Result()
}
}

if msg.ProposalType == ProposalTypeText && !sdk.IsUpgrade(sdk.BEP173) {
return ErrInvalidProposalType(keeper.codespace, msg.ProposalType).Result()
}

result := handleMsgSubmitProposal(ctx, keeper,
NewMsgSubmitProposal(msg.Title, msg.Description, msg.ProposalType, msg.Proposer, msg.InitialDeposit,
Expand Down
6 changes: 4 additions & 2 deletions x/gov/tally.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@ func Tally(ctx sdk.Context, keeper Keeper, proposal Proposal) (passes bool, refu
// if delegator tally voting power
valAddrStr := sdk.ValAddress(vote.Voter).String()
if val, ok := currValidators[valAddrStr]; ok {
val.Vote = vote.Option
currValidators[valAddrStr] = val
if val.DelegatorShares.GT(sdk.ZeroDec()) {
val.Vote = vote.Option
currValidators[valAddrStr] = val
}
} else {

keeper.ds.IterateDelegations(ctx, vote.Voter, func(index int64, delegation sdk.Delegation) (stop bool) {
Expand Down
87 changes: 85 additions & 2 deletions x/ibc/endblock.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,103 @@
package ibc

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/cosmos/cosmos-sdk/x/gov"
)

const (
mirrorChannelID = 4
mirrorSyncChannelID = 5
)

func EndBlocker(ctx sdk.Context, keeper Keeper) {
if len(keeper.packageCollector.collectedPackages) == 0 {
return
}
var attributes []sdk.Attribute
var (
attributes []sdk.Attribute
events sdk.Events
)
for _, ibcPackageRecord := range keeper.packageCollector.collectedPackages {
attributes = append(attributes,
sdk.NewAttribute(ibcPackageInfoAttributeKey,
buildIBCPackageAttributeValue(ibcPackageRecord.destChainID, ibcPackageRecord.channelID, ibcPackageRecord.sequence)))
}

keeper.packageCollector.collectedPackages = keeper.packageCollector.collectedPackages[:0]
event := sdk.NewEvent(ibcEventType, attributes...)
ctx.EventManager().EmitEvent(event)
events.AppendEvent(event)
if sdk.IsUpgrade(sdk.FinalSunsetFork) && !keeper.sideKeeper.IsBSCAllChannelClosed(ctx) {
events = events.AppendEvents(closeSideChainChannels(ctx, keeper))
}
ctx.EventManager().EmitEvents(events)
}

func closeSideChainChannels(ctx sdk.Context, k Keeper) sdk.Events {
var events sdk.Events
sideChainId := k.sideKeeper.BscSideChainId(ctx)
// disable side chain channels
id := k.sideKeeper.Config().DestChainNameToID(sideChainId)
govChannelId := sdk.ChannelID(gov.ProposalTypeManageChanPermission)
permissions := k.sideKeeper.GetChannelSendPermissions(ctx, id)
channels := k.sideKeeper.Config().ChannelIDs()

// mirror, mirrorSync channel was enabled by BEP84(https://github.com/bnb-chain/BEPs/blob/master/BEPs/BEP84.md)
// Those channels were bsc side channels, so they would not be in the bc store.
if _, exist := permissions[mirrorChannelID]; !exist {
channels = append(channels, mirrorChannelID)
permissions[mirrorChannelID] = sdk.ChannelAllow
}
if _, exist := permissions[mirrorSyncChannelID]; !exist {
channels = append(channels, mirrorSyncChannelID)
permissions[mirrorSyncChannelID] = sdk.ChannelAllow
}

// close all side chain channels except gov channel
for _, channelId := range channels {
if channelId == govChannelId {
// skip gov channel
continue
}
if permissions[channelId] == sdk.ChannelForbidden {
// skip forbidden channel
continue
}

events = events.AppendEvents(closeChannelOnSideChanAndKeeper(ctx, k, id, channelId))
}

// disable side chain gov channel
if permissions[govChannelId] == sdk.ChannelAllow {
events = events.AppendEvents(closeChannelOnSideChanAndKeeper(ctx, k, id, govChannelId))
}
k.sideKeeper.SetBSCAllChannelClosed(ctx)
return events
}

func closeChannelOnSideChanAndKeeper(ctx sdk.Context, k Keeper,
destChainID sdk.ChainID, channelID sdk.ChannelID) sdk.Events {
var events sdk.Events
_, err := k.sideKeeper.SaveChannelSettingChangeToIbc(ctx, destChainID, channelID, sdk.ChannelForbidden)
if err != nil {
ctx.Logger().Error("failed to save ibc channel change after FinalSunsetFork",
"sideChainId", destChainID, "channelId", channelID, "err", err.Error())
events.AppendEvent(sdk.NewEvent(EventTypeSaveIBCChannelSettingFailed,
sdk.NewAttribute(AttributeKeySideChainId, fmt.Sprint(destChainID)),
sdk.NewAttribute(AttributeKeyChannelId, fmt.Sprint(channelID)),
sdk.NewAttribute(AttributeKeyError, err.Error()),
))
return events
}
events.AppendEvent(sdk.NewEvent(EventTypeSaveIBCChannelSettingSucceed,
sdk.NewAttribute(AttributeKeySideChainId, fmt.Sprint(destChainID)),
sdk.NewAttribute(AttributeKeyChannelId, fmt.Sprint(channelID)),
))
// close bc side chain channel
k.sideKeeper.SetChannelSendPermission(ctx, destChainID, channelID, sdk.ChannelForbidden)

ctx.Logger().Info("close side chain channel after FinalSunsetFork", "sideChainId", destChainID, "channelId", channelID)
return events
}
9 changes: 9 additions & 0 deletions x/ibc/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
)

var (
EventTypeSaveIBCChannelSettingFailed = "save_ibc_channel_setting_failed"
EventTypeSaveIBCChannelSettingSucceed = "save_ibc_channel_setting_succeed"

AttributeKeySideChainId = "side_chain_id"
AttributeKeyChannelId = "channel_id"
AttributeKeyError = "error"
)

const (
separator = "::"
ibcEventType = "IBCPackage"
Expand Down
4 changes: 4 additions & 0 deletions x/ibc/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ func NewKeeper(storeKey sdk.StoreKey, paramSpace param.Subspace, codespace sdk.C
}
}

func (k *Keeper) SetSideChainKeeper(sidechainKeeper sidechain.Keeper) {
k.sideKeeper = sidechainKeeper
}

func (k *Keeper) CreateIBCSyncPackage(ctx sdk.Context, destChainName string, channelName string, packageLoad []byte) (uint64, sdk.Error) {
relayerFee, err := k.GetRelayerFeeParam(ctx, destChainName)
if err != nil {
Expand Down
3 changes: 3 additions & 0 deletions x/oracle/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ func NewHandler(keeper Keeper) sdk.Handler {
return func(ctx sdk.Context, msg sdk.Msg) sdk.Result {
switch msg := msg.(type) {
case types.ClaimMsg:
if sdk.IsUpgrade(sdk.FinalSunsetFork) {
return sdk.ErrMsgNotSupported("").Result()
}
return handleClaimMsg(ctx, keeper, msg)
default:
errMsg := "Unrecognized oracle msg type"
Expand Down
7 changes: 4 additions & 3 deletions x/paramHub/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const (
SideChainDelegateFee = 1e5
SideChainRedelegateFee = 3e5
SideChainUndelegateFee = 2e5
SideChainStakeMigrationFee = 3e5

// beacon chain stake fee
EditChainValidatorFee = 1e8
Expand Down Expand Up @@ -73,7 +74,7 @@ const (
CrossBindRelayFee = 2e6
CrossUnbindRelayFee = 2e6

//MiniToken fee
// MiniToken fee
TinyIssueFee = 2e8
MiniIssueFee = 3e8
MiniSetUriFee = 37500
Expand All @@ -87,7 +88,7 @@ const (
var DefaultGenesisState = param.GenesisState{
FeeGenesis: FeeGenesisState,

//Add other param genesis here
// Add other param genesis here
}

// --------- Definition about fee prams ------------------- //
Expand Down Expand Up @@ -131,4 +132,4 @@ var FeeGenesisState = []param.FeeParam{
},
}

//---------- End definition about fee param ---------------- //
// ---------- End definition about fee param ---------------- //
7 changes: 7 additions & 0 deletions x/paramHub/hub.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ func RegisterUpgradeBeginBlocker(paramHub *ParamHub) {
}
paramHub.UpdateFeeParams(ctx, updateFeeParams)
})
sdk.UpgradeMgr.RegisterBeginBlocker(sdk.FirstSunsetFork, func(ctx sdk.Context) {
updateFeeParams := []param.FeeParam{
&param.FixedFeeParams{MsgType: "side_stake_migration", Fee: SideChainStakeMigrationFee, FeeFor: sdk.FeeForProposer},
}
paramHub.UpdateFeeParams(ctx, updateFeeParams)
})
}

func EndBreatheBlock(ctx sdk.Context, paramHub *ParamHub) {
Expand Down Expand Up @@ -171,6 +177,7 @@ func init() {
"side_delegate": fees.FixedFeeCalculatorGen,
"side_redelegate": fees.FixedFeeCalculatorGen,
"side_undelegate": fees.FixedFeeCalculatorGen,
"side_stake_migration": fees.FixedFeeCalculatorGen,
"bsc_submit_evidence": fees.FixedFeeCalculatorGen,
"side_chain_unjail": fees.FixedFeeCalculatorGen,
"dexList": fees.FixedFeeCalculatorGen,
Expand Down
3 changes: 2 additions & 1 deletion x/paramHub/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ var (
"side_delegate": {},
"side_redelegate": {},
"side_undelegate": {},
"side_stake_migration": {},

"bsc_submit_evidence": {},
"side_chain_unjail": {},
Expand Down Expand Up @@ -292,7 +293,7 @@ type SCParam interface {
subspace.ParamSet
UpdateCheck() error
// native means weather the parameter stored in native store context or side chain store context
//GetParamAttribute() (string, bool)
// GetParamAttribute() (string, bool)
GetParamAttribute() (string, bool)
}

Expand Down
10 changes: 10 additions & 0 deletions x/sidechain/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import sdk "github.com/cosmos/cosmos-sdk/types"
type crossChainConfig struct {
srcChainID sdk.ChainID

channelIDs []sdk.ChannelID
nameToChannelID map[string]sdk.ChannelID
channelIDToName map[sdk.ChannelID]string
channelIDToApp map[sdk.ChannelID]sdk.CrossChainApplication
Expand All @@ -16,6 +17,7 @@ type crossChainConfig struct {
func newCrossChainCfg() *crossChainConfig {
config := &crossChainConfig{
srcChainID: 0,
channelIDs: make([]sdk.ChannelID, 0),
nameToChannelID: make(map[string]sdk.ChannelID),
channelIDToName: make(map[sdk.ChannelID]string),
destChainNameToID: make(map[string]sdk.ChainID),
Expand All @@ -24,3 +26,11 @@ func newCrossChainCfg() *crossChainConfig {
}
return config
}

func (c *crossChainConfig) DestChainNameToID(name string) sdk.ChainID {
return c.destChainNameToID[name]
}

func (c *crossChainConfig) ChannelIDs() []sdk.ChannelID {
return c.channelIDs
}
15 changes: 15 additions & 0 deletions x/sidechain/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ func (k *Keeper) RegisterChannel(name string, id sdk.ChannelID, app sdk.CrossCha
if ok {
return fmt.Errorf("duplicated channel id")
}
k.cfg.channelIDs = append(k.cfg.channelIDs, id)
k.cfg.nameToChannelID[name] = id
k.cfg.channelIDToName[id] = name
k.cfg.channelIDToApp[id] = app
Expand Down Expand Up @@ -224,6 +225,16 @@ func (k *Keeper) incrSequence(ctx sdk.Context, destChainID sdk.ChainID, channelI
kvStore.Set(buildChannelSequenceKey(destChainID, channelID, prefix), sequenceBytes)
}

func (k *Keeper) IsBSCAllChannelClosed(ctx sdk.Context) bool {
kvStore := ctx.KVStore(k.storeKey)
return kvStore.Has(buildBSCAllChannelStatusPrefixKey(k.BscSideChainId(ctx)))
}

func (k *Keeper) SetBSCAllChannelClosed(ctx sdk.Context) {
kvStore := ctx.KVStore(k.storeKey)
kvStore.Set(buildBSCAllChannelStatusPrefixKey(k.BscSideChainId(ctx)), []byte{1})
}

func EndBlock(ctx sdk.Context, k Keeper) {
if sdk.IsUpgrade(sdk.LaunchBscUpgrade) && k.govKeeper != nil {
chanPermissions := k.getLastChanPermissionChanges(ctx)
Expand All @@ -242,3 +253,7 @@ func EndBlock(ctx sdk.Context, k Keeper) {
}
return
}

func (k *Keeper) Config() *crossChainConfig {
return k.cfg
}
6 changes: 6 additions & 0 deletions x/sidechain/key.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ var (
PrefixForReceiveSequenceKey = []byte{0xf1}

PrefixForChannelPermissionKey = []byte{0xc0}

PrefixForBSCAllChannelStatus = []byte{0xc1}
)

func GetSideChainStorePrefixKey(sideChainId string) []byte {
Expand Down Expand Up @@ -51,3 +53,7 @@ func buildChannelPermissionsPrefixKey(destChainID sdk.ChainID) []byte {
binary.BigEndian.PutUint16(key[prefixLength:prefixLength+destChainIDLength], uint16(destChainID))
return key
}

func buildBSCAllChannelStatusPrefixKey(sideChainId string) []byte {
return append(PrefixForBSCAllChannelStatus, []byte(sideChainId)...)
}
1 change: 1 addition & 0 deletions x/stake/client/cli/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func AddCommands(root *cobra.Command, cdc *codec.Codec) {
GetCmdSideChainDelegate(cdc),
GetCmdSideChainRedelegate(cdc),
GetCmdSideChainUnbond(cdc),
GetCmdSideChainStakeMigration(cdc),
)...,
)
stakingCmd.AddCommand(client.LineBreak)
Expand Down
Loading

0 comments on commit 46d2616

Please sign in to comment.