diff --git a/changelog.md b/changelog.md index 6955f6c892..accd802d9f 100644 --- a/changelog.md +++ b/changelog.md @@ -31,6 +31,7 @@ * [2674](https://github.com/zeta-chain/node/pull/2674) - allow operators to vote on ballots associated with discarded keygen without affecting the status of the current keygen. * [2672](https://github.com/zeta-chain/node/pull/2672) - check observer set for duplicates when adding a new observer or updating an existing one * [2735](https://github.com/zeta-chain/node/pull/2735) - fix the outbound tracker blocking confirmation and outbound processing on EVM chains by locally index outbound txs in zetaclient +* [2944](https://github.com/zeta-chain/node/pull/2844) - add tsspubkey to index for tss keygen voting * [2842](https://github.com/zeta-chain/node/pull/2842) - fix: move interval assignment out of cctx loop in EVM outbound tx scheduler * [2853](https://github.com/zeta-chain/node/pull/2853) - calling precompile through sc with sc state update diff --git a/x/observer/keeper/msg_server_vote_tss_test.go b/x/observer/keeper/msg_server_vote_tss_test.go index b1b61eb14b..e08ad3fa9f 100644 --- a/x/observer/keeper/msg_server_vote_tss_test.go +++ b/x/observer/keeper/msg_server_vote_tss_test.go @@ -66,11 +66,11 @@ func TestMsgServer_VoteTSS(t *testing.T) { keygen.BlockNumber = 42 k.SetNodeAccount(ctx, *nodeAcc) k.SetKeygen(ctx, *keygen) - + tss := sample.Tss() // ACT _, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc.Operator, - TssPubkey: sample.Tss().TssPubkey, + TssPubkey: tss.TssPubkey, KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) @@ -78,7 +78,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { // ASSERT // keygen is already completed, but the vote can still be added if the operator has not voted yet require.NoError(t, err) - ballot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 42, "tss-keygen")) + ballot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s-%s", 42, tss.TssPubkey, "tss-keygen")) require.True(t, found) require.EqualValues(t, types.BallotStatus_BallotFinalized_SuccessObservation, ballot.BallotStatus) require.True(t, ballot.HasVoted(nodeAcc.Operator)) @@ -268,11 +268,12 @@ func TestMsgServer_VoteTSS(t *testing.T) { k.SetNodeAccount(ctx, *nodeAcc) k.SetNodeAccount(ctx, *sample.NodeAccount()) k.SetKeygen(ctx, *keygen) + tss := sample.Tss() // add a first vote res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc.Operator, - TssPubkey: sample.Tss().TssPubkey, + TssPubkey: tss.TssPubkey, KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) @@ -283,7 +284,7 @@ func TestMsgServer_VoteTSS(t *testing.T) { // vote again: voting should fail _, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ Creator: nodeAcc.Operator, - TssPubkey: sample.Tss().TssPubkey, + TssPubkey: tss.TssPubkey, KeygenZetaHeight: 42, Status: chains.ReceiveStatus_success, }) @@ -415,11 +416,11 @@ func TestMsgServer_VoteTSS(t *testing.T) { _, found = k.GetTSS(ctx) require.False(t, found) - oldBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 42, "tss-keygen")) + oldBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s-%s", 42, tss.TssPubkey, "tss-keygen")) require.True(t, found) require.EqualValues(t, types.BallotStatus_BallotFinalized_SuccessObservation, oldBallot.BallotStatus) - newBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 52, "tss-keygen")) + newBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s-%s", 52, tss2.TssPubkey, "tss-keygen")) require.True(t, found) require.EqualValues(t, types.BallotStatus_BallotInProgress, newBallot.BallotStatus) }) @@ -548,16 +549,16 @@ func TestMsgServer_VoteTSS(t *testing.T) { require.EqualValues(t, finalizingHeight, newKeygen.BlockNumber) require.EqualValues(t, types.KeygenStatus_KeyGenSuccess, newKeygen.Status) - tss, found = k.GetTSS(ctx) + tssQueried, found := k.GetTSS(ctx) require.True(t, found) - require.Equal(t, tss.KeyGenZetaHeight, int64(52)) - require.Equal(t, tss.FinalizedZetaHeight, finalizingHeight) + require.Equal(t, tssQueried.KeyGenZetaHeight, int64(52)) + require.Equal(t, tssQueried.FinalizedZetaHeight, finalizingHeight) - oldBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 42, "tss-keygen")) + oldBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s-%s", 42, tss.TssPubkey, "tss-keygen")) require.True(t, found) require.EqualValues(t, types.BallotStatus_BallotInProgress, oldBallot.BallotStatus) - newBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s", 52, "tss-keygen")) + newBallot, found := k.GetBallot(ctx, fmt.Sprintf("%d-%s-%s", 52, tss2.TssPubkey, "tss-keygen")) require.True(t, found) require.EqualValues(t, types.BallotStatus_BallotFinalized_SuccessObservation, newBallot.BallotStatus) }) @@ -715,4 +716,72 @@ func TestMsgServer_VoteTSS(t *testing.T) { require.True(t, found) require.EqualValues(t, types.KeygenStatus_KeyGenFailed, newKeygen.Status) }) + + t.Run("unable to finalize tss if pubkey is different", func(t *testing.T) { + k, ctx, _, _ := keepertest.ObserverKeeper(t) + ctx = ctx.WithBlockHeight(42) + srv := keeper.NewMsgServerImpl(*k) + + // setup state with 3 node accounts + nodeAcc1 := sample.NodeAccount() + nodeAcc2 := sample.NodeAccount() + keygen := sample.Keygen(t) + keygen.BlockNumber = 42 + keygen.Status = types.KeygenStatus_PendingKeygen + tss := sample.Tss() + k.SetNodeAccount(ctx, *nodeAcc1) + k.SetNodeAccount(ctx, *nodeAcc2) + k.SetKeygen(ctx, *keygen) + + // ACT + // Add first vote + res, err := srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc1.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // check response + require.True(t, res.BallotCreated) + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // Add second vote with different pubkey should not finalize the tss + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc2.Operator, + TssPubkey: sample.Tss().TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // ASSERT + require.True(t, res.BallotCreated) // New ballot created as pubkey is different + require.False(t, res.VoteFinalized) + require.False(t, res.KeygenSuccess) + + // Add the second vote with correct pubkey should finalize the tss + finalizingHeight := int64(55) + ctx = ctx.WithBlockHeight(finalizingHeight) + res, err = srv.VoteTSS(ctx, &types.MsgVoteTSS{ + Creator: nodeAcc2.Operator, + TssPubkey: tss.TssPubkey, + KeygenZetaHeight: 42, + Status: chains.ReceiveStatus_success, + }) + require.NoError(t, err) + + // ASSERT + require.False(t, res.BallotCreated) + require.True(t, res.VoteFinalized) + require.True(t, res.KeygenSuccess) + + tssQueried, found := k.GetTSS(ctx) + require.True(t, found) + + require.Equal(t, finalizingHeight, tssQueried.FinalizedZetaHeight) + require.Equal(t, tss.TssPubkey, tssQueried.TssPubkey) + }) } diff --git a/x/observer/types/message_vote_tss.go b/x/observer/types/message_vote_tss.go index c03661f3b4..66282838da 100644 --- a/x/observer/types/message_vote_tss.go +++ b/x/observer/types/message_vote_tss.go @@ -60,5 +60,5 @@ func (msg *MsgVoteTSS) ValidateBasic() error { func (msg *MsgVoteTSS) Digest() string { // We support only 1 keygen at a particular height - return fmt.Sprintf("%d-%s", msg.KeygenZetaHeight, "tss-keygen") + return fmt.Sprintf("%d-%s-%s", msg.KeygenZetaHeight, msg.TssPubkey, "tss-keygen") } diff --git a/x/observer/types/message_vote_tss_test.go b/x/observer/types/message_vote_tss_test.go index 36f9018d7d..6d4c51f9da 100644 --- a/x/observer/types/message_vote_tss_test.go +++ b/x/observer/types/message_vote_tss_test.go @@ -101,6 +101,21 @@ func TestMsgVoteTSS_GetSignBytes(t *testing.T) { } func TestMsgVoteTSS_Digest(t *testing.T) { - msg := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_success) - require.Equal(t, "1-tss-keygen", msg.Digest()) + vote1 := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_success) + require.Equal(t, "1-pubkey-tss-keygen", vote1.Digest()) + + vote2 := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 1, chains.ReceiveStatus_success) + require.Equal(t, "1-pubkey-tss-keygen", vote2.Digest()) + + require.Equal(t, vote1.Digest(), vote2.Digest()) + + vote3 := types.NewMsgVoteTSS(sample.AccAddress(), "pubkeyNew", 2, chains.ReceiveStatus_success) + require.Equal(t, "2-pubkeyNew-tss-keygen", vote3.Digest()) + // Different pubkey changes digest + require.NotEqual(t, vote1.Digest(), vote3.Digest()) + + vote4 := types.NewMsgVoteTSS(sample.AccAddress(), "pubkey", 3, chains.ReceiveStatus_success) + require.Equal(t, "3-pubkey-tss-keygen", vote4.Digest()) + // Different height changes digest + require.NotEqual(t, vote1.Digest(), vote4.Digest()) }