Skip to content

Commit

Permalink
add new test for finalized ballot
Browse files Browse the repository at this point in the history
  • Loading branch information
lumtis committed Feb 28, 2024
1 parent db00ba1 commit e039531
Show file tree
Hide file tree
Showing 4 changed files with 195 additions and 77 deletions.
2 changes: 1 addition & 1 deletion x/crosschain/keeper/msg_server_vote_inbound_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg
// This may happen if the same inbound is observed twice where msg.Digest gives a different index
// This check prevents double spending
if isNew {
if k.IsFinalizedInbound(ctx, msg.InTxHash, msg.SenderChainId, msg.EventIndex) {
if k.IsFinalizedInbound(tmpCtx, msg.InTxHash, msg.SenderChainId, msg.EventIndex) {
return nil, cosmoserrors.Wrap(
types.ErrObservedTxAlreadyFinalized,
fmt.Sprintf("InTxHash:%s, SenderChainID:%d, EventIndex:%d", msg.InTxHash, msg.SenderChainId, msg.EventIndex),
Expand Down
152 changes: 76 additions & 76 deletions x/crosschain/keeper/msg_server_vote_inbound_tx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ func setObservers(t *testing.T, k *keeper.Keeper, ctx sdk.Context, zk keepertest
})
return validatorAddressListFormatted
}

// TODO: Complete the test cases
// https://github.com/zeta-chain/node/issues/1542
func TestKeeper_VoteOnObservedInboundTx(t *testing.T) {
t.Run("successfully vote on evm deposit", func(t *testing.T) {
k, ctx, _, zk := keepertest.CrosschainKeeper(t)
Expand Down Expand Up @@ -69,91 +72,88 @@ func TestKeeper_VoteOnObservedInboundTx(t *testing.T) {
require.Equal(t, cctx.CctxStatus.Status, types.CctxStatus_OutboundMined)
require.Equal(t, cctx.InboundTxParams.TxFinalizationStatus, types.TxFinalizationStatus_Executed)
})
// TODO : https://github.com/zeta-chain/node/issues/1542
}

/*
Potential Double Event Submission
*/
func TestNoDoubleEventProtections(t *testing.T) {
k, ctx, _, zk := keepertest.CrosschainKeeper(t)
t.Run("prevent double event submission", func(t *testing.T) {
k, ctx, _, zk := keepertest.CrosschainKeeper(t)

// MsgServer for the crosschain keeper
msgServer := keeper.NewMsgServerImpl(*k)
// MsgServer for the crosschain keeper
msgServer := keeper.NewMsgServerImpl(*k)

// Set the chain ids we want to use to be valid
params := observertypes.DefaultParams()
zk.ObserverKeeper.SetParams(
ctx, params,
)
// Set the chain ids we want to use to be valid
params := observertypes.DefaultParams()
zk.ObserverKeeper.SetParams(
ctx, params,
)

// Convert the validator address into a user address.
validators := k.GetStakingKeeper().GetAllValidators(ctx)
validatorAddress := validators[0].OperatorAddress
valAddr, _ := sdk.ValAddressFromBech32(validatorAddress)
addresstmp, _ := sdk.AccAddressFromHexUnsafe(hex.EncodeToString(valAddr.Bytes()))
validatorAddr := addresstmp.String()
// Convert the validator address into a user address.
validators := k.GetStakingKeeper().GetAllValidators(ctx)
validatorAddress := validators[0].OperatorAddress
valAddr, _ := sdk.ValAddressFromBech32(validatorAddress)
addresstmp, _ := sdk.AccAddressFromHexUnsafe(hex.EncodeToString(valAddr.Bytes()))
validatorAddr := addresstmp.String()

// Add validator to the observer list for voting
zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{
ObserverList: []string{validatorAddr},
})
// Add validator to the observer list for voting
zk.ObserverKeeper.SetObserverSet(ctx, observertypes.ObserverSet{
ObserverList: []string{validatorAddr},
})

// Vote on the FIRST message.
msg := &types.MsgVoteOnObservedInboundTx{
Creator: validatorAddr,
Sender: "0x954598965C2aCdA2885B037561526260764095B8",
SenderChainId: 1337, // ETH
Receiver: "0x954598965C2aCdA2885B037561526260764095B8",
ReceiverChain: 101, // zetachain
Amount: sdkmath.NewUintFromString("10000000"),
Message: "",
InBlockHeight: 1,
GasLimit: 1000000000,
InTxHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b",
CoinType: 0, // zeta
TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8",
Asset: "",
EventIndex: 1,
}
_, err := msgServer.VoteOnObservedInboundTx(
ctx,
msg,
)
require.NoError(t, err)
// Vote on the FIRST message.
msg := &types.MsgVoteOnObservedInboundTx{
Creator: validatorAddr,
Sender: "0x954598965C2aCdA2885B037561526260764095B8",
SenderChainId: 1337, // ETH
Receiver: "0x954598965C2aCdA2885B037561526260764095B8",
ReceiverChain: 101, // zetachain
Amount: sdkmath.NewUintFromString("10000000"),
Message: "",
InBlockHeight: 1,
GasLimit: 1000000000,
InTxHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b",
CoinType: 0, // zeta
TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8",
Asset: "",
EventIndex: 1,
}
_, err := msgServer.VoteOnObservedInboundTx(
ctx,
msg,
)
require.NoError(t, err)

// Check that the vote passed
ballot, found := zk.ObserverKeeper.GetBallot(ctx, msg.Digest())
require.True(t, found)
require.Equal(t, ballot.BallotStatus, observertypes.BallotStatus_BallotFinalized_SuccessObservation)
//Perform the SAME event. Except, this time, we resubmit the event.
msg2 := &types.MsgVoteOnObservedInboundTx{
Creator: validatorAddr,
Sender: "0x954598965C2aCdA2885B037561526260764095B8",
SenderChainId: 1337,
Receiver: "0x954598965C2aCdA2885B037561526260764095B8",
ReceiverChain: 101,
Amount: sdkmath.NewUintFromString("10000000"),
Message: "",
InBlockHeight: 1,
GasLimit: 1000000001, // <---- Change here
InTxHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b",
CoinType: 0,
TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8",
Asset: "",
EventIndex: 1,
}
// Check that the vote passed
ballot, found := zk.ObserverKeeper.GetBallot(ctx, msg.Digest())
require.True(t, found)
require.Equal(t, ballot.BallotStatus, observertypes.BallotStatus_BallotFinalized_SuccessObservation)
//Perform the SAME event. Except, this time, we resubmit the event.
msg2 := &types.MsgVoteOnObservedInboundTx{
Creator: validatorAddr,
Sender: "0x954598965C2aCdA2885B037561526260764095B8",
SenderChainId: 1337,
Receiver: "0x954598965C2aCdA2885B037561526260764095B8",
ReceiverChain: 101,
Amount: sdkmath.NewUintFromString("10000000"),
Message: "",
InBlockHeight: 1,
GasLimit: 1000000001, // <---- Change here
InTxHash: "0x7a900ef978743f91f57ca47c6d1a1add75df4d3531da17671e9cf149e1aefe0b",
CoinType: 0,
TxOrigin: "0x954598965C2aCdA2885B037561526260764095B8",
Asset: "",
EventIndex: 1,
}

_, err = msgServer.VoteOnObservedInboundTx(
ctx,
msg2,
)
require.Error(t, err)
require.ErrorIs(t, err, types.ErrObservedTxAlreadyFinalized)
_, found = zk.ObserverKeeper.GetBallot(ctx, msg2.Digest())
require.False(t, found)
_, err = msgServer.VoteOnObservedInboundTx(
ctx,
msg2,
)
require.Error(t, err)
require.ErrorIs(t, err, types.ErrObservedTxAlreadyFinalized)
_, found = zk.ObserverKeeper.GetBallot(ctx, msg2.Digest())
require.False(t, found)
})
}
func TestStatus_StatusTransition(t *testing.T) {

func TestStatus_ChangeStatus(t *testing.T) {
tt := []struct {
Name string
Status types.Status
Expand Down
62 changes: 62 additions & 0 deletions x/observer/keeper/vote_inbound_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,4 +320,66 @@ func TestKeeper_VoteOnInboundBallot(t *testing.T) {
require.False(t, isFinalized)
require.False(t, isNew)
})

t.Run("can add vote to an existing ballot and finalize ballot", func(t *testing.T) {
k, ctx, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMocksAll)

observer := sample.AccAddress()
stakingMock := keepertest.GetObserverStakingMock(t, k)
slashingMock := keepertest.GetObserverSlashingMock(t, k)

k.SetCrosschainFlags(ctx, types.CrosschainFlags{
IsInboundEnabled: true,
})
k.SetChainParamsList(ctx, types.ChainParamsList{
ChainParams: []*types.ChainParams{
{
ChainId: getValidEthChainIDWithIndex(t, 0),
IsSupported: true,
},
{
ChainId: getValidEthChainIDWithIndex(t, 1),
IsSupported: true,
},
},
})
k.SetObserverSet(ctx, types.ObserverSet{
ObserverList: []string{observer},
})
stakingMock.MockGetValidator(sample.Validator(t, sample.Rand()))
slashingMock.MockIsTombstoned(false)

// set a ballot
threshold, err := sdk.NewDecFromStr("0.1")
require.NoError(t, err)
ballot := types.Ballot{
Index: "index",
BallotIdentifier: "index",
VoterList: []string{
observer,
sample.AccAddress(),
sample.AccAddress(),
},
Votes: types.CreateVotes(3),
ObservationType: types.ObservationType_InBoundTx,
BallotThreshold: threshold,
BallotStatus: types.BallotStatus_BallotInProgress,
}
k.SetBallot(ctx, &ballot)

isFinalized, isNew, err := k.VoteOnInboundBallot(
ctx,
getValidEthChainIDWithIndex(t, 0),
getValidEthChainIDWithIndex(t, 1),
common.CoinType_ERC20,
observer,
"index",
"inTxHash",
)
require.NoError(t, err)

// ballot should not be finalized as the threshold is not reached
require.True(t, isFinalized)
require.False(t, isNew)
})
}
56 changes: 56 additions & 0 deletions x/observer/keeper/vote_outbound_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,4 +190,60 @@ func TestKeeper_VoteOnOutboundBallot(t *testing.T) {
require.True(t, found)
require.Equal(t, expectedBallot, ballot)
})

t.Run("can add vote to an existing ballot and finalize ballot", func(t *testing.T) {
k, ctx, _ := keepertest.ObserverKeeperWithMocks(t, keepertest.ObserverMocksAll)

observer := sample.AccAddress()
stakingMock := keepertest.GetObserverStakingMock(t, k)
slashingMock := keepertest.GetObserverSlashingMock(t, k)

k.SetChainParamsList(ctx, types.ChainParamsList{
ChainParams: []*types.ChainParams{
{
ChainId: getValidEthChainIDWithIndex(t, 0),
IsSupported: true,
},
},
})
k.SetObserverSet(ctx, types.ObserverSet{
ObserverList: []string{observer},
})
stakingMock.MockGetValidator(sample.Validator(t, sample.Rand()))
slashingMock.MockIsTombstoned(false)

// set a ballot
threshold, err := sdk.NewDecFromStr("0.1")
require.NoError(t, err)
ballot := types.Ballot{
Index: "index",
BallotIdentifier: "index",
VoterList: []string{
observer,
sample.AccAddress(),
sample.AccAddress(),
},
Votes: types.CreateVotes(3),
ObservationType: types.ObservationType_OutBoundTx,
BallotThreshold: threshold,
BallotStatus: types.BallotStatus_BallotInProgress,
}
k.SetBallot(ctx, &ballot)

isFinalized, isNew, ballot, _, err := k.VoteOnOutboundBallot(
ctx,
"index",
getValidEthChainIDWithIndex(t, 0),
common.ReceiveStatus_Success,
observer,
)
require.NoError(t, err)

// ballot should be finalized since there is only one observer
require.True(t, isFinalized)
require.False(t, isNew)
expectedBallot, found := k.GetBallot(ctx, "index")
require.True(t, found)
require.Equal(t, expectedBallot, ballot)
})
}

0 comments on commit e039531

Please sign in to comment.