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

refactor: add VoteOnBallot function #2464

Merged
merged 12 commits into from
Jul 15, 2024
3 changes: 2 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
* [2375](https://github.com/zeta-chain/node/pull/2375) - improve & speedup code formatting
* [2380](https://github.com/zeta-chain/node/pull/2380) - use `ChainInfo` in `authority` to allow dynamically support new chains
* [2395](https://github.com/zeta-chain/node/pull/2395) - converge AppContext with ZetaCoreContext in zetaclient
* [2464](https://github.com/zeta-chain/node/pull/2464) - move common voting logic to voting.go and add new function VoteOnBallot

fbac marked this conversation as resolved.
Show resolved Hide resolved
### Tests

Expand Down Expand Up @@ -549,4 +550,4 @@ Getting the correct TSS address for Bitcoin now requires proviidng the Bitcoin c
### CI

* [1218](https://github.com/zeta-chain/node/pull/1218) - cross-compile release binaries and simplify PR testings
* [1302](https://github.com/zeta-chain/node/pull/1302) - add mainnet builds to goreleaser
* [1302](https://github.com/zeta-chain/node/pull/1302) - add mainnet builds to goreleaser
45 changes: 19 additions & 26 deletions x/observer/keeper/msg_server_vote_blame.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"fmt"

cosmoserrors "cosmossdk.io/errors"
sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"

crosschainTypes "github.com/zeta-chain/zetacore/x/crosschain/types"
Expand All @@ -13,52 +13,45 @@ import (

func (k msgServer) VoteBlame(
goCtx context.Context,
vote *types.MsgVoteBlame,
msg *types.MsgVoteBlame,
) (*types.MsgVoteBlameResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)
observationType := types.ObservationType_TSSKeySign

// GetChainFromChainID makes sure we are getting only supported chains , if a chain support has been turned on using gov proposal, this function returns nil
observationChain, found := k.GetSupportedChainFromChainID(ctx, vote.ChainId)
observationChain, found := k.GetSupportedChainFromChainID(ctx, msg.ChainId)
if !found {
return nil, cosmoserrors.Wrap(
return nil, sdkerrors.Wrap(
fbac marked this conversation as resolved.
Show resolved Hide resolved
crosschainTypes.ErrUnsupportedChain,
fmt.Sprintf("ChainID %d, Blame vote", vote.ChainId),
fmt.Sprintf("ChainID %d, Blame vote", msg.ChainId),
)
}

if ok := k.IsNonTombstonedObserver(ctx, vote.Creator); !ok {
if ok := k.IsNonTombstonedObserver(ctx, msg.Creator); !ok {
return nil, types.ErrNotObserver
}

index := vote.Digest()
// Add votes and Set Ballot
// GetBallot checks against the supported chains list before querying for Ballot
ballot, isNew, err := k.FindBallot(ctx, index, observationChain, observationType)
ballot, isFinalized, isNew, err := k.VoteOnBallot(
ctx,
observationChain,
msg.Digest(),
types.ObservationType_TSSKeySign,
msg.Creator,
types.VoteType_SuccessObservation,
)
if err != nil {
return nil, err
return nil, sdkerrors.Wrap(err, "failed to vote on ballot")
}

if isNew {
EmitEventBallotCreated(ctx, ballot, vote.BlameInfo.Index, observationChain.String())
EmitEventBallotCreated(ctx, ballot, msg.BlameInfo.Index, observationChain.String())
}

// AddVoteToBallot adds a vote and sets the ballot
ballot, err = k.AddVoteToBallot(ctx, ballot, vote.Creator, types.VoteType_SuccessObservation)
if err != nil {
return nil, err
}

_, isFinalized := k.CheckIfFinalizingVote(ctx, ballot)
if !isFinalized {
// Return nil here to add vote to ballot and commit state
// Return nil here to add vote to ballot and commit state.
return &types.MsgVoteBlameResponse{}, nil
}

// ******************************************************************************
// below only happens when ballot is finalized: exactly when threshold vote is in
// ******************************************************************************

k.SetBlame(ctx, vote.BlameInfo)
// Ballot is finalized: exactly when threshold vote is in.
k.SetBlame(ctx, msg.BlameInfo)
return &types.MsgVoteBlameResponse{}, nil
}
27 changes: 14 additions & 13 deletions x/observer/keeper/msg_server_vote_block_header.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package keeper
import (
"context"

cosmoserrors "cosmossdk.io/errors"
sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"

lightclienttypes "github.com/zeta-chain/zetacore/x/lightclient/types"
Expand All @@ -20,7 +20,7 @@ func (k msgServer) VoteBlockHeader(
// check if the chain is enabled
chain, found := k.GetSupportedChainFromChainID(ctx, msg.ChainId)
if !found {
return nil, cosmoserrors.Wrapf(types.ErrSupportedChains, "chain id: %d", msg.ChainId)
return nil, sdkerrors.Wrapf(types.ErrSupportedChains, "chain id: %d", msg.ChainId)
}

// check if observer
Expand All @@ -31,29 +31,30 @@ func (k msgServer) VoteBlockHeader(
// check the new block header is valid
parentHash, err := k.lightclientKeeper.CheckNewBlockHeader(ctx, msg.ChainId, msg.BlockHash, msg.Height, msg.Header)
if err != nil {
return nil, cosmoserrors.Wrap(lightclienttypes.ErrInvalidBlockHeader, err.Error())
return nil, sdkerrors.Wrap(lightclienttypes.ErrInvalidBlockHeader, err.Error())
}

// add vote to ballot
ballot, isNew, err := k.FindBallot(ctx, msg.Digest(), chain, types.ObservationType_InboundTx)
_, isFinalized, isNew, err := k.VoteOnBallot(
ctx,
chain,
msg.Digest(),
types.ObservationType_InboundTx,
msg.Creator,
types.VoteType_SuccessObservation,
)
if err != nil {
return nil, cosmoserrors.Wrap(err, "failed to find ballot")
return nil, sdkerrors.Wrap(err, "failed to vote on ballot")
}
ballot, err = k.AddVoteToBallot(ctx, ballot, msg.Creator, types.VoteType_SuccessObservation)
if err != nil {
return nil, cosmoserrors.Wrap(err, "failed to add vote to ballot")
}
_, isFinalized := k.CheckIfFinalizingVote(ctx, ballot)

if !isFinalized {
return &types.MsgVoteBlockHeaderResponse{
BallotCreated: isNew,
VoteFinalized: false,
}, nil
}

// add the new block header to the store
// Add the new block header to the store.
k.lightclientKeeper.AddBlockHeader(ctx, msg.ChainId, msg.Height, msg.BlockHash, msg.Header, parentHash)

return &types.MsgVoteBlockHeaderResponse{
BallotCreated: isNew,
VoteFinalized: true,
Expand Down
2 changes: 0 additions & 2 deletions x/observer/keeper/msg_server_vote_tss.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ func (k msgServer) VoteTSS(goCtx context.Context, msg *types.MsgVoteTSS) (*types
return &types.MsgVoteTSSResponse{}, types.ErrKeygenCompleted
}

// add votes and set Ballot
// GetBallot checks against the supported chains list before querying for Ballot
// TODO : https://github.com/zeta-chain/node/issues/896
lumtis marked this conversation as resolved.
Show resolved Hide resolved
ballotCreated := false
index := msg.Digest()
ballot, found := k.GetBallot(ctx, index)
Expand Down
25 changes: 12 additions & 13 deletions x/observer/keeper/vote_inbound.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package keeper
import (
"fmt"

sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"

"github.com/zeta-chain/zetacore/pkg/coin"
"github.com/zeta-chain/zetacore/x/observer/types"
Expand All @@ -21,7 +21,7 @@ func (k Keeper) VoteOnInboundBallot(
voter string,
ballotIndex string,
inboundHash string,
) (bool, bool, error) {
) (isFinalized bool, isNew bool, err error) {
if !k.IsInboundEnabled(ctx) {
return false, false, types.ErrInboundDisabled
}
Expand Down Expand Up @@ -64,22 +64,21 @@ func (k Keeper) VoteOnInboundBallot(
}
}

// checks against the supported chains list before querying for Ballot
ballot, isNew, err := k.FindBallot(ctx, ballotIndex, senderChain, types.ObservationType_InboundTx)
ballot, isFinalized, isNew, err := k.VoteOnBallot(
ctx,
senderChain,
ballotIndex,
types.ObservationType_InboundTx,
voter,
types.VoteType_SuccessObservation,
)
if err != nil {
return false, false, err
return false, false, sdkerrors.Wrap(err, "failed to vote on ballot")
}

if isNew {
EmitEventBallotCreated(ctx, ballot, inboundHash, senderChain.String())
}

// adds a vote and sets the ballot
ballot, err = k.AddVoteToBallot(ctx, ballot, voter, types.VoteType_SuccessObservation)
if err != nil {
return false, isNew, err
}

// checks if the ballot is finalized
_, isFinalized := k.CheckIfFinalizingVote(ctx, ballot)
return isFinalized, isNew, nil
}
22 changes: 11 additions & 11 deletions x/observer/keeper/vote_outbound.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
sdkerrors "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"

"github.com/zeta-chain/zetacore/pkg/chains"
Expand Down Expand Up @@ -36,18 +37,17 @@ func (k Keeper) VoteOnOutboundBallot(
return false, false, ballot, "", observertypes.ErrNotObserver
}

// fetch or create ballot
ballot, isNew, err = k.FindBallot(ctx, ballotIndex, observationChain, observertypes.ObservationType_OutboundTx)
ballot, isFinalized, isNew, err = k.VoteOnBallot(
ctx,
observationChain,
ballotIndex,
observertypes.ObservationType_OutboundTx,
voter,
observertypes.ConvertReceiveStatusToVoteType(receiveStatus),
)
if err != nil {
return false, false, ballot, "", err
return false, false, ballot, "", sdkerrors.Wrap(err, "failed to vote on ballot")
}

// add vote to ballot
ballot, err = k.AddVoteToBallot(ctx, ballot, voter, observertypes.ConvertReceiveStatusToVoteType(receiveStatus))
if err != nil {
return false, false, ballot, "", err
}

ballot, isFinalizedInThisBlock := k.CheckIfFinalizingVote(ctx, ballot)
return isFinalizedInThisBlock, isNew, ballot, observationChain.String(), nil
return isFinalized, isNew, ballot, observationChain.String(), nil
}
30 changes: 30 additions & 0 deletions x/observer/keeper/utils.go → x/observer/keeper/voting.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,33 @@ func (k Keeper) CheckObserverSelfDelegation(ctx sdk.Context, accAddress string)
}
return nil
}

// VoteOnBallot finds a ballot or creates a new one if not found,
// and casts a vote on it. Then proceed to check if the vote has been finalized.
// This function holds generic logic for all types of votes.
func (k Keeper) VoteOnBallot(
ctx sdk.Context,
chain chains.Chain,
ballotIndex string,
observationType types.ObservationType,
voter string,
voteType types.VoteType,
) (
ballot types.Ballot,
isFinalized bool,
isNew bool,
err error) {
ballot, isNew, err = k.FindBallot(ctx, ballotIndex, chain, observationType)
if err != nil {
return ballot, false, false, err
}

ballot, err = k.AddVoteToBallot(ctx, ballot, voter, voteType)
if err != nil {
return ballot, false, isNew, err
}

ballot, isFinalized = k.CheckIfFinalizingVote(ctx, ballot)

return ballot, isFinalized, isNew, nil
}
File renamed without changes.
Loading