diff --git a/scripts/test_doc/test_documentation.md b/scripts/test_doc/test_documentation.md new file mode 100644 index 0000000000..1bdbaee73d --- /dev/null +++ b/scripts/test_doc/test_documentation.md @@ -0,0 +1,142 @@ +# Test Documentation + +# [changeover.go](../../tests/integration/changeover.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestRecycleTransferChannel](../../tests/integration/changeover.go#L17) | TestRecycleTransferChannel tests that an existing transfer channel can be reused when transitioning from a standalone to a consumer chain.
DetailsThe test case:
* sets up a provider chain and a standalone chain
* creates a connection between the two chains
* creates a transfer channel between the two chains
* transitions the standalone chain to a consumer chain
* confirms that no extra transfer channel is created, thus only one transfer channel and one CCV channel exist.
| +
+ +# [democracy.go](../../tests/integration/democracy.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestDemocracyRewardsDistribution](../../tests/integration/democracy.go#L78) | TestDemocracyRewardsDistribution checks that rewards to democracy representatives, community pool, and provider redistribution account are done correctly.
Details* Set up a democracy consumer chain.
* Create a new block.
* Check that rewards to democracy representatives, community pool, and provider redistribution account are distributed in the right proportions.
| + [TestDemocracyGovernanceWhitelisting](../../tests/integration/democracy.go#L194) | TestDemocracyGovernanceWhitelisting checks that only whitelisted governance proposals can be executed on democracy consumer chains.
DetailsFor context, see the whitelist for proposals in app/consumer-democracy/proposals_whitelisting.go.
* Set up a democracy consumer chain.
* Submit a proposal containing changes to the auth and mint module parameters.
* Check that the proposal is not executed, since the change to the auth module is not whitelisted.
* Submit a proposal containing changes *only* to the mint module parameters.
* Check that the proposal is executed, since the change to the mint module is whitelisted.
* Submit a proposal containing changes *only* to the auth module parameters.
* Check that again, the proposal is not executed, since the change to the auth module is not whitelisted.
| + [TestDemocracyMsgUpdateParams](../../tests/integration/democracy.go#L294) | TestDemocracyMsgUpdateParams checks that the consumer parameters can be updated through a governance proposal.
Details* Set up a democracy consumer chain.
* Submit a proposal containing changes to the consumer module parameters.
* Check that the proposal is executed, and the parameters are updated.
| +
+ +# [distribution.go](../../tests/integration/distribution.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestRewardsDistribution](../../tests/integration/distribution.go#L32) | TestRewardsDistribution tests the distribution of rewards from the consumer chain to the provider chain.
Details* Set up a provider and consumer chain and completes the channel initialization.
* Send tokens into the FeeCollector on the consumer chain,
and check that these tokens distributed correctly across the provider and consumer chain.
* Check that the tokens are distributed purely on the consumer chain,
then advance the block height to make the consumer chain send a packet with rewards to the provider chain.
* Don't whitelist the consumer denom, so that the tokens stay in the ConsumerRewardsPool on the provider chain.
| + [TestSendRewardsRetries](../../tests/integration/distribution.go#L190) | TestSendRewardsRetries tests that failed reward transmissions are retried every BlocksPerDistributionTransmission blocks
Details* Set up a provider and consumer chain and complete the channel initialization.
* Fill the fee pool on the consumer chain, then corrupt the transmission channel
and try to send rewards to the provider chain, which should fail.
* Advance the block height to trigger a retry of the reward transmission, and confirm that this time, the transmission is successful.
| + [TestEndBlockRD](../../tests/integration/distribution.go#L272) | TestEndBlockRD tests that the last transmission block height is correctly updated after the expected number of block have passed.
Details* Set up CCV and transmission channels between the provider and consumer chains.
* Fill the fee pool on the consumer chain, prepare the system for reward
distribution, and optionally corrupt the transmission channel to simulate failure scenarios.
* After advancing the block height, verify whether the LBTH is updated correctly
and if the escrow balance changes as expected.
* Check that the IBC transfer states are discarded if the reward distribution
to the provider has failed.

Note: this method is effectively a unit test for EndBLockRD(), but is written as an integration test to avoid excessive mocking.
| + [TestSendRewardsToProvider](../../tests/integration/distribution.go#L395) | TestSendRewardsToProvider is effectively a unit test for SendRewardsToProvider(), but is written as an integration test to avoid excessive mocking.
Details* Set up CCV and transmission channels between the provider and consumer chains.
* Verify the SendRewardsToProvider() function under various scenarios and checks if the
function handles each scenario correctly by ensuring the expected number of token transfers.
| + [TestIBCTransferMiddleware](../../tests/integration/distribution.go#L542) | TestIBCTransferMiddleware tests the logic of the IBC transfer OnRecvPacket callback.
Details* Set up IBC and transfer channels.
* Simulate various scenarios of token transfers from the provider chain to
the consumer chain, and evaluate how the middleware processes these transfers.
* Ensure that token transfers are handled correctly and rewards are allocated as expected.
| + [TestAllocateTokens](../../tests/integration/distribution.go#L736) | TestAllocateTokens is a happy-path test of the consumer rewards pool allocation to opted-in validators and the community pool.
Details* Set up a provider chain and multiple consumer chains, and initialize the channels between them.
* Fund the consumer rewards pools on the provider chain and allocate rewards to the consumer chains.
* Begin a new block to cause rewards to be distributed to the validators and the community pool,
and check that the rewards are allocated as expected.
| + [TestAllocateTokensToConsumerValidators](../../tests/integration/distribution.go#L883) | TestAllocateTokensToConsumerValidators tests the allocation of tokens to consumer validators.
Details* The test exclusively uses the provider chain.
* Set up a current set of consumer validators, then call the AllocateTokensToConsumerValidators
function to allocate a number of tokens to the validators.
* Check that the expected number of tokens were allocated to the validators.
* The test covers the following scenarios:
- The tokens to be allocated are empty
- The consumer validator set is empty
- The tokens are allocated to a single validator
- The tokens are allocated to multiple validators
| + [TestAllocateTokensToConsumerValidatorsWithDifferentValidatorHeights](../../tests/integration/distribution.go#L1028) | TestAllocateTokensToConsumerValidatorsWithDifferentValidatorHeights tests AllocateTokensToConsumerValidators test with consumer validators that have different heights.
Details* Set up a context where the consumer validators have different join heights and verify that rewards are
correctly allocated only to validators who have been active long enough.
* Ensure that rewards are evenly distributed among eligible validators, that validators
can withdraw their rewards correctly, and that no rewards are allocated to validators
who do not meet the required join height criteria.
* Confirm that validators that have been consumer validators for some time receive rewards,
while validators that recently became consumer validators do not receive rewards.
| + [TestMultiConsumerRewardsDistribution](../../tests/integration/distribution.go#L1148) | TestMultiConsumerRewardsDistribution tests the rewards distribution of multiple consumers chains.
Details* Set up multiple consumer and transfer channels and verify the distribution of rewards from
various consumer chains to the provider's reward pool.
* Ensure that the consumer reward pools are correctly populated
and that rewards are properly transferred to the provider.
* Checks that the provider's reward pool balance reflects the accumulated
rewards from all consumer chains after processing IBC transfer packets and relaying
committed packets.
| +
+ +# [double_vote.go](../../tests/integration/double_vote.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestHandleConsumerDoubleVoting](../../tests/integration/double_vote.go#L23) | TestHandleConsumerDoubleVoting tests the handling of double voting evidence from the consumer chain.
Details* Set up a CCV channel.
* Create various double voting scenarios and submit those to the provider chain.
* Check if the provider chain correctly processes the evidence, jail and tombstone validators as needed, and apply the
correct slashing penalties.
* Verify that invalid evidence is properly rejected and does not result in incorrect penalties.
| + [TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations](../../tests/integration/double_vote.go#L283) | TestHandleConsumerDoubleVotingSlashesUndelegationsAndRelegations tests the handling of double voting evidence from the consumer chain and checks if slashing, undelegations, and redelegations are correctly processed.
Details* Set up a CCV channel.
* Create various double voting scenarios and submit those to the provider chain.
* Verify that the evidence is processed correctly.
* Ensure that the provider chain slashes the validator appropriately, and that it handles undelegations and redelegations accurately.
* Confirm that the validator’s staking status reflects these actions.
* Check if the slashing penalties are applied correctly and update the validator’s balance and delegations as expected.
| +
+ +# [expired_client.go](../../tests/integration/expired_client.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestVSCPacketSendExpiredClient](../../tests/integration/expired_client.go#L29) | TestVSCPacketSendExpiredClient tests queueing of VSCPackets when the consumer client is expired.
Details* Set up a CCV channel and expire the client on consumer chain.
* Bond tokens to provider, send CCV packet to consumer and check pending packets.
* While the consumer client is expired (or inactive for some reason) all packets will be queued.
* The packet sending and checks are then repeated.
* More tokens are bonded on provider to change validator powers.
* Upgrade expired client to the consumer and all packets are cleared once the consumer client is established.
| + [TestConsumerPacketSendExpiredClient](../../tests/integration/expired_client.go#L99) | TestConsumerPacketSendExpiredClient tests the consumer sending packets when the provider client is expired.
Details* Set up a CCV channel and bond tokens on provider.
* Send CCV packet to consumer and rebond tokens on provider.
* Check for pending VSC packets and relay all VSC packets to consumer.
* The provider client is then expired.
* Confirm that while the provider client is expired all packets will be queued and then cleared
once the provider client is upgraded.
| +
+ +# [key_assignment.go](../../tests/integration/key_assignment.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestKeyAssignment](../../tests/integration/key_assignment.go#L35) | TestKeyAssignment tests key assignments relayed from the provider chain to the consumer chain at different times in the protocol lifecycle.
DetailsEach test scenario sets up a provider chain and then assigns a key for a validator.
However, the assignment comes at different times in the protocol lifecycle.
The test covers the following scenarios:
* successfully assign the key before the CCV channel initialization is complete, then check that a VSCPacket is indeed queued
* successfully assign the key after the CCV channel initialization is complete
* successfully assign the key during an same epoch where the validator power changes
* get an error when assigning the same key twice in the same block by different validators
* get an error when assigning the same key twice in the same block by the same validator
* successfully assign two different keys in the same block by one validator
* get an error when assigning the same key twice in different blocks by different validators
* get an error when assigning the same key twice in different blocks by the same validator
For each scenario where the key assignment does not produce an error,
the test also checks that VSCPackets are relayed to the consumer chain and that the clients on
the provider and consumer chain can be updated.
TODO: Remove panics when unexpected error occurs.
| +
+ +# [misbehaviour.go](../../tests/integration/misbehaviour.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestHandleConsumerMisbehaviour](../../tests/integration/misbehaviour.go#L25) | TestHandleConsumerMisbehaviour tests the handling of consumer misbehavior.
Details* Set up a CCV channel and send an empty VSC packet to ensure that the consumer client revision height is greater than 0.
* Construct a Misbehaviour object with two conflicting headers and process the equivocation evidence.
* Verify that the provider chain correctly processes this misbehavior.
* Ensure that all involved validators are jailed, tombstoned, and slashed according to the expected outcomes.
* Assert that their tokens are adjusted based on the slashing fraction.
| + [TestGetByzantineValidators](../../tests/integration/misbehaviour.go#L101) | TestGetByzantineValidators checks the GetByzantineValidators function on various instances of misbehaviour.
Details* Set up a provider and consumer chain.
* Create a header with a subset of the validators on the consumer chain, then create a second header (in a variety of different ways),
and check which validators are considered Byzantine by calling the GetByzantineValidators function.
* The test scenarios are:
- when one of the headers is empty, the function should return an error
- when one of the headers has a corrupted validator set (e.g. by a validator having a different public key), the function should return an error
- when the signatures in one of the headers are corrupted, the function should return an error
- when the attack is an amnesia attack (i.e. the headers have different block IDs), no validator is considered byzantine
- for non-amnesia misbehaviour, all validators that signed both headers are considered byzantine
| + [TestCheckMisbehaviour](../../tests/integration/misbehaviour.go#L399) | TestCheckMisbehaviour tests that the CheckMisbehaviour function correctly checks for misbehaviour.
Details* Set up a provider and consumer chain.
* Create a valid client header and then create a misbehaviour by creating a second header in a variety of different ways.
* Check that the CheckMisbehaviour function correctly checks for misbehaviour by verifying that
it returns an error when the misbehaviour is invalid and no error when the misbehaviour is valid.
* The test scenarios are:
- both headers are identical (returns an error)
- the misbehaviour is not for the consumer chain (returns an error)
- passing an invalid client id (returns an error)
- passing a misbehaviour with different header height (returns an error)
- passing a misbehaviour older than the min equivocation evidence height (returns an error)
- one header of the misbehaviour has insufficient voting power (returns an error)
- passing a valid misbehaviour (no error)

* Test does not test actually submitting the misbehaviour to the chain or freezing the client.
| +
+ +# [normal_operations.go](../../tests/integration/normal_operations.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestHistoricalInfo](../../tests/integration/normal_operations.go#L19) | TestHistoricalInfo tests the tracking of historical information in the context of new blocks being committed.
Details* Save the initial number of CC validators and current block height.
* Add a new validator and then advance the blockchain by one block, triggering the tracking of historical information.
* Create 2 validators and then call TrackHistoricalInfo with header block height.
* Verify that historical information is pruned correctly and that the validator set is updated as expected.
* Check if the historical information is correctly handled and pruned based on the block height.
| +
+ +# [slashing.go](../../tests/integration/slashing.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestRelayAndApplyDowntimePacket](../../tests/integration/slashing.go#L50) | TestRelayAndApplyDowntimePacket tests that downtime slash packets can be properly relayed from consumer to provider, handled by provider, with a VSC and jailing eventually effective on consumer and provider.
Details* Set up CCV channels and retrieve consumer validators.
* Select a validator and create its consensus address.
* Retrieve the provider consensus address that corresponds to the consumer consensus address of the validator.
* The validator's current state is also retrieved, including its token balance,
* Set validator's signing information is to ensure it will be jailed for downtime.
* Create the slashing packet and send it from the consumer chain to the provider chain with a specified timeout.
* Receive the packet and verify that the validator was removed from the provider validator set.
* Relay VSC packets from the provider chain to each consumer chain and verify that the consumer chains correctly process these packets.
* Check the validator's balance and status on the provider chain to ensure it was jailed correctly but not slashed,
and its unjailing time is updated.
* Reset the outstanding downtime flag on the consumer chain, and ensure that the consumer
chain acknowledges receipt of the packet from the provider chain.

Note: This method does not test the actual slash packet sending logic for downtime
and double-signing, see TestValidatorDowntime and TestValidatorDoubleSigning for
those types of tests.
| + [TestSlashPacketAcknowledgement](../../tests/integration/slashing.go#L185) | TestSlashPacketAcknowledgement tests the handling of a slash packet acknowledgement.
Details* Set up a provider and consumer chain, with channel initialization between them performed.
* Send a slash packet with randomized fields from the consumer to the provider.
* The provider processes the packet
| + [TestHandleSlashPacketDowntime](../../tests/integration/slashing.go#L236) | TestHandleSlashPacketDowntime tests the handling of a downtime related slash packet, with integration tests.
Details* Retrieve a validator from provider chain's validators and checks if it's bonded.
* Set tThe signing information for the validator.
* The provider processes the downtime slashing packet from the consumer.
* Check that the validator has been jailed as a result of the downtime slashing packet being processed.
* Verify that the validator’s signing information is updated and that the jailing duration is set correctly.

Note that only downtime slash packets are processed by HandleSlashPacket.
| + [TestOnRecvSlashPacketErrors](../../tests/integration/slashing.go#L283) | TestOnRecvSlashPacketErrors tests errors for the OnRecvSlashPacket method in an integration testing setting.
Details* Set up all CCV channels and expect panic if the channel is not established via dest channel of packet.
* After the correct channelID is added to the packet, a panic shouldn't occur anymore.
* Create an instance of SlashPacketData and then verify correct processing and error handling
for slashing packets received by the provider chain.
TODO: Move to unit tests.
| + [TestValidatorDowntime](../../tests/integration/slashing.go#L412) | TestValidatorDowntime tests if a slash packet is sent and if the outstanding slashing flag is switched when a validator has downtime on the slashing module.
Details* Set up all CCV channel and send an empty VSC packet, then retrieve the address of a validator.
* Validator signs blocks for the duration of the signedBlocksWindow and a slash packet is constructed to be sent and committed.
* Simulate the validator missing blocks and then verify that the validator is jailed and the jailed time is correctly updated.
* Ensure that the missed block counters are reset.
* Check that there is a pending slash packet in the queue, and then send the pending packets.
* Check if slash record is created and verify that the consumer queue still contains the packet since no
acknowledgment has been received from the provider.
* Verify that the slash packet was sent and check that the outstanding slashing flag prevents the jailed validator to keep missing block.
| + [TestQueueAndSendSlashPacket](../../tests/integration/slashing.go#L533) | TestQueueAndSendSlashPacket tests the integration of QueueSlashPacket with SendPackets. In normal operation slash packets are queued in BeginBlock and sent in EndBlock.
Details* Set up all CCV channels and then queue slash packets for both downtime and double-signing infractions.
* Check that the correct number of slash requests are stored in the queue, including duplicates for downtime infractions.
* Prepare the CCV channel for sending actual slash packets.
* Send the slash packets and check that the outstanding downtime flags are correctly set for validators that were slashed
for downtime infractions.
* Ensure that the pending data packets queue is empty.
TODO: Move to unit tests.
| + [TestCISBeforeCCVEstablished](../../tests/integration/slashing.go#L618) | TestCISBeforeCCVEstablished tests that the consumer chain doesn't panic or have any undesired behavior when a slash packet is queued before the CCV channel is established. Then once the CCV channel is established, the slash packet should be sent soon after.
Details* Check that no pending packets exist and that there's no slash record found.
* Triggers a slashing event which queues a slash packet.
* The slash packet should be queued but not sent, and it should stay like that until the CCV channel is established and the packet is sent.
*Verify that a slashing record now exists, indicating that the slashing packet has been successfully sent.
| +
+ +# [stop_consumer.go](../../tests/integration/stop_consumer.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestStopConsumerChain](../../tests/integration/stop_consumer.go#L26) | TestStopConsumerChain tests the functionality of stopping a consumer chain at a higher level than unit tests.
Details* Retrieve a validator from the provider chain's validators and then the delegator address.
* Set up test operations, populating the provider chain states using the following operations:
- Setup CCV channels; establishes the CCV channel and sets channelToChain, chainToChannel, and initHeight mapping for the consumer chain ID.
- Delegate the total bond amount to the chosen validator.
- Undelegate the shares in four consecutive blocks evenly; create UnbondingOp and UnbondingOpIndex entries for the consumer chain ID.
- Set SlashAck state for the consumer chain ID.

* After, the setup operations are executed, and the consumer chain is stopped.
* Check that the state associated with the consumer chain is properly cleaned up after it is stopped.
| + [TestStopConsumerOnChannelClosed](../../tests/integration/stop_consumer.go#L117) | TestStopConsumerOnChannelClosed tests stopping a consumer chain correctly.
Details* Set up CCV channel and transfer channel, and send empty VSC packet.
* Stop the consumer chain and verify that the provider chain's channel end is closed.

TODO Simon: implement OnChanCloseConfirm in IBC-GO testing to close the consumer chain's channel end
| +
+ +# [throttle.go](../../tests/integration/throttle.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestBasicSlashPacketThrottling](../../tests/integration/throttle.go#L35) | TestBasicSlashPacketThrottling tests slash packet throttling with a single consumer, two slash packets, and no VSC matured packets. The most basic scenario.
Details* Set up various test cases, all CCV channels and validator powers.
* Retrieve the initial value of the slash meter, and the test verify it has the expected value.
* All validators are retrieved as well, and it's ensured that none of them are jailed from the start.
* Create a slash packet for the first validator and send it from the consumer to the provider.
* Asserts that validator 0 is jailed, has no power, and that the slash meter and allowance have the expected values.
* Then, create a second slash packet for a different validator, and check if the second validator is
not jailed after sending the second slash packet.
* Replenishes the slash meter until it is positive.
* Assert that validator 2 is jailed once the slash packet is retried and that it has no more voting power.
| + [TestMultiConsumerSlashPacketThrottling](../../tests/integration/throttle.go#L219) | TestMultiConsumerSlashPacketThrottling tests slash packet throttling in the context of multiple consumers sending slash packets to the provider, with VSC matured packets sprinkled around.
Details* Set up all CCV channels and validator powers.
* Choose three consumer bundles from the available bundles.
* Send the slash packets from each of the chosen consumer bundles to the provider chain. They will each slash a different validator.
* Confirm that the slash packet for the first consumer was handled first, and afterward, the slash packets for the second and
third consumers were bounced.
* Check the total power of validators in the provider chain to ensure it reflects the expected state after the first validator has been jailed.
* Replenish the slash meter and handle one of the two queued slash packet entries when both are retried.
* Verify again that the total power is updated.
* Replenish the slash meter one more time, and handle the final slash packet.
* Confirm that all validators are jailed.
| + [TestPacketSpam](../../tests/integration/throttle.go#L348) | TestPacketSpam confirms that the provider can handle a large number of incoming slash packets in a single block.
Details* Set up all CCV channels and validator powers.
* Set the parameters related to the handling of slash packets.
* Prepare the slash packets for the first three validators, and create 500 slash packets, alternating between
downtime and double-sign infractions.
* Simulate the reception of the 500 packets by the provider chain within the same block.
* Verify that the first three validators have been jailed as expected. This confirms that the
system correctly processed the slash packets and applied the penalties.
| + [TestDoubleSignDoesNotAffectThrottling](../../tests/integration/throttle.go#L420) | TestDoubleSignDoesNotAffectThrottling tests that a large number of double sign slash packets do not affect the throttling mechanism.
Details* Set up a scenario where 3 validators are slashed for double signing, and the 4th is not.
* Send 500 double sign slash packets from a consumer to the provider in a single block.
* Confirm that the slash meter is not affected by this, and that no validators are jailed.
| + [TestSlashingSmallValidators](../../tests/integration/throttle.go#L508) | TestSlashingSmallValidators tests that multiple slash packets from validators with small power can be handled by the provider chain in a non-throttled manner.
Details* Set up all CCV channels and delegate tokens to four validators, giving the first validator a larger amount of power.
* Initialize the slash meter, and verify that none of the validators are jailed before the slash packets are processed.
* Set up default signing information for the three smaller validators to prepare them for being jailed.
* The slash packets for the small validators are then constructed and sent.
* Verify validator powers after processing the slash packets.
* Confirm that the large validator remains unaffected and that the three smaller ones have been penalized and jailed.
| + [TestSlashMeterAllowanceChanges](../../tests/integration/throttle.go#L587) | TestSlashMeterAllowanceChanges tests scenarios where the slash meter allowance is expected to change.
Details* Set up all CCV channels, verify the initial slash meter allowance, and update the power of validators.
* Confirm that the value of the slash meter allowance is adjusted correctly after updating the validators' powers.
* Change the replenish fraction and assert the new expected allowance.

TODO: This should be a unit test, or replaced by TestTotalVotingPowerChanges.
| + [TestSlashAllValidators](../../tests/integration/throttle.go#L619) | TestSlashAllValidators is similar to TestSlashSameValidator, but 100% of validators' power is jailed in a single block.
Details* Set up all CCV channels and validator powers.
* Set the slash meter parameters.
* Create one slash packet for each validator, and then an additional five more for each validator
in order to test the system's ability to handle multiple slashing events in a single block.
* Receive and process each slashing packet in the provider chain and check that all validators are jailed as expected.

Note: This edge case should not occur in practice, but it is useful to validate that
the slash meter can allow any number of slash packets to be handled in a single block when
its allowance is set to "1.0".
| +
+ +# [throttle_retry.go](../../tests/integration/throttle_retry.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestSlashRetries](../../tests/integration/throttle_retry.go#L27) | TestSlashRetries tests the throttling v2 retry logic at an integration level.
Details* Set up the CCV channels and the provider.
* Retrieve the validators and ensure that none are initially jailed.
* Select two validators and set up their signing information.
* Set up the consumer, and then construct and queue a slashing packet for the first validator.
* Verify that the packet is sent.
* Receive the packet on the provider side and handle it.
* Confirm that the first validator has been jailed and check the provider's slash meter to ensure it reflects the correct state.
* Acknowledge the packet on the consumer chain, and verify that the slash record has been deleted and no pending packets remain.
* Confirm that packet sending is now permitted.
* Queue a second slashing packet for the second validator and verify its pending status.
* Handle the second packet, check that the second validator is jailed, and confirm
the final state of the slash record and pending packets on the consumer chain.
| +
+ +# [unbonding.go](../../tests/integration/unbonding.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestUndelegationCompletion](../../tests/integration/unbonding.go#L16) | TestUndelegationCompletion tests that undelegations complete after the unbonding period elapses on the provider, regardless of the consumer's state
Details* Set up CCV channel.
* Perform initial delegation of tokens followed by a partial undelegation (1/4 of the tokens).
* Verify that the staking unbonding operation is created as expected.
* Increment provider block height.
* Check that the unbonding operation has been completed.
* Verify that the token balances are correctly updated and the expected amount of tokens has been returned to the account.
| +
+ +# [valset_update.go](../../tests/integration/valset_update.go) +
Test Specifications + +| Function | Short Description | +|----------|-------------------| + [TestPacketRoundtrip](../../tests/integration/valset_update.go#L23) | TestPacketRoundtrip tests a CCV packet roundtrip when tokens are bonded on the provider.
Details* Set up CCV and transfer channels.
* Bond some tokens on the provider side in order to change validator power.
* Relay a packet from the provider chain to the consumer chain.
* Relays a matured packet from the consumer chain back to the provider chain.
| + [TestQueueAndSendVSCMaturedPackets](../../tests/integration/valset_update.go#L59) | TestQueueAndSendVSCMaturedPackets tests the behavior of EndBlock QueueVSCMaturedPackets call and its integration with SendPackets call.
Details* Set up CCV channel.
* Create and simulate the sending of three VSC packets from the provider chain to the consumer chain at different times.
* Send the first packet and validate its processing.
* Simulate the passage of one hour.
* Send the second packet and validate its processing.
* Simulate the passage of 24 more hours.
* Send the third packet and validate its processing.
* Retrieve all packet maturity times from the consumer, and use this to check the maturity status of the packets sent earlier.
* Advance the time so that the first two packets reach their unbonding period, while the third packet does not.
* Ensure first two packets are unbonded, their maturity times are deleted, and that VSCMatured packets are queued.
* The third packet is still in the store and has not yet been processed for unbonding.
* Checks that the packet commitments for the processed packets are correctly reflected in the consumer chain's state.
| +
+ diff --git a/tests/integration/slashing.go b/tests/integration/slashing.go index 111303cbcf..c4af871af4 100644 --- a/tests/integration/slashing.go +++ b/tests/integration/slashing.go @@ -410,16 +410,27 @@ func (suite *CCVTestSuite) TestOnRecvSlashPacketErrors() { // Expect the packet to bounce if the slash meter is negative providerKeeper.SetSlashMeter(ctx, math.NewInt(-1)) - // Only reaches the bouncing code if it fails in the check that chain is launched and the validator is not a consumer validator, - // so we set the chain as stopped. - providerKeeper.SetConsumerPhase(suite.providerCtx(), firstBundle.ConsumerId, providertypes.CONSUMER_PHASE_STOPPED) + // Only reaches the bouncing code if it fails in the check that chain is not launched and in the check that + // the validator is not a consumer validator. + providerKeeper.SetConsumerPhase(suite.providerCtx(), firstBundle.ConsumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + err = providerKeeper.SetConsumerValidator(ctx, firstBundle.ConsumerId, providertypes.ConsensusValidator{ + ProviderConsAddr: validAddress, + }) ackResult, err = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashPacketData) suite.Require().NoError(err) suite.Require().Equal(ccv.SlashPacketBouncedResult, ackResult, "expected bounced result") - // Expect packet not to bounce if the chain is launched + // Expect packet not to bounce if the chain is stopped + providerKeeper.SetSlashMeter(ctx, math.NewInt(-1)) + providerKeeper.SetConsumerPhase(suite.providerCtx(), firstBundle.ConsumerId, providertypes.CONSUMER_PHASE_STOPPED) + ackResult, err = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashPacketData) + suite.Require().NoError(err) + suite.Require().Equal(ccv.SlashPacketHandledResult, ackResult, "expected successful ack") + + // Expect packet not to bounce if the chain is launched but the validator is not a consumer validator providerKeeper.SetSlashMeter(ctx, math.NewInt(-1)) providerKeeper.SetConsumerPhase(suite.providerCtx(), firstBundle.ConsumerId, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.DeleteConsumerValidator(ctx, firstBundle.ConsumerId, providertypes.NewProviderConsAddress(sdk.ConsAddress(validAddress))) ackResult, err = providerKeeper.OnRecvSlashPacket(ctx, packet, *slashPacketData) suite.Require().Equal(ccv.SlashPacketHandledResult, ackResult, "expected successful ack") diff --git a/x/ccv/provider/keeper/relay.go b/x/ccv/provider/keeper/relay.go index cb251de3ee..f0fcb0f75a 100644 --- a/x/ccv/provider/keeper/relay.go +++ b/x/ccv/provider/keeper/relay.go @@ -343,10 +343,27 @@ func (k Keeper) OnRecvSlashPacket( return ccv.V1Result, nil } - // Check that chain is launched and the validator belongs to the consumer chain valset - if k.GetConsumerPhase(ctx, consumerId) == providertypes.CONSUMER_PHASE_LAUNCHED && !k.IsConsumerValidator(ctx, consumerId, providerConsAddr) { - k.Logger(ctx).Error("cannot jail validator %s that does not belong to consumer %s valset", - providerConsAddr.String(), consumerId) + // check that the chain is launched + if k.GetConsumerPhase(ctx, consumerId) != providertypes.CONSUMER_PHASE_LAUNCHED { + k.Logger(ctx).Info("cannot jail validator on a chain that is not currently launched", + "consumerId", consumerId, + "phase", k.GetConsumerPhase(ctx, consumerId), + "provider cons addr", providerConsAddr.String(), + ) + + // drop packet but return a slash ack + k.AppendSlashAck(ctx, consumerId, consumerConsAddr.String()) + + return ccv.SlashPacketHandledResult, nil + } + + // check that the validator belongs to the consumer chain valset + if !k.IsConsumerValidator(ctx, consumerId, providerConsAddr) { + k.Logger(ctx).Error("cannot jail validator that does not belong on the consumer valset", + "consumerId", consumerId, + "provider cons addr", providerConsAddr.String(), + ) + // drop packet but return a slash ack so that the consumer can send another slash packet k.AppendSlashAck(ctx, consumerId, consumerConsAddr.String()) diff --git a/x/ccv/provider/keeper/relay_test.go b/x/ccv/provider/keeper/relay_test.go index 7923056fe0..e63edea760 100644 --- a/x/ccv/provider/keeper/relay_test.go +++ b/x/ccv/provider/keeper/relay_test.go @@ -152,8 +152,14 @@ func TestOnRecvDowntimeSlashPacket(t *testing.T) { providerKeeper.SetParams(ctx, providertypes.DefaultParams()) // Set channel to chain (faking multiple established channels) - providerKeeper.SetChannelToConsumerId(ctx, "channel-1", "chain-1") - providerKeeper.SetChannelToConsumerId(ctx, "channel-2", "chain-2") + consumerId0 := "0" + channelId0 := "channel-0" + consumerId1 := "1" + channelId1 := "channel-1" + providerKeeper.SetChannelToConsumerId(ctx, channelId0, consumerId0) + providerKeeper.SetChannelToConsumerId(ctx, channelId1, consumerId1) + providerKeeper.SetConsumerPhase(ctx, consumerId0, providertypes.CONSUMER_PHASE_LAUNCHED) + providerKeeper.SetConsumerPhase(ctx, consumerId1, providertypes.CONSUMER_PHASE_LAUNCHED) // Generate a new slash packet data instance with double sign infraction type packetData := testkeeper.GetNewSlashPacketData() @@ -163,25 +169,25 @@ func TestOnRecvDowntimeSlashPacket(t *testing.T) { providerKeeper.SetValsetUpdateBlockHeight(ctx, packetData.ValsetUpdateId, uint64(15)) // Set consumer validator - err := providerKeeper.SetConsumerValidator(ctx, "chain-1", providertypes.ConsensusValidator{ + err := providerKeeper.SetConsumerValidator(ctx, consumerId0, providertypes.ConsensusValidator{ ProviderConsAddr: packetData.Validator.Address, }) require.NoError(t, err) // Set slash meter to negative value and assert a bounce ack is returned providerKeeper.SetSlashMeter(ctx, math.NewInt(-5)) - ackResult, err := executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-1", 1, packetData) + ackResult, err := executeOnRecvSlashPacket(t, &providerKeeper, ctx, channelId0, 1, packetData) require.Equal(t, ccv.SlashPacketBouncedResult, ackResult) require.NoError(t, err) // Set consumer validator - err = providerKeeper.SetConsumerValidator(ctx, "chain-2", providertypes.ConsensusValidator{ + err = providerKeeper.SetConsumerValidator(ctx, consumerId1, providertypes.ConsensusValidator{ ProviderConsAddr: packetData.Validator.Address, }) require.NoError(t, err) // Also bounced for chain-2 - ackResult, err = executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-2", 2, packetData) + ackResult, err = executeOnRecvSlashPacket(t, &providerKeeper, ctx, channelId1, 2, packetData) require.Equal(t, ccv.SlashPacketBouncedResult, ackResult) require.NoError(t, err) @@ -189,7 +195,7 @@ func TestOnRecvDowntimeSlashPacket(t *testing.T) { providerKeeper.SetSlashMeter(ctx, math.NewInt(5)) // Set the consumer validator - err = providerKeeper.SetConsumerValidator(ctx, "chain-1", providertypes.ConsensusValidator{ProviderConsAddr: packetData.Validator.Address}) + err = providerKeeper.SetConsumerValidator(ctx, consumerId0, providertypes.ConsensusValidator{ProviderConsAddr: packetData.Validator.Address}) require.NoError(t, err) // Mock call to GetEffectiveValPower, so that it returns 2. @@ -213,7 +219,7 @@ func TestOnRecvDowntimeSlashPacket(t *testing.T) { gomock.InOrder(calls...) // Execute on recv and confirm slash packet handled result is returned - ackResult, err = executeOnRecvSlashPacket(t, &providerKeeper, ctx, "channel-1", 1, packetData) + ackResult, err = executeOnRecvSlashPacket(t, &providerKeeper, ctx, channelId0, 1, packetData) require.Equal(t, ccv.SlashPacketHandledResult, ackResult) require.NoError(t, err)