diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 94841fe4ba..10d81a95d6 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -15,15 +15,14 @@ jobs: # Install Ignite - name: ignite install - uses: nick-fields/retry@v2 - with: - max_attempts: 3 - retry_on: error - timeout_minutes: 20 - command: git clone --depth 1 --branch v0.22.2 https://github.com/ignite/cli && cd cli && make install - + run: git clone --depth 1 --branch v0.22.2 https://github.com/ignite/cli && cd cli && make install + # run: curl https://get.ignite.com/cli! | bash - name: ignite version run: ignite version + # - name: starport install + # run: curl https://get.starport.network/starport@v0.19.2! | bash + # - name: starport version + # run: starport version # Setup Paths - name: home @@ -188,4 +187,4 @@ jobs: - name: GRPC Consumer Error Only Logs if: always() continue-on-error: true - run: cat testutil/e2e/logs/11_grpcConsumer_errors.log \ No newline at end of file + run: cat testutil/e2e/logs/11_grpcConsumer_errors.log diff --git a/app/app.go b/app/app.go index 4245a728e4..5f02207dde 100644 --- a/app/app.go +++ b/app/app.go @@ -88,6 +88,7 @@ import ( "github.com/lavanet/lava/app/upgrades" "github.com/lavanet/lava/app/upgrades/v0_5_0" "github.com/lavanet/lava/app/upgrades/v0_5_1" + "github.com/lavanet/lava/app/upgrades/v0_5_2" "github.com/lavanet/lava/docs" conflictmodule "github.com/lavanet/lava/x/conflict" conflictmodulekeeper "github.com/lavanet/lava/x/conflict/keeper" @@ -117,7 +118,7 @@ const ( ) // Upgrades add here future upgrades (upgrades.Upgrade) -var Upgrades = []upgrades.Upgrade{upgrades.Upgrade_0_4_0, upgrades.Upgrade_0_4_3, upgrades.Upgrade_0_4_4, upgrades.Upgrade_0_4_5, v0_5_0.Upgrade, v0_5_1.Upgrade} +var Upgrades = []upgrades.Upgrade{upgrades.Upgrade_0_4_0, upgrades.Upgrade_0_4_3, upgrades.Upgrade_0_4_4, upgrades.Upgrade_0_4_5, v0_5_0.Upgrade, v0_5_1.Upgrade, v0_5_2.Upgrade} // this line is used by starport scaffolding # stargate/wasm/app/enabledProposals diff --git a/app/upgrades/v0_5_2/upgrade.go b/app/upgrades/v0_5_2/upgrade.go new file mode 100644 index 0000000000..4906d1d8e7 --- /dev/null +++ b/app/upgrades/v0_5_2/upgrade.go @@ -0,0 +1,39 @@ +package v0_5_2 + +import ( + "log" + + store "github.com/cosmos/cosmos-sdk/store/types" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/types/module" + upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types" + "github.com/lavanet/lava/app/keepers" + "github.com/lavanet/lava/app/upgrades" + pairingtypes "github.com/lavanet/lava/x/pairing/types" +) + +const UpgradeName = "v0.5.2" + +var Upgrade = upgrades.Upgrade{ + UpgradeName: UpgradeName, // upgrade name defined few lines above + CreateUpgradeHandler: CreateUpgradeHandler, // create CreateUpgradeHandler in upgrades.go below + StoreUpgrades: store.StoreUpgrades{}, // StoreUpgrades has 3 fields: Added/Renamed/Deleted any module that fits these description should be added in the way below +} + +func CreateUpgradeHandler( + mm *module.Manager, + configurator module.Configurator, + bpm upgrades.BaseAppParamManager, + keepers *keepers.LavaKeepers, +) upgradetypes.UpgradeHandler { + return func(ctx sdk.Context, plan upgradetypes.Plan, vm module.VersionMap) (module.VersionMap, error) { + log.Println("########################") + log.Println("# STARTING UPGRADE #") + log.Println("########################") + + // we use a dedicated SET since the upgrade package doesn't have access to the paramstore, thus can't set a parameter directly + keepers.PairingKeeper.SetRecommendedEpochNumToCollectPayment(ctx, pairingtypes.DefaultRecommendedEpochNumToCollectPayment) + + return mm.RunMigrations(ctx, configurator, vm) + } +} diff --git a/proto/pairing/params.proto b/proto/pairing/params.proto index f1ea987e34..ec8e8f4ff0 100644 --- a/proto/pairing/params.proto +++ b/proto/pairing/params.proto @@ -54,4 +54,5 @@ message Params { (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Dec", (gogoproto.nullable) = false ]; + uint64 recommendedEpochNumToCollectPayment = 14 [(gogoproto.moretags) = "yaml:\"recommended_epoch_num_to_collect_payment\""]; } \ No newline at end of file diff --git a/proto/pairing/provider_payment_storage.proto b/proto/pairing/provider_payment_storage.proto index 9d5d346331..1cbed1db3f 100644 --- a/proto/pairing/provider_payment_storage.proto +++ b/proto/pairing/provider_payment_storage.proto @@ -5,11 +5,13 @@ option go_package = "github.com/lavanet/lava/x/pairing/types"; import "pairing/unique_payment_storage_client_provider.proto"; message ProviderPaymentStorage { + string index = 1; reserved 2; uint64 epoch = 3; - repeated string unresponsiveness_complaints = 4; + reserved 4; repeated string uniquePaymentStorageClientProviderKeys = 5; + uint64 complainersTotalCu = 6; // total CU that were supposed to be served by the provider but didn't because he was unavailable (so consumers complained about him) } // change Client -> consumer diff --git a/testutil/keeper/keepers_init.go b/testutil/keeper/keepers_init.go index e0c6b14917..ae3fa2fa8e 100644 --- a/testutil/keeper/keepers_init.go +++ b/testutil/keeper/keepers_init.go @@ -18,6 +18,7 @@ import ( conflicttypes "github.com/lavanet/lava/x/conflict/types" epochstoragekeeper "github.com/lavanet/lava/x/epochstorage/keeper" epochstoragetypes "github.com/lavanet/lava/x/epochstorage/types" + "github.com/lavanet/lava/x/pairing" pairingkeeper "github.com/lavanet/lava/x/pairing/keeper" pairingtypes "github.com/lavanet/lava/x/pairing/types" "github.com/lavanet/lava/x/spec" @@ -31,7 +32,9 @@ import ( tmdb "github.com/tendermint/tm-db" ) -const BLOCK_TIME = 30 * time.Second +const ( + BLOCK_TIME = 30 * time.Second +) const BLOCK_HEADER_LEN = 32 @@ -214,20 +217,9 @@ func AdvanceEpoch(ctx context.Context, ks *Keepers, customBlockTime ...time.Dura // Make sure you save the new context func NewBlock(ctx context.Context, ks *Keepers, customTime ...time.Duration) { unwrapedCtx := sdk.UnwrapSDKContext(ctx) - block := uint64(unwrapedCtx.BlockHeight()) if ks.Epochstorage.IsEpochStart(sdk.UnwrapSDKContext(ctx)) { - ks.Epochstorage.FixateParams(unwrapedCtx, block) - // begin block - ks.Epochstorage.SetEpochDetailsStart(unwrapedCtx, block) - ks.Epochstorage.StoreCurrentEpochStakeStorage(unwrapedCtx, block, epochstoragetypes.ProviderKey) - ks.Epochstorage.StoreCurrentEpochStakeStorage(unwrapedCtx, block, epochstoragetypes.ClientKey) - - ks.Epochstorage.UpdateEarliestEpochstart(unwrapedCtx) - ks.Epochstorage.RemoveOldEpochData(unwrapedCtx, epochstoragetypes.ProviderKey) - ks.Epochstorage.RemoveOldEpochData(unwrapedCtx, epochstoragetypes.ClientKey) - - ks.Pairing.RemoveOldEpochPayment(unwrapedCtx) - ks.Pairing.CheckUnstakingForCommit(unwrapedCtx) + ks.Epochstorage.EpochStart(unwrapedCtx) + ks.Pairing.EpochStart(unwrapedCtx, pairing.EPOCHS_NUM_TO_CHECK_CU_FOR_UNRESPONSIVE_PROVIDER, pairing.EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS) } ks.Conflict.CheckAndHandleAllVotes(unwrapedCtx) diff --git a/x/epochstorage/keeper/epoch_start.go b/x/epochstorage/keeper/epoch_start.go new file mode 100644 index 0000000000..9e433a6cf9 --- /dev/null +++ b/x/epochstorage/keeper/epoch_start.go @@ -0,0 +1,32 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/x/epochstorage/types" +) + +// Function that calls all the functions that are supposed to run in epoch start +func (k Keeper) EpochStart(ctx sdk.Context) { + block := uint64(ctx.BlockHeight()) + + // save params for this epoch + k.FixateParams(ctx, block) + + // on Epoch start we need to do: + // 1. update Epoch start + // 2. update the StakeStorage + // on epoch start block end: (because other modules need this info) to clear their storages + // 3. remove old StakeStorage + // 4. update earliest epoch start + + k.SetEpochDetailsStart(ctx, block) + + k.StoreCurrentEpochStakeStorage(ctx, block, types.ProviderKey) + + k.StoreCurrentEpochStakeStorage(ctx, block, types.ClientKey) + + k.UpdateEarliestEpochstart(ctx) + + k.RemoveOldEpochData(ctx, types.ProviderKey) + k.RemoveOldEpochData(ctx, types.ClientKey) +} diff --git a/x/epochstorage/module.go b/x/epochstorage/module.go index 8e4f73e336..e7e3c8fb50 100644 --- a/x/epochstorage/module.go +++ b/x/epochstorage/module.go @@ -169,28 +169,8 @@ func (AppModule) ConsensusVersion() uint64 { return 2 } // BeginBlock executes all ABCI BeginBlock logic respective to the capability module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { if am.keeper.IsEpochStart(ctx) { - block := uint64(ctx.BlockHeight()) - - // save params for this epoch - am.keeper.FixateParams(ctx, block) - - // on Epoch start we need to do: - // 1. update Epoch start - // 2. update the StakeStorage - // on epoch start block end: (because other modules need this info) to clear their storages - // 3. remove old StakeStorage - // 4. update earliest epoch start - - am.keeper.SetEpochDetailsStart(ctx, block) - - am.keeper.StoreCurrentEpochStakeStorage(ctx, block, types.ProviderKey) - - am.keeper.StoreCurrentEpochStakeStorage(ctx, block, types.ClientKey) - - am.keeper.UpdateEarliestEpochstart(ctx) - - am.keeper.RemoveOldEpochData(ctx, types.ProviderKey) - am.keeper.RemoveOldEpochData(ctx, types.ClientKey) + // run functions that are supposed to run in epoch start + am.keeper.EpochStart(ctx) // Notify world we have a new session diff --git a/x/pairing/keeper/epoch_payments_test.go b/x/pairing/keeper/epoch_payments_test.go index 1d4b4854fc..a20b5f29e6 100644 --- a/x/pairing/keeper/epoch_payments_test.go +++ b/x/pairing/keeper/epoch_payments_test.go @@ -39,6 +39,7 @@ func TestEpochPaymentsGet(t *testing.T) { ) } } + func TestEpochPaymentsRemove(t *testing.T) { keeper, ctx := keepertest.PairingKeeper(t) items := createNEpochPayments(keeper, ctx, 10) diff --git a/x/pairing/keeper/epoch_start.go b/x/pairing/keeper/epoch_start.go new file mode 100644 index 0000000000..86b18b5ff7 --- /dev/null +++ b/x/pairing/keeper/epoch_start.go @@ -0,0 +1,34 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/utils" +) + +// Function that calls all the functions that are supposed to run in epoch start +func (k Keeper) EpochStart(ctx sdk.Context, epochsNumToCheckCuForUnresponsiveProvider uint64, epochsNumToCheckForComplainers uint64) { + logger := k.Logger(ctx) + logOnErr := func(err error, failingFunc string) { + if err != nil { + attrs := map[string]string{"error": err.Error()} + utils.LavaError(ctx, logger, "new_epoch", attrs, failingFunc) + } + } + // on session start we need to do: + // 1. remove old session payments + // 2. unstake any unstaking providers + // 3. unstake any unstaking users + // 4. unstake/jail unresponsive providers + + // 1. + err := k.RemoveOldEpochPayment(ctx) + logOnErr(err, "RemoveOldEpochPayment") + + // 2+3. + err = k.CheckUnstakingForCommit(ctx) + logOnErr(err, "CheckUnstakingForCommit") + + // 4. unstake unresponsive providers + err = k.UnstakeUnresponsiveProviders(ctx, epochsNumToCheckCuForUnresponsiveProvider, epochsNumToCheckForComplainers) + logOnErr(err, "UnstakeUnresponsiveProviders") +} diff --git a/x/pairing/keeper/fixation_test.go b/x/pairing/keeper/fixation_test.go index 5cf52a264d..9ce379773f 100644 --- a/x/pairing/keeper/fixation_test.go +++ b/x/pairing/keeper/fixation_test.go @@ -26,10 +26,10 @@ func TestServicersToPair(t *testing.T) { tests := []struct { name string - Block uint64 //advance test to this block - ServicersToPair uint64 //set this if not zero at the start of the test + Block uint64 // advance test to this block + ServicersToPair uint64 // set this if not zero at the start of the test ExpectedServicersToPair uint64 - NumOfFixation int //expected number of fixations in the memory + NumOfFixation int // expected number of fixations in the memory }{ {"FillHalfMemory", blocksInMemory / 2, 0, servicersToParCount, 1}, {"ParamChange", blocksInMemory / 2, 2 * servicersToParCount, servicersToParCount, 1}, @@ -84,14 +84,12 @@ func TestServicersToPair(t *testing.T) { Block uint64 ExpectedServicersToPair uint64 }{Block: tt.Block, ExpectedServicersToPair: tt.ExpectedServicersToPair}) - }) } } func TestEpochPaymentDeletionWithMemoryShortening(t *testing.T) { - - ts := setupForPaymentTest(t) //reset the keepers state before each state + ts := setupForPaymentTest(t) // reset the keepers state before each state ts.spec = common.CreateMockSpec() ts.keepers.Spec.SetSpec(sdk.UnwrapSDKContext(ts.ctx), ts.spec) err := ts.addClient(1) @@ -120,18 +118,18 @@ func TestEpochPaymentDeletionWithMemoryShortening(t *testing.T) { relayRequest.Sig = sig require.Nil(t, err) - //make payment request + // make payment request _, err = ts.servers.PairingServer.RelayPayment(ts.ctx, &pairingtypes.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: []*pairingtypes.RelayRequest{relayRequest}}) require.Nil(t, err) - //shorten memory + // shorten memory err = testkeeper.SimulateParamChange(sdk.UnwrapSDKContext(ts.ctx), ts.keepers.ParamsKeeper, epochstoragetypes.ModuleName, string(epochstoragetypes.KeyEpochsToSave), "\""+strconv.FormatUint(epochsToSave/2, 10)+"\"") require.NoError(t, err) - //advance epoch + // advance epoch ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) - //make another request + // make another request relayRequest.SessionId++ sig, err = sigs.SignRelay(ts.clients[0].secretKey, *relayRequest) @@ -141,14 +139,13 @@ func TestEpochPaymentDeletionWithMemoryShortening(t *testing.T) { _, err = ts.servers.PairingServer.RelayPayment(ts.ctx, &pairingtypes.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: []*pairingtypes.RelayRequest{relayRequest}}) require.Nil(t, err) - //check that both payments were deleted + // check that both payments were deleted for i := 0; i < int(epochsToSave); i++ { ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) } - //check second payment was deleted + // check second payment was deleted ans, err := ts.keepers.Pairing.EpochPaymentsAll(ts.ctx, &pairingtypes.QueryAllEpochPaymentsRequest{}) require.Nil(t, err) require.Equal(t, 0, len(ans.EpochPayments)) - } diff --git a/x/pairing/keeper/msg_server_relay_payment.go b/x/pairing/keeper/msg_server_relay_payment.go index 8bf3a79014..c45cc02460 100644 --- a/x/pairing/keeper/msg_server_relay_payment.go +++ b/x/pairing/keeper/msg_server_relay_payment.go @@ -12,7 +12,6 @@ import ( epochstoragetypes "github.com/lavanet/lava/x/epochstorage/types" "github.com/lavanet/lava/x/pairing/types" "github.com/tendermint/tendermint/libs/log" - "golang.org/x/exp/slices" ) const ( @@ -262,9 +261,14 @@ func (k msgServer) RelayPayment(goCtx context.Context, msg *types.MsgRelayPaymen details["relayNumber"] = strconv.FormatUint(relay.RelayNum, 10) utils.LogLavaEvent(ctx, logger, types.RelayPaymentEventName, details, "New Proof Of Work Was Accepted") - // - // deal with unresponsive providers - err = k.dealWithUnresponsiveProviders(ctx, relay.UnresponsiveProviders, logger, clientAddr, epochStart, relay.ChainID) + // Get servicersToPair param + servicersToPair, err := k.ServicersToPairCount(ctx, epochStart) + if err != nil { + return nil, utils.LavaError(ctx, k.Logger(ctx), "get_servicers_to_pair", map[string]string{"err": err.Error(), "epoch": fmt.Sprintf("%+v", epochStart)}, "couldn't get servicers to pair") + } + + // update provider payment storage with complainer's CU + err = k.updateProviderPaymentStorageWithComplainerCU(ctx, relay.UnresponsiveProviders, logger, epochStart, relay.ChainID, relay.CuSum, servicersToPair, clientAddr) if err != nil { utils.LogLavaEvent(ctx, logger, types.UnresponsiveProviderUnstakeFailedEventName, map[string]string{"err:": err.Error()}, "Error Unresponsive Providers could not unstake") } @@ -272,105 +276,78 @@ func (k msgServer) RelayPayment(goCtx context.Context, msg *types.MsgRelayPaymen return &types.MsgRelayPaymentResponse{}, nil } -func (k msgServer) dealWithUnresponsiveProviders(ctx sdk.Context, unresponsiveData []byte, logger log.Logger, clientAddr sdk.AccAddress, epoch uint64, chainID string) error { +func (k msgServer) updateProviderPaymentStorageWithComplainerCU(ctx sdk.Context, unresponsiveData []byte, logger log.Logger, epoch uint64, chainID string, cuSum uint64, servicersToPair uint64, clientAddr sdk.AccAddress) error { var unresponsiveProviders []string + + // check that unresponsiveData exists if len(unresponsiveData) == 0 { return nil } + + // check that servicersToPair is bigger than 1 + if servicersToPair <= 1 { + servicersToPair = 2 + } + + // unmarshal the byte array unresponsiveData to get a list of unresponsive providers Bech32 addresses err := json.Unmarshal(unresponsiveData, &unresponsiveProviders) if err != nil { return utils.LavaFormatError("unable to unmarshal unresponsive providers", err, &map[string]string{"UnresponsiveProviders": string(unresponsiveData), "dataLength": strconv.Itoa(len(unresponsiveData))}) } + + // check there are unresponsive providers if len(unresponsiveProviders) == 0 { // nothing to do. return nil } + + // the added complainer CU takes into account the number of providers the client complained on and the number + complainerCuToAdd := cuSum / (uint64(len(unresponsiveProviders)) * (servicersToPair - 1)) + + // iterate over the unresponsive providers list and update their complainers_total_cu for _, unresponsiveProvider := range unresponsiveProviders { + // get provider address sdkUnresponsiveProviderAddress, err := sdk.AccAddressFromBech32(unresponsiveProvider) if err != nil { // if bad data was given, we cant parse it so we ignote it and continue this protects from spamming wrong information. utils.LavaFormatError("unable to sdk.AccAddressFromBech32(unresponsive_provider)", err, &map[string]string{"unresponsive_provider_address": unresponsiveProvider}) continue } - existingEntry, entryExists, indexInStakeStorage := k.epochStorageKeeper.GetStakeEntryByAddressCurrent(ctx, epochstoragetypes.ProviderKey, chainID, sdkUnresponsiveProviderAddress) - // if !entryExists provider is alraedy unstaked - if !entryExists { - continue // if provider is not staked, nothing to do. + + // get this epoch's epochPayments object + epochPayments, found, key := k.GetEpochPaymentsFromBlock(ctx, epoch) + if !found { + // the epochPayments object should exist since we already paid. if not found, print an error and continue + utils.LavaFormatError("did not find epochPayments object", err, &map[string]string{"epochPaymentskey": key}) + continue } + // get the providerPaymentStorage object using the providerStorageKey providerStorageKey := k.GetProviderPaymentStorageKey(ctx, chainID, epoch, sdkUnresponsiveProviderAddress) providerPaymentStorage, found := k.GetProviderPaymentStorage(ctx, providerStorageKey) if !found { - // currently this provider has not payments in this epoch and also no complaints, we need to add one complaint here + // providerPaymentStorage not found (this provider has no payments in this epoch and also no complaints) -> we need to add one complaint emptyProviderPaymentStorageWithComplaint := types.ProviderPaymentStorage{ Index: providerStorageKey, UniquePaymentStorageClientProviderKeys: []string{}, Epoch: epoch, - UnresponsivenessComplaints: []string{clientAddr.String()}, + ComplainersTotalCu: uint64(0), } - k.SetProviderPaymentStorage(ctx, emptyProviderPaymentStorageWithComplaint) - continue - } - // providerPaymentStorage was found for epoch, start analyzing if unstake is necessary - // check if the same consumer is trying to complain a second time for this epoch - if slices.Contains(providerPaymentStorage.UnresponsivenessComplaints, clientAddr.String()) { - continue - } - providerPaymentStorage.UnresponsivenessComplaints = append(providerPaymentStorage.UnresponsivenessComplaints, clientAddr.String()) + // append the emptyProviderPaymentStorageWithComplaint to the epochPayments object's providerPaymentStorages + epochPayments.ProviderPaymentStorageKeys = append(epochPayments.GetProviderPaymentStorageKeys(), emptyProviderPaymentStorageWithComplaint.GetIndex()) + k.SetEpochPayments(ctx, epochPayments) - // now we check if we have more UnresponsivenessComplaints than maxComplaintsPerEpoch - if len(providerPaymentStorage.UnresponsivenessComplaints) >= maxComplaintsPerEpoch { - // we check if we have double complaints than previous "collectPaymentsFromNumberOfPreviousEpochs" epochs (including this one) payment requests - totalPaymentsInPreviousEpochs, err := k.getTotalPaymentsForPreviousEpochs(ctx, collectPaymentsFromNumberOfPreviousEpochs, epoch, chainID, sdkUnresponsiveProviderAddress) - totalPaymentRequests := totalPaymentsInPreviousEpochs + len(providerPaymentStorage.UniquePaymentStorageClientProviderKeys) // get total number of payments including this epoch - if err != nil { - utils.LavaFormatError("lava_unresponsive_providers: couldnt fetch getTotalPaymentsForPreviousEpochs", err, nil) - } else if totalPaymentRequests*providerPaymentMultiplier < len(providerPaymentStorage.UnresponsivenessComplaints) { - // unstake provider - utils.LogLavaEvent(ctx, logger, types.ProviderJailedEventName, map[string]string{"provider_address": sdkUnresponsiveProviderAddress.String(), "chain_id": chainID}, "Unresponsive provider was unstaked from the chain due to unresponsiveness") - err = k.unSafeUnstakeProviderEntry(ctx, epochstoragetypes.ProviderKey, chainID, indexInStakeStorage, existingEntry) - if err != nil { - utils.LavaFormatError("unable to unstake provider entry (unsafe method)", err, &map[string]string{"chainID": chainID, "indexInStakeStorage": strconv.FormatUint(indexInStakeStorage, 10), "existingEntry": existingEntry.GetStake().String()}) - continue - } - } + // assign providerPaymentStorage with the new empty providerPaymentStorage + providerPaymentStorage = emptyProviderPaymentStorageWithComplaint } - // set the final provider payment storage state including the complaints - k.SetProviderPaymentStorage(ctx, providerPaymentStorage) - } - return nil -} -func (k msgServer) getTotalPaymentsForPreviousEpochs(ctx sdk.Context, numberOfEpochs int, currentEpoch uint64, chainID string, sdkUnresponsiveProviderAddress sdk.AccAddress) (totalPaymentsReceived int, errorsGettingEpochs error) { - var totalPaymentRequests int - epochTemp := currentEpoch - for payment := 0; payment < numberOfEpochs; payment++ { - previousEpoch, err := k.epochStorageKeeper.GetPreviousEpochStartForBlock(ctx, epochTemp) - if err != nil { - return 0, err - } - previousEpochProviderStorageKey := k.GetProviderPaymentStorageKey(ctx, chainID, previousEpoch, sdkUnresponsiveProviderAddress) - previousEpochProviderPaymentStorage, providerPaymentStorageFound := k.GetProviderPaymentStorage(ctx, previousEpochProviderStorageKey) - if providerPaymentStorageFound { - totalPaymentRequests += len(previousEpochProviderPaymentStorage.UniquePaymentStorageClientProviderKeys) // increase by the amount of previous epoch - } - epochTemp = previousEpoch - } - return totalPaymentRequests, nil -} - -func (k msgServer) unSafeUnstakeProviderEntry(ctx sdk.Context, providerKey string, chainID string, indexInStakeStorage uint64, existingEntry epochstoragetypes.StakeEntry) error { - err := k.epochStorageKeeper.RemoveStakeEntryCurrent(ctx, epochstoragetypes.ProviderKey, chainID, indexInStakeStorage) - if err != nil { - return utils.LavaError(ctx, k.Logger(ctx), "relay_payment_unstake", map[string]string{"existingEntry": fmt.Sprintf("%+v", existingEntry)}, "tried to unstake unsafe but didnt find entry") - } + // add complainer's used CU to providerPaymentStorage + providerPaymentStorage.ComplainersTotalCu += complainerCuToAdd - unstakeHoldBlocks, err := k.unstakeHoldBlocks(ctx, existingEntry.Chain, true) - if err != nil { - return err + // set the final provider payment storage state including the complaints + k.SetProviderPaymentStorage(ctx, providerPaymentStorage) } - k.epochStorageKeeper.AppendUnstakeEntry(ctx, epochstoragetypes.ProviderKey, existingEntry, unstakeHoldBlocks) return nil } diff --git a/x/pairing/keeper/msg_server_relay_payment_gov_test.go b/x/pairing/keeper/msg_server_relay_payment_gov_test.go index d8af13596c..16be3cecb0 100644 --- a/x/pairing/keeper/msg_server_relay_payment_gov_test.go +++ b/x/pairing/keeper/msg_server_relay_payment_gov_test.go @@ -15,7 +15,6 @@ import ( // Test that if the QosWeight param changes before the provider collected its reward, the provider's payment is according to the last QosWeight value (QosWeight is not fixated) // Provider reward formula: reward = reward*(QOSScore*QOSWeight + (1-QOSWeight)) func TestRelayPaymentGovQosWeightChange(t *testing.T) { - // setup testnet with mock spec, a staked client and a staked provider ts := setupForPaymentTest(t) @@ -64,7 +63,6 @@ func TestRelayPaymentGovQosWeightChange(t *testing.T) { for ti, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Create relay request that was done in the test's epoch. Change session ID each iteration to avoid double spending error (provider asks reward for the same transaction twice) relayRequest := &pairingtypes.RelayRequest{ Provider: ts.providers[0].address.String(), @@ -123,7 +121,6 @@ func TestRelayPaymentGovQosWeightChange(t *testing.T) { // Test that if the EpochBlocks param decreases make sure the provider can claim reward after the new EpochBlocks*EpochsToSave, and not the original EpochBlocks (EpochBlocks = number of blocks in an epoch) func TestRelayPaymentGovEpochBlocksDecrease(t *testing.T) { - // setup testnet with mock spec, stake a client and a provider ts := setupForPaymentTest(t) @@ -171,7 +168,6 @@ func TestRelayPaymentGovEpochBlocksDecrease(t *testing.T) { for ti, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Create relay request that was done in the test's epoch. Change session ID each iteration to avoid double spending error (provider asks reward for the same transaction twice) relayRequest := &pairingtypes.RelayRequest{ Provider: ts.providers[0].address.String(), @@ -198,13 +194,11 @@ func TestRelayPaymentGovEpochBlocksDecrease(t *testing.T) { payAndVerifyBalance(t, ts, relayPaymentMessage, tt.valid, ts.clients[0].address, ts.providers[0].address) }) } - } // TODO: Currently the test passes since PaymentBeforeEpochBlocksChangesToFifty's value is false. It should be true. After bug CNS-83 is fixed, change this test // Test that if the EpochBlocks param increases make sure the provider can claim reward after the new EpochBlocks*EpochsToSave, and not the original EpochBlocks (EpochBlocks = number of blocks in an epoch) func TestRelayPaymentGovEpochBlocksIncrease(t *testing.T) { - // setup testnet with mock spec, stake a client and a provider ts := setupForPaymentTest(t) @@ -256,7 +250,6 @@ func TestRelayPaymentGovEpochBlocksIncrease(t *testing.T) { for ti, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Create relay request that was done in the test's epoch+block. Change session ID each iteration to avoid double spending error (provider asks reward for the same transaction twice) relayRequest := &pairingtypes.RelayRequest{ Provider: ts.providers[0].address.String(), @@ -283,12 +276,10 @@ func TestRelayPaymentGovEpochBlocksIncrease(t *testing.T) { payAndVerifyBalance(t, ts, relayPaymentMessage, tt.valid, ts.clients[0].address, ts.providers[0].address) }) } - } // Test that if the EpochToSave param decreases make sure the provider can claim reward after the new EpochBlocks*EpochsToSave, and not the original EpochBlocks (EpochsToSave = number of epochs the chain remembers (accessible memory)) func TestRelayPaymentGovEpochToSaveDecrease(t *testing.T) { - // setup testnet with mock spec, stake a client and a provider ts := setupForPaymentTest(t) @@ -341,7 +332,6 @@ func TestRelayPaymentGovEpochToSaveDecrease(t *testing.T) { for ti, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // advance to one block to reach the start of the newDecreasedEpochsToSave+1 epoch -> the provider from epochAfterChange shouldn't be able to get its payments (epoch out of memory) if ti == 2 { ts.ctx = testkeeper.AdvanceBlock(ts.ctx, ts.keepers) @@ -373,13 +363,11 @@ func TestRelayPaymentGovEpochToSaveDecrease(t *testing.T) { payAndVerifyBalance(t, ts, relayPaymentMessage, tt.valid, ts.clients[0].address, ts.providers[0].address) }) } - } // TODO: Currently the test passes since PaymentBeforeEpochsToSaveChangesToTwenty's value is false. It should be true. After bug CNS-83 is fixed, change this test // Test that if the EpochToSave param increases make sure the provider can claim reward after the new EpochBlocks*EpochsToSave, and not the original EpochBlocks (EpochsToSave = number of epochs the chain remembers (accessible memory)) func TestRelayPaymentGovEpochToSaveIncrease(t *testing.T) { - // setup testnet with mock spec, stake a client and a provider ts := setupForPaymentTest(t) @@ -425,7 +413,6 @@ func TestRelayPaymentGovEpochToSaveIncrease(t *testing.T) { for ti, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Create relay request that was done in the test's epoch+block. Change session ID each iteration to avoid double spending error (provider asks reward for the same transaction twice) relayRequest := &pairingtypes.RelayRequest{ Provider: ts.providers[0].address.String(), @@ -452,12 +439,10 @@ func TestRelayPaymentGovEpochToSaveIncrease(t *testing.T) { payAndVerifyBalance(t, ts, relayPaymentMessage, tt.valid, ts.clients[0].address, ts.providers[0].address) }) } - } // Test that if the StakeToMaxCU.MaxCU param decreases make sure the client can send queries according to the original StakeToMaxCUList in the current epoch (This parameter is fixated) func TestRelayPaymentGovStakeToMaxCUListMaxCUDecrease(t *testing.T) { - // setup testnet with mock spec, stake a client and a provider ts := setupForPaymentTest(t) @@ -548,12 +533,10 @@ func TestRelayPaymentGovStakeToMaxCUListMaxCUDecrease(t *testing.T) { payAndVerifyBalance(t, ts, relayPaymentMessage, tt.valid, ts.clients[0].address, ts.providers[0].address) }) } - } // Test that if the StakeToMaxCU.StakeThreshold param increases make sure the client can send queries according to the original StakeToMaxCUList in the current epoch (This parameter is fixated) func TestRelayPaymentGovStakeToMaxCUListStakeThresholdIncrease(t *testing.T) { - // setup testnet with mock spec, stake a client and a provider ts := setupForPaymentTest(t) @@ -644,7 +627,6 @@ func TestRelayPaymentGovStakeToMaxCUListStakeThresholdIncrease(t *testing.T) { payAndVerifyBalance(t, ts, relayPaymentMessage, tt.valid, ts.clients[0].address, ts.providers[0].address) }) } - } func TestRelayPaymentGovEpochBlocksMultipleChanges(t *testing.T) { @@ -699,7 +681,6 @@ func TestRelayPaymentGovEpochBlocksMultipleChanges(t *testing.T) { for ti, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // change the EpochBlocks parameter according to the epoch test values epochBlocksNew := uint64(epochTests[ti].epochBlocksNewValues) err = testkeeper.SimulateParamChange(sdk.UnwrapSDKContext(ts.ctx), ts.keepers.ParamsKeeper, epochstoragetypes.ModuleName, string(epochstoragetypes.KeyEpochBlocks), "\""+strconv.FormatUint(epochBlocksNew, 10)+"\"") @@ -741,11 +722,9 @@ func TestRelayPaymentGovEpochBlocksMultipleChanges(t *testing.T) { payAndVerifyBalance(t, ts, relayPaymentMessage, tt.valid, ts.clients[0].address, ts.providers[0].address) }) } - } func TestRelayPaymentGovStakeToMaxCUListStakeThresholdMultipleChanges(t *testing.T) { - // setup testnet with mock spec, stake a client and a provider ts := setupForPaymentTest(t) @@ -827,7 +806,6 @@ func TestRelayPaymentGovStakeToMaxCUListStakeThresholdMultipleChanges(t *testing // this test checks what happens if a single provider stake, get payment, and then unstake and gets its money. func TestStakePaymentUnstake(t *testing.T) { - // setup testnet with mock spec, stake a client and a provider ts := setupForPaymentTest(t) @@ -888,7 +866,6 @@ func TestStakePaymentUnstake(t *testing.T) { // TODO: Currently the test passes since second call to verifyRelayPaymentObjects is called with true (see TODO comment right next to it). It should be false. After bug CNS-83 is fixed, change this test // Test that the payment object is deleted in the end of the memory and can't be used to double spend all while making gov changes func TestRelayPaymentMemoryTransferAfterEpochChangeWithGovParamChange(t *testing.T) { - tests := []struct { name string // Test name decreaseEpochBlocks bool // flag to indicate if EpochBlocks is decreased or not @@ -975,7 +952,6 @@ func TestRelayPaymentMemoryTransferAfterEpochChangeWithGovParamChange(t *testing // Helper function to verify the relay payment objects that are saved on-chain after getting payment from a relay request func verifyRelayPaymentObjects(t *testing.T, ts *testStruct, relayRequest *pairingtypes.RelayRequest, objectExists bool) { - // Get EpochPayment struct from current epoch and perform basic verifications epochPayments, found, epochPaymentKey := ts.keepers.Pairing.GetEpochPaymentsFromBlock(sdk.UnwrapSDKContext(ts.ctx), uint64(relayRequest.GetBlockHeight())) if objectExists { diff --git a/x/pairing/keeper/msg_server_relay_payment_test.go b/x/pairing/keeper/msg_server_relay_payment_test.go index cf769dc9a1..e18a85c192 100644 --- a/x/pairing/keeper/msg_server_relay_payment_test.go +++ b/x/pairing/keeper/msg_server_relay_payment_test.go @@ -87,7 +87,6 @@ func (ts *testStruct) getProvider(addr string) *account { // Test that a provider payment is valid if he asked it within the chain's memory, and check the relay payment object (RPO) func TestRelayPaymentMemoryTransferAfterEpochChange(t *testing.T) { - // setup testnet with mock spec, a staked client and a staked provider ts := setupForPaymentTest(t) @@ -122,7 +121,6 @@ func TestRelayPaymentMemoryTransferAfterEpochChange(t *testing.T) { for _, tt := range tests { sessionCounter += 1 t.Run(tt.name, func(t *testing.T) { - // Advance epochs according to the epochsToAdvance if tt.epochsToAdvance != 0 { for i := 0; i < int(tt.epochsToAdvance); i++ { @@ -164,10 +162,8 @@ func TestRelayPaymentMemoryTransferAfterEpochChange(t *testing.T) { // Check the RPO exists (shouldn't exist after epochsToSave+1 passes) verifyRelayPaymentObjects(t, ts, relayRequest, tt.valid) - }) } - } func setupForPaymentTest(t *testing.T) *testStruct { @@ -189,7 +185,6 @@ func setupForPaymentTest(t *testing.T) *testStruct { } func TestRelayPaymentBlockHeight(t *testing.T) { - tests := []struct { name string blockTime int64 @@ -202,8 +197,7 @@ func TestRelayPaymentBlockHeight(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - - ts := setupForPaymentTest(t) //reset the keepers state before each state + ts := setupForPaymentTest(t) // reset the keepers state before each state ts.spec = common.CreateMockSpec() ts.keepers.Spec.SetSpec(sdk.UnwrapSDKContext(ts.ctx), ts.spec) err := ts.addClient(1) @@ -255,7 +249,6 @@ func TestRelayPaymentBlockHeight(t *testing.T) { } else { require.NotNil(t, err) } - }) } } @@ -325,155 +318,6 @@ func setupClientsAndProvidersForUnresponsiveness(t *testing.T, amountOfClients i return ts } -func TestRelayPaymentUnstakingProviderForUnresponsiveness(t *testing.T) { - testClientAmount := 4 - testProviderAmount := 2 - ts := setupClientsAndProvidersForUnresponsiveness(t, testClientAmount, testProviderAmount) - - for i := 0; i < 2; i++ { // move to epoch 3 so we can check enough epochs in the past - ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) - } - staked_amount, _, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) - balanceProvideratBeforeStake := staked_amount.Stake.Amount.Int64() + ts.keepers.BankKeeper.GetBalance(sdk.UnwrapSDKContext(ts.ctx), ts.providers[1].address, epochstoragetypes.TokenDenom).Amount.Int64() - - unresponsiveProvidersData, err := json.Marshal([]string{ts.providers[1].address.String()}) - require.Nil(t, err) - var Relays []*types.RelayRequest - for clientIndex := 0; clientIndex < testClientAmount; clientIndex++ { // testing testClientAmount of complaints - relayRequest := &types.RelayRequest{ - Provider: ts.providers[0].address.String(), - ApiUrl: "", - Data: []byte(ts.spec.Apis[0].Name), - SessionId: uint64(1), - ChainID: ts.spec.Name, - CuSum: ts.spec.Apis[0].ComputeUnits * 10, - BlockHeight: sdk.UnwrapSDKContext(ts.ctx).BlockHeight(), - RelayNum: 0, - RequestBlock: -1, - DataReliability: nil, - UnresponsiveProviders: unresponsiveProvidersData, // create the complaint - } - - sig, err := sigs.SignRelay(ts.clients[clientIndex].secretKey, *relayRequest) - relayRequest.Sig = sig - require.Nil(t, err) - Relays = append(Relays, relayRequest) - } - _, err = ts.servers.PairingServer.RelayPayment(ts.ctx, &types.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: Relays}) - require.Nil(t, err) - // testing that the provider was unstaked. and checking his balance after many epochs - _, unStakeStoragefound, _ := ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[1].address) - require.True(t, unStakeStoragefound) - _, stakeStorageFound, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) - require.False(t, stakeStorageFound) - - OriginalBlockHeight := uint64(sdk.UnwrapSDKContext(ts.ctx).BlockHeight()) - blocksToSave, err := ts.keepers.Epochstorage.BlocksToSave(sdk.UnwrapSDKContext(ts.ctx), OriginalBlockHeight) - require.Nil(t, err) - for { // move to epoch 13 so we can check balance at the end - ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) - blockHeight := uint64(sdk.UnwrapSDKContext(ts.ctx).BlockHeight()) - if blockHeight > blocksToSave+OriginalBlockHeight { - break - } - } - // validate that the provider is no longer unstaked. and stake was returned. - _, unStakeStoragefound, _ = ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[1].address) - require.False(t, unStakeStoragefound) - // also that the provider wasnt returned to stake pool - _, stakeStorageFound, _ = ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) - require.False(t, stakeStorageFound) - - balanceProviderAfterUnstakeMoneyReturned := ts.keepers.BankKeeper.GetBalance(sdk.UnwrapSDKContext(ts.ctx), ts.providers[1].address, epochstoragetypes.TokenDenom).Amount.Int64() - require.Equal(t, balanceProvideratBeforeStake, balanceProviderAfterUnstakeMoneyReturned) -} - -func TestRelayPaymentUnstakingProviderForUnresponsivenessContinueComplainingAfterUnstake(t *testing.T) { - testClientAmount := 4 - testProviderAmount := 2 - ts := setupClientsAndProvidersForUnresponsiveness(t, testClientAmount, testProviderAmount) - for i := 0; i < 2; i++ { // move to epoch 3 so we can check enough epochs in the past - ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) - } - - unresponsiveProvidersData, err := json.Marshal([]string{ts.providers[1].address.String()}) - require.Nil(t, err) - var Relays []*types.RelayRequest - for clientIndex := 0; clientIndex < testClientAmount; clientIndex++ { // testing testClientAmount of complaints - - relayRequest := &types.RelayRequest{ - Provider: ts.providers[0].address.String(), - ApiUrl: "", - Data: []byte(ts.spec.Apis[0].Name), - SessionId: uint64(1), - ChainID: ts.spec.Name, - CuSum: ts.spec.Apis[0].ComputeUnits * 10, - BlockHeight: sdk.UnwrapSDKContext(ts.ctx).BlockHeight(), - RelayNum: 0, - RequestBlock: -1, - DataReliability: nil, - UnresponsiveProviders: unresponsiveProvidersData, // create the complaint - } - - sig, err := sigs.SignRelay(ts.clients[clientIndex].secretKey, *relayRequest) - relayRequest.Sig = sig - require.Nil(t, err) - Relays = append(Relays, relayRequest) - } - _, err = ts.servers.PairingServer.RelayPayment(ts.ctx, &types.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: Relays}) - require.Nil(t, err) - // testing that the provider wasnt unstaked. - _, unStakeStoragefound, _ := ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[1].address) - require.True(t, unStakeStoragefound) - _, stakeStorageFound, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) - require.False(t, stakeStorageFound) - - // continue reporting provider after unstake - for i := 0; i < 2; i++ { // move to epoch 5 - ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) - } - - var RelaysAfter []*types.RelayRequest - for clientIndex := 0; clientIndex < testClientAmount; clientIndex++ { // testing testClientAmount of complaints - - relayRequest := &types.RelayRequest{ - Provider: ts.providers[0].address.String(), - ApiUrl: "", - Data: []byte(ts.spec.Apis[0].Name), - SessionId: uint64(2), - ChainID: ts.spec.Name, - CuSum: ts.spec.Apis[0].ComputeUnits * 10, - BlockHeight: sdk.UnwrapSDKContext(ts.ctx).BlockHeight(), - RelayNum: 0, - RequestBlock: -1, - DataReliability: nil, - UnresponsiveProviders: unresponsiveProvidersData, // create the complaint - } - sig, err := sigs.SignRelay(ts.clients[clientIndex].secretKey, *relayRequest) - relayRequest.Sig = sig - require.Nil(t, err) - RelaysAfter = append(RelaysAfter, relayRequest) - } - _, err = ts.servers.PairingServer.RelayPayment(ts.ctx, &types.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: RelaysAfter}) - require.Nil(t, err) - - _, stakeStorageFound, _ = ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) - require.False(t, stakeStorageFound) - _, unStakeStoragefound, _ = ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[1].address) - require.True(t, unStakeStoragefound) - - // validating number of appearances for unstaked provider in unstake storage (if more than once found, throw an error) - storage, foundStorage := ts.keepers.Epochstorage.GetStakeStorageUnstake(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey) - require.True(t, foundStorage) - var numberOfAppearances int - for _, stored := range storage.StakeEntries { - if stored.Address == ts.providers[1].address.String() { - numberOfAppearances += 1 - } - } - require.Equal(t, numberOfAppearances, 1) -} - // only one epoch is not enough for the unstaking to happen need atleast two epochs in the past func TestRelayPaymentNotUnstakingProviderForUnresponsivenessIfNoEpochInformation(t *testing.T) { testClientAmount := 4 @@ -683,7 +527,6 @@ func TestRelayPaymentDoubleSpending(t *testing.T) { burn := ts.keepers.Pairing.BurnCoinsPerCU(sdk.UnwrapSDKContext(ts.ctx)).MulInt64(int64(cuSum)) newStakeClient, _, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ClientKey, ts.spec.Index, ts.clients[0].address) require.Equal(t, stakeClient.Stake.Amount.Int64()-burn.TruncateInt64(), newStakeClient.Stake.Amount.Int64()) - } func TestRelayPaymentDataModification(t *testing.T) { @@ -727,7 +570,6 @@ func TestRelayPaymentDataModification(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - relayRequest.Provider = tt.provider relayRequest.CuSum = tt.cu relayRequest.SessionId = uint64(tt.id) @@ -786,13 +628,12 @@ func TestRelayPaymentDelayedDoubleSpending(t *testing.T) { }{ {"Epoch", 1}, {"Memory-Epoch", epochToSave - 1}, - {"Memory", 1}, //epochToSave - {"Memory+Epoch", 1}, //epochToSave + 1 + {"Memory", 1}, // epochToSave + {"Memory+Epoch", 1}, // epochToSave + 1 } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - for i := 0; i < int(tt.advance); i++ { ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) } @@ -803,7 +644,6 @@ func TestRelayPaymentDelayedDoubleSpending(t *testing.T) { _, err = ts.servers.PairingServer.RelayPayment(ts.ctx, &types.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: Relays}) require.NotNil(t, err) - }) } } @@ -834,10 +674,10 @@ func TestRelayPaymentOldEpochs(t *testing.T) { epoch int64 valid bool }{ - {"Epoch", 1, 1, true}, //current -1*epoch - {"Memory-Epoch", 2, int64(epochsToSave - 1), true}, //current -epoch to save + 1 - {"Memory", 3, int64(epochsToSave), true}, //current - epochToSave - {"Memory+Epoch", 4, int64(epochsToSave + 1), false}, //current - epochToSave - 1 + {"Epoch", 1, 1, true}, // current -1*epoch + {"Memory-Epoch", 2, int64(epochsToSave - 1), true}, // current -epoch to save + 1 + {"Memory", 3, int64(epochsToSave), true}, // current - epochToSave + {"Memory+Epoch", 4, int64(epochsToSave + 1), false}, // current - epochToSave - 1 } for _, tt := range tests { @@ -880,7 +720,6 @@ func TestRelayPaymentOldEpochs(t *testing.T) { } else { require.NotNil(t, err) } - }) } } @@ -961,7 +800,6 @@ func TestRelayPaymentQoS(t *testing.T) { } else { require.NotNil(t, err) } - }) } } @@ -995,7 +833,7 @@ func TestRelayPaymentDataReliability(t *testing.T) { params := ts.keepers.Pairing.GetParams(sdk.UnwrapSDKContext(ts.ctx)) params.ServicersToPairCount = 100 ts.keepers.Pairing.SetParams(sdk.UnwrapSDKContext(ts.ctx), params) - ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) //we need that in order for the param set to take effect + ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) // we need that in order for the param set to take effect err := ts.addClient(1) require.Nil(t, err) err = ts.addProvider(100) @@ -1139,7 +977,7 @@ func TestRelayPaymentDataReliabilityWrongProvider(t *testing.T) { params := ts.keepers.Pairing.GetParams(sdk.UnwrapSDKContext(ts.ctx)) params.ServicersToPairCount = 100 ts.keepers.Pairing.SetParams(sdk.UnwrapSDKContext(ts.ctx), params) - ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) //we need that in order for the param set to take effect + ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) // we need that in order for the param set to take effect err := ts.addClient(1) require.Nil(t, err) err = ts.addProvider(100) @@ -1257,7 +1095,7 @@ func TestRelayPaymentDataReliabilityBelowReliabilityThreshold(t *testing.T) { params := ts.keepers.Pairing.GetParams(sdk.UnwrapSDKContext(ts.ctx)) params.ServicersToPairCount = 5 ts.keepers.Pairing.SetParams(sdk.UnwrapSDKContext(ts.ctx), params) - ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) //we need that in order for the param set to take effect + ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) // we need that in order for the param set to take effect err := ts.addClient(1) require.Nil(t, err) err = ts.addProvider(5) @@ -1348,7 +1186,7 @@ func TestRelayPaymentDataReliabilityDifferentClientSign(t *testing.T) { params := ts.keepers.Pairing.GetParams(sdk.UnwrapSDKContext(ts.ctx)) params.ServicersToPairCount = 100 ts.keepers.Pairing.SetParams(sdk.UnwrapSDKContext(ts.ctx), params) - ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) //we need that in order for the param set to take effect + ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) // we need that in order for the param set to take effect err := ts.addClient(2) require.Nil(t, err) err = ts.addProvider(100) @@ -1446,7 +1284,7 @@ func TestRelayPaymentDataReliabilityDoubleSpendDifferentEpoch(t *testing.T) { params := ts.keepers.Pairing.GetParams(sdk.UnwrapSDKContext(ts.ctx)) params.ServicersToPairCount = 100 ts.keepers.Pairing.SetParams(sdk.UnwrapSDKContext(ts.ctx), params) - ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) //we need that in order for the param set to take effect + ts.keepers.Epochstorage.PushFixatedParams(sdk.UnwrapSDKContext(ts.ctx), 0, 0) // we need that in order for the param set to take effect err := ts.addClient(1) require.Nil(t, err) err = ts.addProvider(100) @@ -1550,7 +1388,6 @@ func TestRelayPaymentDataReliabilityDoubleSpendDifferentEpoch(t *testing.T) { // Helper function to perform payment and verify the balances (if valid, provider's balance should increase and consumer should decrease) func payAndVerifyBalance(t *testing.T, ts *testStruct, relayPaymentMessage types.MsgRelayPayment, valid bool, clientAddress sdk.AccAddress, providerAddress sdk.AccAddress) { - // Get provider's and consumer's before payment balance := ts.keepers.BankKeeper.GetBalance(sdk.UnwrapSDKContext(ts.ctx), providerAddress, epochstoragetypes.TokenDenom).Amount.Int64() stakeClient, _, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ClientKey, ts.spec.Index, clientAddress) @@ -1558,6 +1395,7 @@ func payAndVerifyBalance(t *testing.T, ts *testStruct, relayPaymentMessage types // perform payment _, err := ts.servers.PairingServer.RelayPayment(ts.ctx, &relayPaymentMessage) if valid { + require.Nil(t, err) // payment is valid, provider's balance should increase mint := ts.keepers.Pairing.MintCoinsPerCU(sdk.UnwrapSDKContext(ts.ctx)) want := mint.MulInt64(int64(relayPaymentMessage.GetRelays()[0].CuSum)) // The compensation for a single query @@ -1576,8 +1414,7 @@ func payAndVerifyBalance(t *testing.T, ts *testStruct, relayPaymentMessage types } func TestEpochPaymentDeletion(t *testing.T) { - - ts := setupForPaymentTest(t) //reset the keepers state before each state + ts := setupForPaymentTest(t) // reset the keepers state before each state ts.spec = common.CreateMockSpec() ts.keepers.Spec.SetSpec(sdk.UnwrapSDKContext(ts.ctx), ts.spec) err := ts.addClient(1) @@ -1636,5 +1473,4 @@ func TestEpochPaymentDeletion(t *testing.T) { ans, err := ts.keepers.Pairing.EpochPaymentsAll(ts.ctx, &types.QueryAllEpochPaymentsRequest{}) require.Nil(t, err) require.Equal(t, 0, len(ans.EpochPayments)) - } diff --git a/x/pairing/keeper/msg_server_stake_client_test.go b/x/pairing/keeper/msg_server_stake_client_test.go index 4b7d37d853..b69285bc66 100644 --- a/x/pairing/keeper/msg_server_stake_client_test.go +++ b/x/pairing/keeper/msg_server_stake_client_test.go @@ -16,7 +16,7 @@ import ( func TestNewStakeClient(t *testing.T) { servers, keepers, ctx := testkeeper.InitAllKeepers(t) - //init keepers state + // init keepers state _, clientAddr := sigs.GenerateFloatingKey() var amount int64 = 1000 keepers.BankKeeper.SetBalance(sdk.UnwrapSDKContext(ctx), clientAddr, sdk.NewCoins(sdk.NewCoin(epochstoragetypes.TokenDenom, sdk.NewInt(amount)))) @@ -39,7 +39,6 @@ func TestNewStakeClient(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, err := servers.PairingServer.StakeClient(ctx, &types.MsgStakeClient{Creator: clientAddr.String(), ChainID: spec.Name, Amount: tt.stake, Geolocation: 1, Vrfpk: vrfPk.String()}) ctx = testkeeper.AdvanceEpoch(ctx, keepers) @@ -60,7 +59,7 @@ func TestNewStakeClient(t *testing.T) { func TestAddStakeClient(t *testing.T) { servers, keepers, ctx := testkeeper.InitAllKeepers(t) - //init keepers state + // init keepers state _, clientAddr := sigs.GenerateFloatingKey() var amount int64 = 1000 keepers.BankKeeper.SetBalance(sdk.UnwrapSDKContext(ctx), clientAddr, sdk.NewCoins(sdk.NewCoin(epochstoragetypes.TokenDenom, sdk.NewInt(amount)))) @@ -103,13 +102,12 @@ func TestAddStakeClient(t *testing.T) { } }) } - } func TestStakeClientPairingimmediately(t *testing.T) { servers, keepers, ctx := testkeeper.InitAllKeepers(t) - //init keepers state + // init keepers state var balance int64 = 10000 consumer := common.CreateNewAccount(ctx, *keepers, balance) provider1 := common.CreateNewAccount(ctx, *keepers, balance) @@ -128,7 +126,7 @@ func TestStakeClientPairingimmediately(t *testing.T) { ctx = testkeeper.AdvanceBlock(ctx, keepers) - //check pairing in the same epoch + // check pairing in the same epoch clientStakeEntry, err := keepers.Pairing.VerifyPairingData(sdk.UnwrapSDKContext(ctx), spec.Index, consumer.Addr, uint64(sdk.UnwrapSDKContext(ctx).BlockHeight())) require.Nil(t, err) require.Equal(t, clientStakeEntry.Stake.Amount, sdk.NewInt(stake)) @@ -136,17 +134,16 @@ func TestStakeClientPairingimmediately(t *testing.T) { _, err = keepers.Pairing.GetPairingForClient(sdk.UnwrapSDKContext(ctx), spec.Index, consumer.Addr) require.Nil(t, err) - //try to change stake + // try to change stake common.StakeAccount(t, ctx, *keepers, *servers, consumer, spec, 2*stake, false) clientStakeEntry, err = keepers.Pairing.VerifyPairingData(sdk.UnwrapSDKContext(ctx), spec.Index, consumer.Addr, uint64(sdk.UnwrapSDKContext(ctx).BlockHeight())) require.Nil(t, err) require.Equal(t, clientStakeEntry.Stake.Amount, sdk.NewInt(stake)) - //new stake takes effect + // new stake takes effect ctx = testkeeper.AdvanceEpoch(ctx, keepers) clientStakeEntry, err = keepers.Pairing.VerifyPairingData(sdk.UnwrapSDKContext(ctx), spec.Index, consumer.Addr, uint64(sdk.UnwrapSDKContext(ctx).BlockHeight())) require.Nil(t, err) require.Equal(t, clientStakeEntry.Stake.Amount, sdk.NewInt(2*stake)) - } diff --git a/x/pairing/keeper/msg_server_stake_provider_test.go b/x/pairing/keeper/msg_server_stake_provider_test.go index c2161b9ea4..f10d139f8d 100644 --- a/x/pairing/keeper/msg_server_stake_provider_test.go +++ b/x/pairing/keeper/msg_server_stake_provider_test.go @@ -39,7 +39,6 @@ func TestStakeProviderWithMoniker(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Advance epoch ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) @@ -66,10 +65,8 @@ func TestStakeProviderWithMoniker(t *testing.T) { } else { require.NotEqual(t, tt.moniker, stakeEntry.Moniker) } - }) } - } func TestModifyStakeProviderWithMoniker(t *testing.T) { @@ -107,7 +104,7 @@ func TestModifyStakeProviderWithMoniker(t *testing.T) { require.True(t, foundProvider) require.Equal(t, moniker, stakeEntry.Moniker) - //modify moniker + // modify moniker moniker = "anotherExampleMoniker" _, err = ts.servers.PairingServer.StakeProvider(ts.ctx, &types.MsgStakeProvider{Creator: address.String(), ChainID: ts.spec.Name, Amount: sdk.NewCoin(epochstoragetypes.TokenDenom, sdk.NewInt(stake)), Geolocation: 1, Endpoints: endpoints, Moniker: moniker}) require.Nil(t, err) diff --git a/x/pairing/keeper/msg_server_stake_unstake_gov_test.go b/x/pairing/keeper/msg_server_stake_unstake_gov_test.go index 292189bffb..31643cb302 100644 --- a/x/pairing/keeper/msg_server_stake_unstake_gov_test.go +++ b/x/pairing/keeper/msg_server_stake_unstake_gov_test.go @@ -14,7 +14,6 @@ import ( // Test that if the EpochBlocks param decreases make sure the provider/client is staked only after the original EpochBlocks value (EpochBlocks = number of blocks in an epoch. This parameter is fixated) func TestStakeGovEpochBlocksDecrease(t *testing.T) { - // Create teststruct ts ts := &testStruct{ providers: make([]*account, 0), @@ -84,7 +83,6 @@ func TestStakeGovEpochBlocksDecrease(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // check if the provider/client are staked _, foundProvider, _ := ts.keepers.Epochstorage.GetEpochStakeEntries(sdk.UnwrapSDKContext(ts.ctx), tt.epoch, epochstoragetypes.ProviderKey, ts.spec.GetIndex()) require.Equal(t, tt.shouldBeStaked, foundProvider) @@ -92,12 +90,10 @@ func TestStakeGovEpochBlocksDecrease(t *testing.T) { require.Equal(t, tt.shouldBeStaked, foundClient) }) } - } // Test that if the EpochBlocks param increases make sure the provider/client is staked after the original EpochBlocks value, and not the new enlarged one (EpochBlocks = number of blocks in an epoch. This parameter is fixated) func TestStakeGovEpochBlocksIncrease(t *testing.T) { - // Create teststruct ts ts := &testStruct{ providers: make([]*account, 0), @@ -171,7 +167,6 @@ func TestStakeGovEpochBlocksIncrease(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // check if the provider/client are staked _, found, _ := ts.keepers.Epochstorage.GetEpochStakeEntries(sdk.UnwrapSDKContext(ts.ctx), tt.epoch, epochstoragetypes.ProviderKey, ts.spec.GetIndex()) require.Equal(t, tt.shouldBeStaked, found) @@ -179,12 +174,10 @@ func TestStakeGovEpochBlocksIncrease(t *testing.T) { require.Equal(t, tt.shouldBeStaked, found) }) } - } // Test that if the UnstakeHoldBlocks param decreases make sure the provider/client is getting their funds back only by the original UnstakeHoldBlocks value (return_funds_block = next_epoch(current_block + max(UnstakeHoldBlocks, BlocksToSave))) func TestUnstakeGovUnstakeHoldBlocksDecrease(t *testing.T) { - // Create teststruct ts ts := &testStruct{ providers: make([]*account, 0), @@ -263,12 +256,10 @@ func TestUnstakeGovUnstakeHoldBlocksDecrease(t *testing.T) { require.Equal(t, balance, clientCurrentFunds.Amount.Int64()) providerCurrentFunds = ts.keepers.BankKeeper.GetBalance(sdk.UnwrapSDKContext(ts.ctx), providerAddress, epochstoragetypes.TokenDenom) require.Equal(t, balance, providerCurrentFunds.Amount.Int64()) - } // Test that if the UnstakeHoldBlocks param increases make sure the provider/client is getting their funds back only by the original UnstakeHoldBlocks value (return_funds_block = next_epoch(current_block + max(UnstakeHoldBlocks, BlocksToSave))) func TestUnstakeGovUnstakeHoldBlocksIncrease(t *testing.T) { - // Create teststruct ts ts := &testStruct{ providers: make([]*account, 0), @@ -349,5 +340,4 @@ func TestUnstakeGovUnstakeHoldBlocksIncrease(t *testing.T) { require.Equal(t, balance, clientCurrentFunds.Amount.Int64()) providerCurrentFunds = ts.keepers.BankKeeper.GetBalance(sdk.UnwrapSDKContext(ts.ctx), providerAddress, epochstoragetypes.TokenDenom) require.Equal(t, balance, providerCurrentFunds.Amount.Int64()) - } diff --git a/x/pairing/keeper/msg_server_test.go b/x/pairing/keeper/msg_server_test.go index ef473f2be9..29a517d670 100644 --- a/x/pairing/keeper/msg_server_test.go +++ b/x/pairing/keeper/msg_server_test.go @@ -10,7 +10,7 @@ import ( "github.com/lavanet/lava/x/pairing/types" ) -//TODO: use or delete this function +// TODO: use or delete this function func setupMsgServer(t testing.TB) (types.MsgServer, context.Context) { k, ctx := keepertest.PairingKeeper(t) return keeper.NewMsgServerImpl(*k), sdk.WrapSDKContext(ctx) diff --git a/x/pairing/keeper/msg_server_unstake_client_test.go b/x/pairing/keeper/msg_server_unstake_client_test.go index 3237d728b0..ff5542eb19 100644 --- a/x/pairing/keeper/msg_server_unstake_client_test.go +++ b/x/pairing/keeper/msg_server_unstake_client_test.go @@ -16,7 +16,7 @@ import ( func TestUnstakeClient(t *testing.T) { servers, keepers, ctx := testkeeper.InitAllKeepers(t) - //init keepers state + // init keepers state _, clientAddr := sigs.GenerateFloatingKey() var amount int64 = 1000 keepers.BankKeeper.SetBalance(sdk.UnwrapSDKContext(ctx), clientAddr, sdk.NewCoins(sdk.NewCoin(epochstoragetypes.TokenDenom, sdk.NewInt(amount)))) @@ -67,7 +67,7 @@ func TestUnstakeClient(t *testing.T) { func TestUnstakeNotStakedClient(t *testing.T) { servers, keepers, ctx := testkeeper.InitAllKeepers(t) - //init keepers state + // init keepers state _, clientAddr := sigs.GenerateFloatingKey() var amount int64 = 1000 keepers.BankKeeper.SetBalance(sdk.UnwrapSDKContext(ctx), clientAddr, sdk.NewCoins(sdk.NewCoin(epochstoragetypes.TokenDenom, sdk.NewInt(amount)))) @@ -96,7 +96,6 @@ func TestUnstakeNotStakedClient(t *testing.T) { balance := keepers.BankKeeper.GetBalance(sdk.UnwrapSDKContext(ctx), clientAddr, epochstoragetypes.TokenDenom).Amount.Int64() require.Equal(t, amount, balance) - }) } } @@ -104,7 +103,7 @@ func TestUnstakeNotStakedClient(t *testing.T) { func TestDoubleUnstakeClient(t *testing.T) { servers, keepers, ctx := testkeeper.InitAllKeepers(t) - //init keepers state + // init keepers state _, clientAddr := sigs.GenerateFloatingKey() var amount int64 = 1000 keepers.BankKeeper.SetBalance(sdk.UnwrapSDKContext(ctx), clientAddr, sdk.NewCoins(sdk.NewCoin(epochstoragetypes.TokenDenom, sdk.NewInt(amount)))) diff --git a/x/pairing/keeper/pairing_test.go b/x/pairing/keeper/pairing_test.go index b037c5d5a0..80089b3315 100644 --- a/x/pairing/keeper/pairing_test.go +++ b/x/pairing/keeper/pairing_test.go @@ -15,7 +15,7 @@ import ( func TestPairingUniqueness(t *testing.T) { servers, keepers, ctx := testkeeper.InitAllKeepers(t) - //init keepers state + // init keepers state spec := common.CreateMockSpec() keepers.Spec.SetSpec(sdk.UnwrapSDKContext(ctx), spec) @@ -79,7 +79,7 @@ func TestPairingUniqueness(t *testing.T) { } require.True(t, different) - //test that get pairing gives the same results for the whole epoch + // test that get pairing gives the same results for the whole epoch epochBlocks := keepers.Epochstorage.EpochBlocksRaw(sdk.UnwrapSDKContext(ctx)) foundIndexMap := map[string]int{} for i := uint64(0); i < epochBlocks-1; i++ { @@ -129,7 +129,6 @@ func TestGetPairing(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - // Advance an epoch according to the test switch tt.name { case "zeroEpoch": @@ -221,7 +220,6 @@ func TestGetPairing(t *testing.T) { // verify nextPairingBlock require.Equal(t, nextPairingBlock, pairing.BlockOfNextPairing) } - }) } } @@ -229,7 +227,7 @@ func TestGetPairing(t *testing.T) { func TestPairingStatic(t *testing.T) { servers, keepers, ctx := testkeeper.InitAllKeepers(t) - //init keepers state + // init keepers state spec := common.CreateMockSpec() spec.ProvidersTypes = spectypes.Spec_static keepers.Spec.SetSpec(sdk.UnwrapSDKContext(ctx), spec) @@ -246,7 +244,7 @@ func TestPairingStatic(t *testing.T) { common.StakeAccount(t, ctx, *keepers, *servers, provider, spec, stake+int64(i), true) } - //we expect to get all the providers in static spec + // we expect to get all the providers in static spec ctx = testkeeper.AdvanceEpoch(ctx, keepers) @@ -256,5 +254,4 @@ func TestPairingStatic(t *testing.T) { for i, provider := range providers { require.Equal(t, provider.Stake.Amount.Int64(), stake+int64(i)) } - } diff --git a/x/pairing/keeper/params.go b/x/pairing/keeper/params.go index 424d9e78a1..d6bb58364a 100644 --- a/x/pairing/keeper/params.go +++ b/x/pairing/keeper/params.go @@ -19,6 +19,7 @@ func (k Keeper) GetParams(ctx sdk.Context) types.Params { k.SlashLimit(ctx), k.DataReliabilityReward(ctx), k.QoSWeight(ctx), + k.RecommendedEpochNumToCollectPayment(ctx), ) } @@ -96,3 +97,13 @@ func (k Keeper) QoSWeight(ctx sdk.Context) (res sdk.Dec) { k.paramstore.Get(ctx, types.KeyQoSWeight, &res) return } + +// RecommendedEpochNumToCollectPayment returns the RecommendedEpochNumToCollectPayment param +func (k Keeper) RecommendedEpochNumToCollectPayment(ctx sdk.Context) (res uint64) { + k.paramstore.Get(ctx, types.KeyRecommendedEpochNumToCollectPayment, &res) + return +} + +func (k Keeper) SetRecommendedEpochNumToCollectPayment(ctx sdk.Context, val uint64) { + k.paramstore.Set(ctx, types.KeyRecommendedEpochNumToCollectPayment, val) +} diff --git a/x/pairing/keeper/params_test.go b/x/pairing/keeper/params_test.go index 686b3bcb6e..230d9367de 100644 --- a/x/pairing/keeper/params_test.go +++ b/x/pairing/keeper/params_test.go @@ -21,4 +21,5 @@ func TestGetParams(t *testing.T) { require.EqualValues(t, params.FraudSlashingAmount, k.FraudSlashingAmount(ctx)) require.EqualValues(t, params.ServicersToPairCount, k.ServicersToPairCountRaw(ctx)) require.EqualValues(t, params.EpochBlocksOverlap, k.EpochBlocksOverlap(ctx)) + require.EqualValues(t, params.RecommendedEpochNumToCollectPayment, k.RecommendedEpochNumToCollectPayment(ctx)) } diff --git a/x/pairing/keeper/provider_payment_storage_test.go b/x/pairing/keeper/provider_payment_storage_test.go index b3c903f864..d8bb531410 100644 --- a/x/pairing/keeper/provider_payment_storage_test.go +++ b/x/pairing/keeper/provider_payment_storage_test.go @@ -39,6 +39,7 @@ func TestProviderPaymentStorageGet(t *testing.T) { ) } } + func TestProviderPaymentStorageRemove(t *testing.T) { keeper, ctx := keepertest.PairingKeeper(t) items := createNProviderPaymentStorage(keeper, ctx, 10) diff --git a/x/pairing/keeper/unique_payment_storage_client_provider_test.go b/x/pairing/keeper/unique_payment_storage_client_provider_test.go index a990b7eb44..7f0edbe276 100644 --- a/x/pairing/keeper/unique_payment_storage_client_provider_test.go +++ b/x/pairing/keeper/unique_payment_storage_client_provider_test.go @@ -39,6 +39,7 @@ func TestUniquePaymentStorageClientProviderGet(t *testing.T) { ) } } + func TestUniquePaymentStorageClientProviderRemove(t *testing.T) { keeper, ctx := keepertest.PairingKeeper(t) items := createNUniquePaymentStorageClientProvider(keeper, ctx, 10) diff --git a/x/pairing/keeper/unresponsive_provider.go b/x/pairing/keeper/unresponsive_provider.go new file mode 100644 index 0000000000..ec1ab17bc4 --- /dev/null +++ b/x/pairing/keeper/unresponsive_provider.go @@ -0,0 +1,224 @@ +package keeper + +import ( + "fmt" + "strconv" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/utils" + epochstoragetypes "github.com/lavanet/lava/x/epochstorage/types" + "github.com/lavanet/lava/x/pairing/types" +) + +// Function that returns a map that links between a provider that should be punished and its providerCuCounterForUnreponsiveness +func (k Keeper) UnstakeUnresponsiveProviders(ctx sdk.Context, epochsNumToCheckCUForUnresponsiveProvider uint64, epochsNumToCheckCUForComplainers uint64) error { + // check the epochsNum consts + if epochsNumToCheckCUForComplainers <= 0 || epochsNumToCheckCUForUnresponsiveProvider <= 0 { + return utils.LavaError(ctx, k.Logger(ctx), "get_unresponsive_providers_to_punish", nil, "epochsNumToCheckCUForUnresponsiveProvider or epochsNumToCheckCUForComplainers are smaller or equal than zero") + } + + // Get current epoch + currentEpoch := k.epochStorageKeeper.GetEpochStart(ctx) + + // Get recommendedEpochNumToCollectPayment + recommendedEpochNumToCollectPayment := k.RecommendedEpochNumToCollectPayment(ctx) + + // check which of the consts is larger + largerEpochsNumConst := epochsNumToCheckCUForComplainers + if epochsNumToCheckCUForUnresponsiveProvider > epochsNumToCheckCUForComplainers { + largerEpochsNumConst = epochsNumToCheckCUForUnresponsiveProvider + } + + // To check for punishment, we have to go back recommendedEpochNumToCollectPayment+max(epochsNumToCheckCUForComplainers,epochsNumToCheckCUForUnresponsiveProvider) epochs from the current epoch. If there isn't enough memory, do nothing + epochTemp := currentEpoch + for counter := uint64(0); counter < largerEpochsNumConst+recommendedEpochNumToCollectPayment; counter++ { + previousEpoch, err := k.epochStorageKeeper.GetPreviousEpochStartForBlock(ctx, epochTemp) + if err != nil { + utils.LavaFormatInfo("Epoch too early to punish unresponsive providers", &map[string]string{"epoch": fmt.Sprintf("%+v", currentEpoch)}) + return nil + } + epochTemp = previousEpoch + } + + // Get the current stake storages (from all chains). stake storages contain a list of stake entries. Each stake storage is for a different chain + providerStakeStorageList := k.getCurrentProviderStakeStorageList(ctx) + if len(providerStakeStorageList) == 0 { + // no provider is staked -> no one to punish + return nil + } + + // Go back recommendedEpochNumToCollectPayment + epochTemp = currentEpoch + for counter := uint64(0); counter < recommendedEpochNumToCollectPayment; counter++ { + previousEpoch, err := k.epochStorageKeeper.GetPreviousEpochStartForBlock(ctx, epochTemp) + if err != nil { + return utils.LavaError(ctx, k.Logger(ctx), "get_previous_epoch", map[string]string{"err": err.Error(), "epoch": fmt.Sprintf("%+v", currentEpoch)}, "couldn't get previous epoch") + } + epochTemp = previousEpoch + } + + // Go over the staked provider entries (on all chains) + for _, providerStakeStorage := range providerStakeStorageList { + for _, providerStakeEntry := range providerStakeStorage.GetStakeEntries() { + // update the CU count for this provider in providerCuCounterForUnreponsivenessMap + providerPaymentStorageKeyList, err := k.countCuForUnresponsiveness(ctx, epochTemp, epochsNumToCheckCUForUnresponsiveProvider, epochsNumToCheckCUForComplainers, providerStakeEntry) + if err != nil { + return utils.LavaError(ctx, k.Logger(ctx), "count_cu_for_unresponsiveness", map[string]string{"err": err.Error()}, "couldn't count CU for unreponsiveness") + } + + // providerPaymentStorageKeyList is not empty -> provider should be punished + if len(providerPaymentStorageKeyList) != 0 { + err = k.punishUnresponsiveProvider(ctx, epochTemp, providerPaymentStorageKeyList, providerStakeEntry.GetAddress(), providerStakeEntry.GetChain()) + if err != nil { + return utils.LavaError(ctx, k.Logger(ctx), "punish_unresponsive_provider", map[string]string{"err": err.Error()}, "couldn't punish unresponsive provider") + } + } + } + } + + return nil +} + +// Function to count the CU serviced by the unresponsive provider and the CU of the complainers. The function returns a list of the found providerPaymentStorageKey +func (k Keeper) countCuForUnresponsiveness(ctx sdk.Context, epoch uint64, epochsNumToCheckCUForUnresponsiveProvider uint64, epochsNumToCheckCUForComplainers uint64, providerStakeEntry epochstoragetypes.StakeEntry) ([]string, error) { + epochTemp := epoch + providerServicedCu := uint64(0) + complainersCu := uint64(0) + providerPaymentStorageKeyList := []string{} + + // get the provider's SDK account address + sdkStakeEntryProviderAddress, err := sdk.AccAddressFromBech32(providerStakeEntry.GetAddress()) + if err != nil { + return nil, utils.LavaFormatError("unable to sdk.AccAddressFromBech32(provider)", err, &map[string]string{"provider_address": providerStakeEntry.Address}) + } + + // check which of the consts is larger + largerEpochsNumConst := epochsNumToCheckCUForComplainers + if epochsNumToCheckCUForUnresponsiveProvider > epochsNumToCheckCUForComplainers { + largerEpochsNumConst = epochsNumToCheckCUForUnresponsiveProvider + } + + // count the CU serviced by the unersponsive provider and used CU of the complainers + for counter := uint64(0); counter < largerEpochsNumConst; counter++ { + // get providerPaymentStorageKey for epochTemp (other traits from the stake entry) + providerPaymentStorageKey := k.GetProviderPaymentStorageKey(ctx, providerStakeEntry.GetChain(), epochTemp, sdkStakeEntryProviderAddress) + + // try getting providerPaymentStorage using the providerPaymentStorageKey + providerPaymentStorage, found := k.GetProviderPaymentStorage(ctx, providerPaymentStorageKey) + if found { + // counter is smaller than epochsNumToCheckCUForUnresponsiveProvider -> count CU serviced by the provider in the epoch + if counter < epochsNumToCheckCUForUnresponsiveProvider { + // count the CU by iterating through the uniquePaymentStorageClientProvider objects + for _, uniquePaymentKey := range providerPaymentStorage.GetUniquePaymentStorageClientProviderKeys() { + uniquePayment, _ := k.GetUniquePaymentStorageClientProvider(ctx, uniquePaymentKey) + providerServicedCu += uniquePayment.GetUsedCU() + } + } + + // counter is smaller than epochsNumToCheckCUForComplainers -> count complainer CU + if counter < epochsNumToCheckCUForComplainers { + // update complainersCu + complainersCu += providerPaymentStorage.ComplainersTotalCu + } + + // save the providerPaymentStorageKey in the providerPaymentStorageKeyList + providerPaymentStorageKeyList = append(providerPaymentStorageKeyList, providerPaymentStorageKey) + } + + // Get previous epoch (from epochTemp) + previousEpoch, err := k.epochStorageKeeper.GetPreviousEpochStartForBlock(ctx, epochTemp) + if err != nil { + return nil, utils.LavaError(ctx, k.Logger(ctx), "get_previous_epoch", map[string]string{"err": err.Error(), "epoch": fmt.Sprintf("%+v", epochTemp)}, "couldn't get previous epoch") + } + // update epochTemp + epochTemp = previousEpoch + } + + // the complainers' CU is larger than the provider serviced CU -> should be punished (return providerPaymentStorageKeyList so the complainers' CU can be reset after the punishment) + if complainersCu > providerServicedCu { + return providerPaymentStorageKeyList, nil + } + + return nil, nil +} + +// Function that return the current stake storage for all chains +func (k Keeper) getCurrentProviderStakeStorageList(ctx sdk.Context) []epochstoragetypes.StakeStorage { + var stakeStorageList []epochstoragetypes.StakeStorage + + // get all chain IDs + chainIdList := k.specKeeper.GetAllChainIDs(ctx) + + // go over all chain IDs and keep their stake storage. If there is no stake storage for a specific chain, continue to the next one + for _, chainID := range chainIdList { + stakeStorage, found := k.epochStorageKeeper.GetStakeStorageCurrent(ctx, epochstoragetypes.ProviderKey, chainID) + if !found { + continue + } + stakeStorageList = append(stakeStorageList, stakeStorage) + } + + return stakeStorageList +} + +// Function that punishes providers. Current punishment is unstake +func (k Keeper) punishUnresponsiveProvider(ctx sdk.Context, epoch uint64, providerPaymentStorageKeyList []string, providerAddress string, chainID string) error { + // Get provider's sdk.Account address + sdkUnresponsiveProviderAddress, err := sdk.AccAddressFromBech32(providerAddress) + if err != nil { + // if bad data was given, we cant parse it so we ignore it and continue this protects from spamming wrong information. + return utils.LavaFormatError("unable to sdk.AccAddressFromBech32(unresponsive_provider)", err, &map[string]string{"unresponsive_provider_address": providerAddress}) + } + + // Get provider's stake entry + existingEntry, entryExists, indexInStakeStorage := k.epochStorageKeeper.GetStakeEntryByAddressCurrent(ctx, epochstoragetypes.ProviderKey, chainID, sdkUnresponsiveProviderAddress) + if !entryExists { + // if provider is not staked, nothing to do. + return nil + } + + // unstake the unresponsive provider + utils.LogLavaEvent(ctx, k.Logger(ctx), types.ProviderJailedEventName, map[string]string{"provider_address": providerAddress, "chain_id": chainID}, "Unresponsive provider was unstaked from the chain due to unresponsiveness") + err = k.unsafeUnstakeProviderEntry(ctx, epoch, epochstoragetypes.ProviderKey, chainID, indexInStakeStorage, existingEntry) + if err != nil { + utils.LavaFormatError("unable to unstake provider entry (unsafe method)", err, &map[string]string{"chainID": chainID, "indexInStakeStorage": strconv.FormatUint(indexInStakeStorage, 10), "existingEntry": existingEntry.GetStake().String()}) + } + + // reset the provider's complainer CU (so he won't get punished for the same complaints twice) + k.resetComplainersCU(ctx, providerPaymentStorageKeyList) + + return nil +} + +// Function that reset the complainer CU of providerPaymentStorage objects that can be accessed using providerPaymentStorageIndexList +func (k Keeper) resetComplainersCU(ctx sdk.Context, providerPaymentStorageIndexList []string) { + // go over the providerPaymentStorageIndexList + for _, providerPaymentStorageIndex := range providerPaymentStorageIndexList { + // get providerPaymentStorage using its index + providerPaymentStorage, found := k.GetProviderPaymentStorage(ctx, providerPaymentStorageIndex) + if !found { + continue + } + + // reset the complainer CU + providerPaymentStorage.ComplainersTotalCu = 0 + k.SetProviderPaymentStorage(ctx, providerPaymentStorage) + } +} + +// Function that unstakes a provider (considered unsafe because it doesn't check that the provider is staked. It's ok since we check the provider is staked before we call it) +func (k Keeper) unsafeUnstakeProviderEntry(ctx sdk.Context, epoch uint64, providerKey string, chainID string, indexInStakeStorage uint64, existingEntry epochstoragetypes.StakeEntry) error { + // Remove the provider's stake entry + err := k.epochStorageKeeper.RemoveStakeEntryCurrent(ctx, epochstoragetypes.ProviderKey, chainID, indexInStakeStorage) + if err != nil { + return utils.LavaError(ctx, k.Logger(ctx), "relay_payment_unstake", map[string]string{"existingEntry": fmt.Sprintf("%+v", existingEntry)}, "tried to unstake unsafe but didnt find entry") + } + + // get unstakeHoldBlocks + unstakeHoldBlocks := k.epochStorageKeeper.UnstakeHoldBlocks(ctx, epoch) + + // Appened the provider's stake entry to the unstake entry list + k.epochStorageKeeper.AppendUnstakeEntry(ctx, epochstoragetypes.ProviderKey, existingEntry, unstakeHoldBlocks) + + return nil +} diff --git a/x/pairing/keeper/unresponsive_provider_test.go b/x/pairing/keeper/unresponsive_provider_test.go new file mode 100644 index 0000000000..7db4dbeaac --- /dev/null +++ b/x/pairing/keeper/unresponsive_provider_test.go @@ -0,0 +1,341 @@ +package keeper_test + +import ( + "encoding/json" + "math/rand" + "testing" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/lavanet/lava/relayer/sigs" + testkeeper "github.com/lavanet/lava/testutil/keeper" + epochstoragetypes "github.com/lavanet/lava/x/epochstorage/types" + "github.com/lavanet/lava/x/pairing" + "github.com/lavanet/lava/x/pairing/types" + "github.com/stretchr/testify/require" +) + +func TestUnresponsivenessStressTest(t *testing.T) { + // setup test for unresponsiveness + testClientAmount := 50 + testProviderAmount := 5 + ts := setupClientsAndProvidersForUnresponsiveness(t, testClientAmount, testProviderAmount) + + // get recommendedEpochNumToCollectPayment + recommendedEpochNumToCollectPayment := ts.keepers.Pairing.RecommendedEpochNumToCollectPayment(sdk.UnwrapSDKContext(ts.ctx)) + + // check which const is larger + largerConst := pairing.EPOCHS_NUM_TO_CHECK_CU_FOR_UNRESPONSIVE_PROVIDER + if largerConst < pairing.EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS { + largerConst = pairing.EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS + } + + // advance enough epochs so we can check punishment due to unresponsiveness (if the epoch is too early, there's no punishment) + for i := uint64(0); i < uint64(largerConst)+recommendedEpochNumToCollectPayment; i++ { + ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) + } + + // create unresponsive data list of the first 100 providers being unresponsive + var unresponsiveDataList [][]byte + unresponsiveProviderAmount := 1 + for i := 0; i < unresponsiveProviderAmount; i++ { + unresponsiveData, err := json.Marshal([]string{ts.providers[i].address.String()}) + require.Nil(t, err) + unresponsiveDataList = append(unresponsiveDataList, unresponsiveData) + } + + // create relay requests for that contain complaints about providers with indices 0-100 + relayEpoch := sdk.UnwrapSDKContext(ts.ctx).BlockHeight() + for clientIndex := 0; clientIndex < testClientAmount; clientIndex++ { // testing testClientAmount of complaints + var Relays []*types.RelayRequest + + // Get pairing for the client to pick a valid provider + providersStakeEntries, err := ts.keepers.Pairing.GetPairingForClient(sdk.UnwrapSDKContext(ts.ctx), ts.spec.Name, ts.clients[clientIndex].address) + providerIndex := rand.Intn(len(providersStakeEntries)) + providerAddress := providersStakeEntries[providerIndex].Address + providerSdkAddress, err := sdk.AccAddressFromBech32(providerAddress) + require.Nil(t, err) + + // create relay request + relayRequest := &types.RelayRequest{ + Provider: providerAddress, + ApiUrl: "", + Data: []byte(ts.spec.Apis[0].Name), + SessionId: uint64(0), + ChainID: ts.spec.Name, + CuSum: ts.spec.Apis[0].ComputeUnits*10 + uint64(clientIndex), + BlockHeight: relayEpoch, + RelayNum: 0, + RequestBlock: -1, + DataReliability: nil, + UnresponsiveProviders: unresponsiveDataList[clientIndex%unresponsiveProviderAmount], // create the complaint + } + + sig, err := sigs.SignRelay(ts.clients[clientIndex].secretKey, *relayRequest) + relayRequest.Sig = sig + require.Nil(t, err) + Relays = append(Relays, relayRequest) + + // send relay payment and check the funds did transfer normally + payAndVerifyBalance(t, ts, types.MsgRelayPayment{Creator: providerAddress, Relays: Relays}, true, ts.clients[clientIndex].address, providerSdkAddress) + } + + // advance enough epochs so the unresponsive providers will be punished + if largerConst < recommendedEpochNumToCollectPayment { + largerConst = recommendedEpochNumToCollectPayment + } + for i := uint64(0); i < largerConst; i++ { + ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) + } + + // go over unresponsive providers + for i := 0; i < unresponsiveProviderAmount; i++ { + // test the providers has been unstaked + _, unstakeStoragefound, _ := ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[i].address) + require.True(t, unstakeStoragefound) + _, stakeStorageFound, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[i].address) + require.False(t, stakeStorageFound) + + // validate the complainers CU field in the unresponsive provider's providerPaymentStorage has been reset after being punished (note we use the epoch from the relay because that is when it got reported) + providerPaymentStorageKey := ts.keepers.Pairing.GetProviderPaymentStorageKey(sdk.UnwrapSDKContext(ts.ctx), ts.spec.Name, uint64(relayEpoch), ts.providers[i].address) + providerPaymentStorage, found := ts.keepers.Pairing.GetProviderPaymentStorage(sdk.UnwrapSDKContext(ts.ctx), providerPaymentStorageKey) + require.Equal(t, true, found) + require.Equal(t, uint64(0), providerPaymentStorage.GetComplainersTotalCu()) + } + + // go over responsive providers - make sure they are still staked + for i := unresponsiveProviderAmount; i < testProviderAmount; i++ { + // test the providers hasn't been unstaked + _, unstakeStoragefound, _ := ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[i].address) + require.False(t, unstakeStoragefound) + _, stakeStorageFound, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[i].address) + require.True(t, stakeStorageFound) + } +} + +// Test to measure the time the check for unresponsiveness every epoch start takes +func TestUnstakingProviderForUnresponsiveness(t *testing.T) { + // setup test for unresponsiveness + testClientAmount := 4 + testProviderAmount := 2 + ts := setupClientsAndProvidersForUnresponsiveness(t, testClientAmount, testProviderAmount) + + // get recommendedEpochNumToCollectPayment + recommendedEpochNumToCollectPayment := ts.keepers.Pairing.RecommendedEpochNumToCollectPayment(sdk.UnwrapSDKContext(ts.ctx)) + + // check which const is larger + largerConst := pairing.EPOCHS_NUM_TO_CHECK_CU_FOR_UNRESPONSIVE_PROVIDER + if largerConst < pairing.EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS { + largerConst = pairing.EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS + } + + // advance enough epochs so we can check punishment due to unresponsiveness (if the epoch is too early, there's no punishment) + for i := uint64(0); i < uint64(largerConst)+recommendedEpochNumToCollectPayment; i++ { + ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) + } + + // get provider1's balance before the stake + staked_amount, _, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) + balanceProvideratBeforeStake := staked_amount.Stake.Amount.Int64() + ts.keepers.BankKeeper.GetBalance(sdk.UnwrapSDKContext(ts.ctx), ts.providers[1].address, epochstoragetypes.TokenDenom).Amount.Int64() + + // create unresponsive data that includes provider1 being unresponsive + unresponsiveProvidersData, err := json.Marshal([]string{ts.providers[1].address.String()}) + require.Nil(t, err) + + // create relay requests for provider0 that contain complaints about provider1 + relayEpoch := sdk.UnwrapSDKContext(ts.ctx).BlockHeight() + for clientIndex := 0; clientIndex < testClientAmount; clientIndex++ { // testing testClientAmount of complaints + var Relays []*types.RelayRequest + relayRequest := &types.RelayRequest{ + Provider: ts.providers[0].address.String(), + ApiUrl: "", + Data: []byte(ts.spec.Apis[0].Name), + SessionId: uint64(0), + ChainID: ts.spec.Name, + CuSum: ts.spec.Apis[0].ComputeUnits*10 + uint64(clientIndex), + BlockHeight: relayEpoch, + RelayNum: 0, + RequestBlock: -1, + DataReliability: nil, + UnresponsiveProviders: unresponsiveProvidersData, // create the complaint + } + + sig, err := sigs.SignRelay(ts.clients[clientIndex].secretKey, *relayRequest) + relayRequest.Sig = sig + require.Nil(t, err) + Relays = append(Relays, relayRequest) + + // send relay payment and check the funds did transfer normally + payAndVerifyBalance(t, ts, types.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: Relays}, true, ts.clients[clientIndex].address, ts.providers[0].address) + } + + // advance enough epochs so the unresponsive provider will be punished + if largerConst < recommendedEpochNumToCollectPayment { + largerConst = recommendedEpochNumToCollectPayment + } + for i := uint64(0); i < largerConst; i++ { + ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) + } + + // test the unresponsive provider1 has been unstaked + _, unstakeStoragefound, _ := ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[1].address) + require.True(t, unstakeStoragefound) + _, stakeStorageFound, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) + require.False(t, stakeStorageFound) + + // validate the complainers CU field in provider1's providerPaymentStorage has been reset after being punished (note we use the epoch from the relay because that is when it got reported) + providerPaymentStorageKey := ts.keepers.Pairing.GetProviderPaymentStorageKey(sdk.UnwrapSDKContext(ts.ctx), ts.spec.Name, uint64(relayEpoch), ts.providers[1].address) + providerPaymentStorage, found := ts.keepers.Pairing.GetProviderPaymentStorage(sdk.UnwrapSDKContext(ts.ctx), providerPaymentStorageKey) + require.Equal(t, true, found) + require.Equal(t, uint64(0), providerPaymentStorage.GetComplainersTotalCu()) + + // test the responsive provider0 hasn't been unstaked + _, unstakeStoragefound, _ = ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[0].address) + require.False(t, unstakeStoragefound) + _, stakeStorageFound, _ = ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[0].address) + require.True(t, stakeStorageFound) + + // advance enough epochs so the current block will be deleted (advance more than the chain's memory - blocksToSave) + OriginalBlockHeight := uint64(sdk.UnwrapSDKContext(ts.ctx).BlockHeight()) + blocksToSave, err := ts.keepers.Epochstorage.BlocksToSave(sdk.UnwrapSDKContext(ts.ctx), OriginalBlockHeight) + require.Nil(t, err) + for { + ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) + blockHeight := uint64(sdk.UnwrapSDKContext(ts.ctx).BlockHeight()) + if blockHeight > blocksToSave+OriginalBlockHeight { + break + } + } + + // validate that the provider is no longer unstaked + _, unstakeStoragefound, _ = ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[1].address) + require.False(t, unstakeStoragefound) + + // also validate that the provider hasn't returned to the stake pool + _, stakeStorageFound, _ = ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) + require.False(t, stakeStorageFound) + + // validate that the provider's balance after the unstake is the same as before he staked + balanceProviderAfterUnstakeMoneyReturned := ts.keepers.BankKeeper.GetBalance(sdk.UnwrapSDKContext(ts.ctx), ts.providers[1].address, epochstoragetypes.TokenDenom).Amount.Int64() + require.Equal(t, balanceProvideratBeforeStake, balanceProviderAfterUnstakeMoneyReturned) +} + +func TestUnstakingProviderForUnresponsivenessContinueComplainingAfterUnstake(t *testing.T) { + // setup test for unresponsiveness + testClientAmount := 4 + testProviderAmount := 2 + ts := setupClientsAndProvidersForUnresponsiveness(t, testClientAmount, testProviderAmount) + + // get recommendedEpochNumToCollectPayment + recommendedEpochNumToCollectPayment := ts.keepers.Pairing.RecommendedEpochNumToCollectPayment(sdk.UnwrapSDKContext(ts.ctx)) + + // check which const is larger + largerConst := pairing.EPOCHS_NUM_TO_CHECK_CU_FOR_UNRESPONSIVE_PROVIDER + if largerConst < pairing.EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS { + largerConst = pairing.EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS + } + + // advance enough epochs so we can check punishment due to unresponsiveness (if the epoch is too early, there's no punishment) + for i := uint64(0); i < uint64(largerConst)+ts.keepers.Pairing.RecommendedEpochNumToCollectPayment(sdk.UnwrapSDKContext(ts.ctx)); i++ { + ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) + } + + // create unresponsive data that includes provider1 being unresponsive + unresponsiveProvidersData, err := json.Marshal([]string{ts.providers[1].address.String()}) + require.Nil(t, err) + + // create relay requests for provider0 that contain complaints about provider1 + relayEpoch := sdk.UnwrapSDKContext(ts.ctx).BlockHeight() + for clientIndex := 0; clientIndex < testClientAmount; clientIndex++ { // testing testClientAmount of complaints + var Relays []*types.RelayRequest + relayRequest := &types.RelayRequest{ + Provider: ts.providers[0].address.String(), + ApiUrl: "", + Data: []byte(ts.spec.Apis[0].Name), + SessionId: uint64(0), + ChainID: ts.spec.Name, + CuSum: ts.spec.Apis[0].ComputeUnits * 10, + BlockHeight: relayEpoch, + RelayNum: 0, + RequestBlock: -1, + DataReliability: nil, + UnresponsiveProviders: unresponsiveProvidersData, // create the complaint + } + + sig, err := sigs.SignRelay(ts.clients[clientIndex].secretKey, *relayRequest) + relayRequest.Sig = sig + require.Nil(t, err) + Relays = append(Relays, relayRequest) + + // send relay payment and check the funds did transfer normally + payAndVerifyBalance(t, ts, types.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: Relays}, true, ts.clients[clientIndex].address, ts.providers[0].address) + } + + // advance enough epochs so the unresponsive provider will be punished + if largerConst < recommendedEpochNumToCollectPayment { + largerConst = recommendedEpochNumToCollectPayment + } + for i := uint64(0); i < largerConst; i++ { + ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) + } + + // test the provider has been unstaked + _, unStakeStoragefound, _ := ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[1].address) + require.True(t, unStakeStoragefound) + _, stakeStorageFound, _ := ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) + require.False(t, stakeStorageFound) + + // validate the complainers CU field in provider1's providerPaymentStorage has been reset after being punished (note we use the epoch from the relay because that is when it got reported) + providerPaymentStorageKey := ts.keepers.Pairing.GetProviderPaymentStorageKey(sdk.UnwrapSDKContext(ts.ctx), ts.spec.Name, uint64(relayEpoch), ts.providers[1].address) + providerPaymentStorage, found := ts.keepers.Pairing.GetProviderPaymentStorage(sdk.UnwrapSDKContext(ts.ctx), providerPaymentStorageKey) + require.Equal(t, true, found) + require.Equal(t, uint64(0), providerPaymentStorage.GetComplainersTotalCu()) + + // advance some more epochs + for i := 0; i < 2; i++ { + ts.ctx = testkeeper.AdvanceEpoch(ts.ctx, ts.keepers) + } + + // create more relay requests for provider0 that contain complaints about provider1 (note, sessionID changed) + for clientIndex := 0; clientIndex < testClientAmount; clientIndex++ { // testing testClientAmount of complaints + var RelaysAfter []*types.RelayRequest + relayRequest := &types.RelayRequest{ + Provider: ts.providers[0].address.String(), + ApiUrl: "", + Data: []byte(ts.spec.Apis[0].Name), + SessionId: uint64(2), + ChainID: ts.spec.Name, + CuSum: ts.spec.Apis[0].ComputeUnits * 10, + BlockHeight: sdk.UnwrapSDKContext(ts.ctx).BlockHeight(), + RelayNum: 0, + RequestBlock: -1, + DataReliability: nil, + UnresponsiveProviders: unresponsiveProvidersData, // create the complaint + } + sig, err := sigs.SignRelay(ts.clients[clientIndex].secretKey, *relayRequest) + relayRequest.Sig = sig + require.Nil(t, err) + RelaysAfter = append(RelaysAfter, relayRequest) + + // send relay payment and check the funds did transfer normally + payAndVerifyBalance(t, ts, types.MsgRelayPayment{Creator: ts.providers[0].address.String(), Relays: RelaysAfter}, true, ts.clients[clientIndex].address, ts.providers[0].address) + } + + // test the provider is still unstaked + _, stakeStorageFound, _ = ts.keepers.Epochstorage.GetStakeEntryByAddressCurrent(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.spec.Name, ts.providers[1].address) + require.False(t, stakeStorageFound) + _, unStakeStoragefound, _ = ts.keepers.Epochstorage.UnstakeEntryByAddress(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey, ts.providers[1].address) + require.True(t, unStakeStoragefound) + + // get the current unstake storage + storage, foundStorage := ts.keepers.Epochstorage.GetStakeStorageUnstake(sdk.UnwrapSDKContext(ts.ctx), epochstoragetypes.ProviderKey) + require.True(t, foundStorage) + + // validate the punished provider is not shown twice (or more) in the unstake storage + var numberOfAppearances int + for _, stored := range storage.StakeEntries { + if stored.Address == ts.providers[1].address.String() { + numberOfAppearances += 1 + } + } + require.Equal(t, numberOfAppearances, 1) +} diff --git a/x/pairing/module.go b/x/pairing/module.go index c742d380fa..821c6e0ed7 100644 --- a/x/pairing/module.go +++ b/x/pairing/module.go @@ -16,7 +16,6 @@ import ( cdctypes "github.com/cosmos/cosmos-sdk/codec/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" - "github.com/lavanet/lava/utils" "github.com/lavanet/lava/x/pairing/client/cli" "github.com/lavanet/lava/x/pairing/keeper" "github.com/lavanet/lava/x/pairing/types" @@ -27,6 +26,11 @@ var ( _ module.AppModuleBasic = AppModuleBasic{} ) +const ( + EPOCHS_NUM_TO_CHECK_CU_FOR_UNRESPONSIVE_PROVIDER uint64 = 4 // number of epochs to sum CU that the provider serviced + EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS uint64 = 2 // number of epochs to sum CU of complainers against the provider +) + // ---------------------------------------------------------------------------- // AppModuleBasic // ---------------------------------------------------------------------------- @@ -168,26 +172,9 @@ func (AppModule) ConsensusVersion() uint64 { return 2 } // BeginBlock executes all ABCI BeginBlock logic respective to the capability module. func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock) { - logger := am.keeper.Logger(ctx) - logOnErr := func(err error, failingFunc string) { - if err != nil { - attrs := map[string]string{"error": err.Error()} - utils.LavaError(ctx, logger, "new_epoch", attrs, failingFunc) - } - } if am.keeper.IsEpochStart(ctx) { - // on session start we need to do: - // 1. remove old session payments - // 2. unstake any unstaking providers - // 3. unstake any unstaking users - - // 1. - err := am.keeper.RemoveOldEpochPayment(ctx) - logOnErr(err, "RemoveOldEpochPayment") - - // 2+3. - err = am.keeper.CheckUnstakingForCommit(ctx) - logOnErr(err, "CheckUnstakingForCommit") + // run functions that are supposed to run in epoch start + am.keeper.EpochStart(ctx, EPOCHS_NUM_TO_CHECK_CU_FOR_UNRESPONSIVE_PROVIDER, EPOCHS_NUM_TO_CHECK_FOR_COMPLAINERS) } } diff --git a/x/pairing/module_simulation.go b/x/pairing/module_simulation.go index 4227d8e0df..73da491fd1 100644 --- a/x/pairing/module_simulation.go +++ b/x/pairing/module_simulation.go @@ -87,6 +87,9 @@ func (am AppModule) RandomizedParams(_ *rand.Rand) []simtypes.ParamChange { simulation.NewSimParamChange(types.ModuleName, string(types.KeyEpochBlocksOverlap), func(r *rand.Rand) string { return string(types.Amino.MustMarshalJSON(pairingParams.EpochBlocksOverlap)) }), + simulation.NewSimParamChange(types.ModuleName, string(types.KeyRecommendedEpochNumToCollectPayment), func(r *rand.Rand) string { + return string(types.Amino.MustMarshalJSON(pairingParams.RecommendedEpochNumToCollectPayment)) + }), } } diff --git a/x/pairing/types/expected_keepers.go b/x/pairing/types/expected_keepers.go index 4fcaa6b866..1021791bbd 100644 --- a/x/pairing/types/expected_keepers.go +++ b/x/pairing/types/expected_keepers.go @@ -13,6 +13,7 @@ type SpecKeeper interface { GetSpec(ctx sdk.Context, index string) (val spectypes.Spec, found bool) GeolocationCount(ctx sdk.Context) uint64 GetExpectedInterfacesForSpec(ctx sdk.Context, chainID string) map[string]bool + GetAllChainIDs(ctx sdk.Context) (chainIDs []string) } type EpochstorageKeeper interface { diff --git a/x/pairing/types/params.go b/x/pairing/types/params.go index 83dd4ae074..f3c85e7ca8 100644 --- a/x/pairing/types/params.go +++ b/x/pairing/types/params.go @@ -78,6 +78,11 @@ var ( DefaultQoSWeight sdk.Dec = sdk.NewDecWithPrec(5, 1) // 0.5 ) +var ( + KeyRecommendedEpochNumToCollectPayment = []byte("RecommendedEpochNumToCollectPayment") // the recommended amount of max epochs that a provider should wait before collecting its payment (if he'll collect later, there's a higher chance to get punished) + DefaultRecommendedEpochNumToCollectPayment uint64 = 3 +) + // ParamKeyTable the param key table for launch module func ParamKeyTable() paramtypes.KeyTable { return paramtypes.NewKeyTable().RegisterParamSet(&Params{}) @@ -96,19 +101,21 @@ func NewParams( slashLimit sdk.Dec, dataReliabilityReward sdk.Dec, qoSWeight sdk.Dec, + recommendedEpochNumToCollectPayment uint64, ) Params { return Params{ - MintCoinsPerCU: mintCoinsPerCU, - BurnCoinsPerCU: burnCoinsPerCU, - FraudStakeSlashingFactor: fraudStakeSlashingFactor, - FraudSlashingAmount: fraudSlashingAmount, - ServicersToPairCount: servicersToPairCount, - EpochBlocksOverlap: epochBlocksOverlap, - StakeToMaxCUList: stakeToMaxCUList, - UnpayLimit: unpayLimit, - SlashLimit: slashLimit, - DataReliabilityReward: dataReliabilityReward, - QoSWeight: qoSWeight, + MintCoinsPerCU: mintCoinsPerCU, + BurnCoinsPerCU: burnCoinsPerCU, + FraudStakeSlashingFactor: fraudStakeSlashingFactor, + FraudSlashingAmount: fraudSlashingAmount, + ServicersToPairCount: servicersToPairCount, + EpochBlocksOverlap: epochBlocksOverlap, + StakeToMaxCUList: stakeToMaxCUList, + UnpayLimit: unpayLimit, + SlashLimit: slashLimit, + DataReliabilityReward: dataReliabilityReward, + QoSWeight: qoSWeight, + RecommendedEpochNumToCollectPayment: recommendedEpochNumToCollectPayment, } } @@ -126,6 +133,7 @@ func DefaultParams() Params { DefaultSlashLimit, DefaultDataReliabilityReward, DefaultQoSWeight, + DefaultRecommendedEpochNumToCollectPayment, ) } @@ -143,6 +151,7 @@ func (p *Params) ParamSetPairs() paramtypes.ParamSetPairs { paramtypes.NewParamSetPair(KeySlashLimit, &p.SlashLimit, validateSlashLimit), paramtypes.NewParamSetPair(KeyDataReliabilityReward, &p.DataReliabilityReward, validateDataReliabilityReward), paramtypes.NewParamSetPair(KeyQoSWeight, &p.QoSWeight, validateQoSWeight), + paramtypes.NewParamSetPair(KeyRecommendedEpochNumToCollectPayment, &p.RecommendedEpochNumToCollectPayment, validateRecommendedEpochNumToCollectPayment), } } @@ -186,6 +195,9 @@ func (p Params) Validate() error { if err := validateDataReliabilityReward(p.DataReliabilityReward); err != nil { return err } + if err := validateRecommendedEpochNumToCollectPayment(p.RecommendedEpochNumToCollectPayment); err != nil { + return err + } return nil } @@ -354,3 +366,16 @@ func validateQoSWeight(v interface{}) error { return nil } + +// validateRecommendedEpochNumToCollectPayment validates the RecommendedEpochNumToCollectPayment param +func validateRecommendedEpochNumToCollectPayment(v interface{}) error { + recommendedEpochNumToCollectPayment, ok := v.(uint64) + if !ok { + return fmt.Errorf("invalid parameter type: %T", v) + } + + // TODO implement validation + _ = recommendedEpochNumToCollectPayment + + return nil +} diff --git a/x/pairing/types/params.pb.go b/x/pairing/types/params.pb.go index d24fe17731..f2a6b7bc99 100644 --- a/x/pairing/types/params.pb.go +++ b/x/pairing/types/params.pb.go @@ -26,17 +26,18 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // Params defines the parameters for the module. type Params struct { - MintCoinsPerCU github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=mintCoinsPerCU,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"mintCoinsPerCU" yaml:"mint_coins_per_cu"` - BurnCoinsPerCU github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=burnCoinsPerCU,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"burnCoinsPerCU" yaml:"burn_coins_per_cu"` - FraudStakeSlashingFactor github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=fraudStakeSlashingFactor,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"fraudStakeSlashingFactor" yaml:"fraud_stake_slashing_factor"` - FraudSlashingAmount uint64 `protobuf:"varint,6,opt,name=fraudSlashingAmount,proto3" json:"fraudSlashingAmount,omitempty" yaml:"fraud_slashing_amount"` - ServicersToPairCount uint64 `protobuf:"varint,7,opt,name=servicersToPairCount,proto3" json:"servicersToPairCount,omitempty" yaml:"servicers_to_pair_count"` - EpochBlocksOverlap uint64 `protobuf:"varint,8,opt,name=epochBlocksOverlap,proto3" json:"epochBlocksOverlap,omitempty" yaml:"epoch_blocks_overlap"` - StakeToMaxCUList StakeToMaxCUList `protobuf:"bytes,9,opt,name=stakeToMaxCUList,proto3,customtype=StakeToMaxCUList" json:"stakeToMaxCUList" yaml:"stake_to_computeunits_list"` - UnpayLimit github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,10,opt,name=unpayLimit,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"unpayLimit" yaml:"unpay_limit"` - SlashLimit github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,11,opt,name=slashLimit,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"slashLimit" yaml:"slash_limit"` - DataReliabilityReward github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,12,opt,name=dataReliabilityReward,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"dataReliabilityReward" yaml:"data_reliability_reward"` - QoSWeight github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,13,opt,name=QoSWeight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"QoSWeight" yaml:"data_reliability_reward"` + MintCoinsPerCU github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,3,opt,name=mintCoinsPerCU,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"mintCoinsPerCU" yaml:"mint_coins_per_cu"` + BurnCoinsPerCU github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,4,opt,name=burnCoinsPerCU,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"burnCoinsPerCU" yaml:"burn_coins_per_cu"` + FraudStakeSlashingFactor github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,5,opt,name=fraudStakeSlashingFactor,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"fraudStakeSlashingFactor" yaml:"fraud_stake_slashing_factor"` + FraudSlashingAmount uint64 `protobuf:"varint,6,opt,name=fraudSlashingAmount,proto3" json:"fraudSlashingAmount,omitempty" yaml:"fraud_slashing_amount"` + ServicersToPairCount uint64 `protobuf:"varint,7,opt,name=servicersToPairCount,proto3" json:"servicersToPairCount,omitempty" yaml:"servicers_to_pair_count"` + EpochBlocksOverlap uint64 `protobuf:"varint,8,opt,name=epochBlocksOverlap,proto3" json:"epochBlocksOverlap,omitempty" yaml:"epoch_blocks_overlap"` + StakeToMaxCUList StakeToMaxCUList `protobuf:"bytes,9,opt,name=stakeToMaxCUList,proto3,customtype=StakeToMaxCUList" json:"stakeToMaxCUList" yaml:"stake_to_computeunits_list"` + UnpayLimit github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,10,opt,name=unpayLimit,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"unpayLimit" yaml:"unpay_limit"` + SlashLimit github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,11,opt,name=slashLimit,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"slashLimit" yaml:"slash_limit"` + DataReliabilityReward github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,12,opt,name=dataReliabilityReward,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"dataReliabilityReward" yaml:"data_reliability_reward"` + QoSWeight github_com_cosmos_cosmos_sdk_types.Dec `protobuf:"bytes,13,opt,name=QoSWeight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Dec" json:"QoSWeight" yaml:"data_reliability_reward"` + RecommendedEpochNumToCollectPayment uint64 `protobuf:"varint,14,opt,name=recommendedEpochNumToCollectPayment,proto3" json:"recommendedEpochNumToCollectPayment,omitempty" yaml:"recommended_epoch_num_to_collect_payment"` } func (m *Params) Reset() { *m = Params{} } @@ -92,6 +93,13 @@ func (m *Params) GetEpochBlocksOverlap() uint64 { return 0 } +func (m *Params) GetRecommendedEpochNumToCollectPayment() uint64 { + if m != nil { + return m.RecommendedEpochNumToCollectPayment + } + return 0 +} + func init() { proto.RegisterType((*Params)(nil), "lavanet.lava.pairing.Params") } @@ -99,44 +107,48 @@ func init() { func init() { proto.RegisterFile("pairing/params.proto", fileDescriptor_72cc734580d3bc3a) } var fileDescriptor_72cc734580d3bc3a = []byte{ - // 592 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0x3f, 0x6f, 0xd3, 0x4e, - 0x18, 0xc7, 0xe3, 0x36, 0xbf, 0xfe, 0x9a, 0xe3, 0x8f, 0xa2, 0x23, 0x48, 0x16, 0x20, 0xbb, 0x78, - 0x80, 0x2e, 0xc4, 0x03, 0x5b, 0x25, 0x86, 0x26, 0x15, 0x43, 0x55, 0xd4, 0xe0, 0xb4, 0x20, 0xb1, - 0x9c, 0x2e, 0xce, 0xd5, 0x39, 0xc5, 0xf6, 0x59, 0x77, 0xe7, 0xd0, 0xbc, 0x01, 0xe6, 0x8e, 0x8c, - 0xbc, 0x16, 0xa6, 0x8e, 0x1d, 0x11, 0x83, 0x85, 0x92, 0x77, 0x90, 0x57, 0x80, 0xfc, 0xd8, 0x6d, - 0xd2, 0x10, 0x86, 0xa8, 0x62, 0x3a, 0xcb, 0xf7, 0x7d, 0x3e, 0x9f, 0xd3, 0x3d, 0xa7, 0x07, 0x35, - 0x12, 0xca, 0x25, 0x8f, 0x03, 0x37, 0xa1, 0x92, 0x46, 0xaa, 0x99, 0x48, 0xa1, 0x05, 0x6e, 0x84, - 0x74, 0x44, 0x63, 0xa6, 0x9b, 0xf9, 0xda, 0x2c, 0x23, 0x4f, 0x1a, 0x81, 0x08, 0x04, 0x04, 0xdc, - 0xfc, 0xab, 0xc8, 0x3a, 0xdf, 0x6b, 0x68, 0xab, 0x03, 0xc5, 0x58, 0xa2, 0x87, 0x11, 0x8f, 0x75, - 0x5b, 0xf0, 0x58, 0x75, 0x98, 0x6c, 0x9f, 0x9a, 0x9b, 0x3b, 0xc6, 0x6e, 0xad, 0x75, 0x78, 0x99, - 0xd9, 0x95, 0x9f, 0x99, 0xfd, 0x22, 0xe0, 0x7a, 0x90, 0xf6, 0x9a, 0xbe, 0x88, 0x5c, 0x5f, 0xa8, - 0x48, 0xa8, 0x72, 0x79, 0xa5, 0xfa, 0x43, 0x57, 0x8f, 0x13, 0xa6, 0x9a, 0x07, 0xcc, 0x9f, 0x65, - 0xb6, 0x39, 0xa6, 0x51, 0xb8, 0xe7, 0xe4, 0x34, 0xe2, 0xe7, 0x38, 0x92, 0x30, 0x49, 0xfc, 0xd4, - 0xf1, 0x96, 0x0c, 0xb9, 0xb3, 0x97, 0xca, 0x78, 0xc1, 0x59, 0xbd, 0x9b, 0x33, 0xa7, 0x2d, 0x3b, - 0x6f, 0x1b, 0xf0, 0x85, 0x81, 0xcc, 0x33, 0x49, 0xd3, 0x7e, 0x57, 0xd3, 0x21, 0xeb, 0x86, 0x54, - 0x0d, 0x78, 0x1c, 0xbc, 0xa5, 0xbe, 0x16, 0xd2, 0xfc, 0x0f, 0xf4, 0x27, 0x6b, 0xeb, 0x9d, 0x42, - 0x0f, 0x5c, 0xa2, 0x72, 0x30, 0x51, 0x25, 0x99, 0x9c, 0x01, 0xda, 0xf1, 0xfe, 0x6a, 0xc5, 0x1e, - 0x7a, 0x54, 0xec, 0x95, 0xbf, 0xf7, 0x23, 0x91, 0xc6, 0xda, 0xdc, 0xda, 0x31, 0x76, 0xab, 0xad, - 0x9d, 0x59, 0x66, 0x3f, 0xbb, 0x85, 0xbf, 0x06, 0x53, 0x88, 0x39, 0xde, 0xaa, 0x62, 0xfc, 0x01, - 0x35, 0x14, 0x93, 0x23, 0xee, 0x33, 0xa9, 0x4e, 0x44, 0x87, 0x72, 0xd9, 0x06, 0xe8, 0xff, 0x00, - 0x75, 0x66, 0x99, 0x6d, 0x15, 0xd0, 0x9b, 0x14, 0xd1, 0x82, 0xe4, 0xaf, 0x85, 0xf8, 0x05, 0x76, - 0x65, 0x3d, 0x3e, 0x46, 0x98, 0x25, 0xc2, 0x1f, 0xb4, 0x42, 0xe1, 0x0f, 0xd5, 0xf1, 0x88, 0xc9, - 0x90, 0x26, 0xe6, 0x36, 0x50, 0xed, 0x59, 0x66, 0x3f, 0x2d, 0xa8, 0x90, 0x21, 0x3d, 0x08, 0x11, - 0x51, 0xa4, 0x1c, 0x6f, 0x45, 0x29, 0xe6, 0xa8, 0x0e, 0x17, 0x76, 0x22, 0xde, 0xd1, 0xf3, 0xf6, - 0xe9, 0x11, 0x57, 0xda, 0xac, 0x41, 0x1b, 0xde, 0x94, 0x6d, 0xa8, 0x77, 0x97, 0xf6, 0x67, 0x99, - 0xfd, 0xbc, 0x3c, 0x3c, 0x5c, 0xb5, 0x16, 0xc4, 0x17, 0x51, 0x92, 0x6a, 0x96, 0xc6, 0x5c, 0x2b, - 0x12, 0x72, 0xa5, 0x1d, 0xef, 0x0f, 0x2c, 0xee, 0x23, 0x94, 0xc6, 0x09, 0x1d, 0x1f, 0xf1, 0x88, - 0x6b, 0x13, 0x81, 0xe4, 0x60, 0xed, 0x5e, 0xe3, 0x42, 0x0d, 0x24, 0x12, 0xe6, 0x28, 0xc7, 0x5b, - 0xe0, 0xe6, 0x16, 0x68, 0x51, 0x61, 0xb9, 0x77, 0x37, 0x0b, 0x90, 0x6e, 0x2c, 0x73, 0x2e, 0xfe, - 0x62, 0xa0, 0xc7, 0x7d, 0xaa, 0xa9, 0xc7, 0x42, 0x4e, 0x7b, 0x3c, 0xe4, 0x7a, 0xec, 0xb1, 0xcf, - 0x54, 0xf6, 0xcd, 0xfb, 0x60, 0xec, 0xac, 0x6d, 0x2c, 0xdf, 0x43, 0x0e, 0x25, 0x72, 0x4e, 0x25, - 0x12, 0xb0, 0x8e, 0xb7, 0x5a, 0x87, 0x63, 0x54, 0x7b, 0x2f, 0xba, 0x1f, 0x19, 0x0f, 0x06, 0xda, - 0x7c, 0xf0, 0x8f, 0xdc, 0x73, 0xc5, 0x5e, 0xf5, 0xeb, 0x37, 0xbb, 0x72, 0x58, 0xdd, 0x36, 0xea, - 0x1b, 0x87, 0xd5, 0xed, 0x8d, 0xfa, 0x66, 0x6b, 0xff, 0x72, 0x62, 0x19, 0x57, 0x13, 0xcb, 0xf8, - 0x35, 0xb1, 0x8c, 0x8b, 0xa9, 0x55, 0xb9, 0x9a, 0x5a, 0x95, 0x1f, 0x53, 0xab, 0xf2, 0xe9, 0xe5, - 0xc2, 0x01, 0xca, 0xa9, 0x08, 0xab, 0x7b, 0xee, 0x5e, 0x8f, 0x4e, 0x38, 0x45, 0x6f, 0x0b, 0xc6, - 0xe1, 0xeb, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0x32, 0x2d, 0x65, 0x2c, 0x52, 0x05, 0x00, 0x00, + // 650 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x94, 0x41, 0x6f, 0xd3, 0x3c, + 0x18, 0xc7, 0x9b, 0xad, 0xef, 0xde, 0xcd, 0xef, 0xcb, 0x54, 0x85, 0x22, 0x45, 0x80, 0x92, 0x11, + 0x24, 0xd8, 0x85, 0xe6, 0xb0, 0xdb, 0x24, 0x0e, 0x6b, 0x07, 0x87, 0x69, 0xb0, 0x92, 0x76, 0x20, + 0x71, 0xb1, 0x5c, 0xc7, 0x6b, 0xad, 0xc5, 0x76, 0x64, 0x3b, 0x63, 0xfd, 0x00, 0x70, 0xde, 0x91, + 0x23, 0x1f, 0x67, 0xe2, 0xb4, 0x23, 0xe2, 0x10, 0xa1, 0xed, 0x1b, 0xf4, 0x13, 0xa0, 0xd8, 0xd9, + 0xd6, 0x8d, 0x22, 0x31, 0x4d, 0x9c, 0x5c, 0xd5, 0xff, 0xe7, 0xf7, 0x8b, 0x9e, 0xe7, 0x91, 0x41, + 0x33, 0x43, 0x54, 0x52, 0x3e, 0x8c, 0x32, 0x24, 0x11, 0x53, 0xad, 0x4c, 0x0a, 0x2d, 0xdc, 0x66, + 0x8a, 0x0e, 0x10, 0x27, 0xba, 0x55, 0x9e, 0xad, 0x2a, 0x72, 0xbf, 0x39, 0x14, 0x43, 0x61, 0x02, + 0x51, 0xf9, 0xcb, 0x66, 0xc3, 0xaf, 0x00, 0x2c, 0x74, 0x4d, 0xb1, 0x2b, 0xc1, 0x32, 0xa3, 0x5c, + 0x77, 0x04, 0xe5, 0xaa, 0x4b, 0x64, 0x67, 0xd7, 0x9b, 0x5f, 0x71, 0x56, 0x97, 0xda, 0x5b, 0xc7, + 0x45, 0x50, 0xfb, 0x5e, 0x04, 0x4f, 0x86, 0x54, 0x8f, 0xf2, 0x41, 0x0b, 0x0b, 0x16, 0x61, 0xa1, + 0x98, 0x50, 0xd5, 0xf1, 0x4c, 0x25, 0xfb, 0x91, 0x1e, 0x67, 0x44, 0xb5, 0x36, 0x09, 0x9e, 0x14, + 0x81, 0x37, 0x46, 0x2c, 0x5d, 0x0f, 0x4b, 0x1a, 0xc4, 0x25, 0x0e, 0x66, 0x44, 0x42, 0x9c, 0x87, + 0xf1, 0x35, 0x43, 0xe9, 0x1c, 0xe4, 0x92, 0x4f, 0x39, 0xeb, 0xb7, 0x73, 0x96, 0xb4, 0xeb, 0xce, + 0xab, 0x06, 0xf7, 0xc8, 0x01, 0xde, 0x9e, 0x44, 0x79, 0xd2, 0xd3, 0x68, 0x9f, 0xf4, 0x52, 0xa4, + 0x46, 0x94, 0x0f, 0x5f, 0x22, 0xac, 0x85, 0xf4, 0xfe, 0x31, 0xfa, 0xfe, 0x8d, 0xf5, 0xa1, 0xd5, + 0x1b, 0x2e, 0x54, 0x25, 0x18, 0xaa, 0x8a, 0x0c, 0xf7, 0x0c, 0x3a, 0x8c, 0x7f, 0x6b, 0x75, 0x63, + 0x70, 0xd7, 0xde, 0x55, 0x7f, 0x6f, 0x30, 0x91, 0x73, 0xed, 0x2d, 0xac, 0x38, 0xab, 0xf5, 0xf6, + 0xca, 0xa4, 0x08, 0x1e, 0x5e, 0xc1, 0x9f, 0x83, 0x91, 0x89, 0x85, 0xf1, 0xac, 0x62, 0xf7, 0x2d, + 0x68, 0x2a, 0x22, 0x0f, 0x28, 0x26, 0x52, 0xf5, 0x45, 0x17, 0x51, 0xd9, 0x31, 0xd0, 0x7f, 0x0d, + 0x34, 0x9c, 0x14, 0x81, 0x6f, 0xa1, 0x17, 0x29, 0xa8, 0x05, 0x2c, 0xb7, 0x05, 0x62, 0x8b, 0x9d, + 0x59, 0xef, 0xee, 0x00, 0x97, 0x64, 0x02, 0x8f, 0xda, 0xa9, 0xc0, 0xfb, 0x6a, 0xe7, 0x80, 0xc8, + 0x14, 0x65, 0xde, 0xa2, 0xa1, 0x06, 0x93, 0x22, 0x78, 0x60, 0xa9, 0x26, 0x03, 0x07, 0x26, 0x04, + 0x85, 0x4d, 0x85, 0xf1, 0x8c, 0x52, 0x97, 0x82, 0x86, 0x69, 0x58, 0x5f, 0xbc, 0x42, 0x87, 0x9d, + 0xdd, 0x6d, 0xaa, 0xb4, 0xb7, 0x64, 0xc6, 0xf0, 0xbc, 0x1a, 0x43, 0xa3, 0x77, 0xed, 0x7e, 0x52, + 0x04, 0x8f, 0xaa, 0x8f, 0x37, 0xad, 0xd6, 0x02, 0x62, 0xc1, 0xb2, 0x5c, 0x93, 0x9c, 0x53, 0xad, + 0x60, 0x4a, 0x95, 0x0e, 0xe3, 0x5f, 0xb0, 0x6e, 0x02, 0x40, 0xce, 0x33, 0x34, 0xde, 0xa6, 0x8c, + 0x6a, 0x0f, 0x18, 0xc9, 0xe6, 0x8d, 0x67, 0xed, 0x5a, 0xb5, 0x21, 0xc1, 0xb4, 0x44, 0x85, 0xf1, + 0x14, 0xb7, 0xb4, 0x98, 0x11, 0x59, 0xcb, 0x7f, 0xb7, 0xb3, 0x18, 0xd2, 0x85, 0xe5, 0x92, 0xeb, + 0x7e, 0x72, 0xc0, 0xbd, 0x04, 0x69, 0x14, 0x93, 0x94, 0xa2, 0x01, 0x4d, 0xa9, 0x1e, 0xc7, 0xe4, + 0x03, 0x92, 0x89, 0xf7, 0xbf, 0x31, 0x76, 0x6f, 0x6c, 0xac, 0xf6, 0xa1, 0x84, 0x42, 0x79, 0x49, + 0x85, 0xd2, 0x60, 0xc3, 0x78, 0xb6, 0xce, 0xe5, 0x60, 0xe9, 0x8d, 0xe8, 0xbd, 0x23, 0x74, 0x38, + 0xd2, 0xde, 0x9d, 0xbf, 0xe4, 0xbe, 0x54, 0xb8, 0x1f, 0x1d, 0xf0, 0x58, 0x12, 0x2c, 0x18, 0x23, + 0x3c, 0x21, 0xc9, 0x8b, 0x72, 0xa3, 0x5e, 0xe7, 0xac, 0x2f, 0x3a, 0x22, 0x4d, 0x09, 0xd6, 0x5d, + 0x34, 0x66, 0x84, 0x6b, 0x6f, 0xd9, 0xac, 0xe4, 0xda, 0xa4, 0x08, 0x22, 0x0b, 0x9f, 0x2a, 0x82, + 0x76, 0x3d, 0x79, 0xce, 0xec, 0xee, 0x98, 0x42, 0x98, 0xd9, 0xca, 0x30, 0xfe, 0x13, 0xfe, 0x7a, + 0xfd, 0xf3, 0x97, 0xa0, 0xb6, 0x55, 0x5f, 0x74, 0x1a, 0x73, 0x5b, 0xf5, 0xc5, 0xb9, 0xc6, 0x7c, + 0x7b, 0xe3, 0xf8, 0xd4, 0x77, 0x4e, 0x4e, 0x7d, 0xe7, 0xc7, 0xa9, 0xef, 0x1c, 0x9d, 0xf9, 0xb5, + 0x93, 0x33, 0xbf, 0xf6, 0xed, 0xcc, 0xaf, 0xbd, 0x7f, 0x3a, 0xd5, 0x88, 0xea, 0x75, 0x36, 0x67, + 0x74, 0x18, 0x9d, 0x3f, 0xe1, 0xa6, 0x1b, 0x83, 0x05, 0xf3, 0x2c, 0xaf, 0xfd, 0x0c, 0x00, 0x00, + 0xff, 0xff, 0xa8, 0x01, 0x54, 0x8a, 0xda, 0x05, 0x00, 0x00, } func (m *Params) Marshal() (dAtA []byte, err error) { @@ -159,6 +171,11 @@ func (m *Params) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.RecommendedEpochNumToCollectPayment != 0 { + i = encodeVarintParams(dAtA, i, uint64(m.RecommendedEpochNumToCollectPayment)) + i-- + dAtA[i] = 0x70 + } { size := m.QoSWeight.Size() i -= size @@ -299,6 +316,9 @@ func (m *Params) Size() (n int) { n += 1 + l + sovParams(uint64(l)) l = m.QoSWeight.Size() n += 1 + l + sovParams(uint64(l)) + if m.RecommendedEpochNumToCollectPayment != 0 { + n += 1 + sovParams(uint64(m.RecommendedEpochNumToCollectPayment)) + } return n } @@ -666,6 +686,25 @@ func (m *Params) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 14: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RecommendedEpochNumToCollectPayment", wireType) + } + m.RecommendedEpochNumToCollectPayment = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowParams + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.RecommendedEpochNumToCollectPayment |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipParams(dAtA[iNdEx:]) diff --git a/x/pairing/types/provider_payment_storage.pb.go b/x/pairing/types/provider_payment_storage.pb.go index 302601fe9f..40a774a086 100644 --- a/x/pairing/types/provider_payment_storage.pb.go +++ b/x/pairing/types/provider_payment_storage.pb.go @@ -25,8 +25,8 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type ProviderPaymentStorage struct { Index string `protobuf:"bytes,1,opt,name=index,proto3" json:"index,omitempty"` Epoch uint64 `protobuf:"varint,3,opt,name=epoch,proto3" json:"epoch,omitempty"` - UnresponsivenessComplaints []string `protobuf:"bytes,4,rep,name=unresponsiveness_complaints,json=unresponsivenessComplaints,proto3" json:"unresponsiveness_complaints,omitempty"` UniquePaymentStorageClientProviderKeys []string `protobuf:"bytes,5,rep,name=uniquePaymentStorageClientProviderKeys,proto3" json:"uniquePaymentStorageClientProviderKeys,omitempty"` + ComplainersTotalCu uint64 `protobuf:"varint,6,opt,name=complainersTotalCu,proto3" json:"complainersTotalCu,omitempty"` } func (m *ProviderPaymentStorage) Reset() { *m = ProviderPaymentStorage{} } @@ -76,18 +76,18 @@ func (m *ProviderPaymentStorage) GetEpoch() uint64 { return 0 } -func (m *ProviderPaymentStorage) GetUnresponsivenessComplaints() []string { +func (m *ProviderPaymentStorage) GetUniquePaymentStorageClientProviderKeys() []string { if m != nil { - return m.UnresponsivenessComplaints + return m.UniquePaymentStorageClientProviderKeys } return nil } -func (m *ProviderPaymentStorage) GetUniquePaymentStorageClientProviderKeys() []string { +func (m *ProviderPaymentStorage) GetComplainersTotalCu() uint64 { if m != nil { - return m.UniquePaymentStorageClientProviderKeys + return m.ComplainersTotalCu } - return nil + return 0 } func init() { @@ -99,25 +99,25 @@ func init() { } var fileDescriptor_4f1d2e8d774659ae = []byte{ - // 282 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x90, 0xb1, 0x4a, 0xf4, 0x40, - 0x14, 0x85, 0x33, 0x7f, 0xb2, 0x3f, 0x6e, 0x2a, 0x09, 0x8b, 0x84, 0x15, 0x86, 0x60, 0xb1, 0xa6, - 0x4a, 0x0a, 0xed, 0x45, 0xb7, 0xd3, 0x66, 0x89, 0x60, 0x61, 0x13, 0x66, 0xb3, 0x97, 0xec, 0x40, - 0x32, 0x33, 0xce, 0x4c, 0xc2, 0xe6, 0x2d, 0x7c, 0x2c, 0xcb, 0x2d, 0x2d, 0x25, 0x79, 0x11, 0x49, - 0x26, 0x11, 0xdc, 0xca, 0xea, 0x72, 0x2e, 0xe7, 0x3b, 0x1c, 0x8e, 0xbb, 0x12, 0x84, 0x4a, 0xca, - 0xf2, 0x58, 0x48, 0x5e, 0xd3, 0x1d, 0xc8, 0x54, 0x90, 0xa6, 0x04, 0xa6, 0x53, 0xa5, 0xb9, 0x24, - 0x39, 0x44, 0x42, 0x72, 0xcd, 0xbd, 0x45, 0x41, 0x6a, 0xc2, 0x40, 0x47, 0xfd, 0x8d, 0x46, 0x68, - 0x79, 0x3b, 0xd1, 0x15, 0xa3, 0x6f, 0x15, 0x9c, 0xb2, 0x69, 0x56, 0xd0, 0x5e, 0x4e, 0xd9, 0x26, - 0xeb, 0xaa, 0x43, 0xee, 0xc5, 0x66, 0x7c, 0x6d, 0x0c, 0xf1, 0x6c, 0x00, 0x6f, 0xe1, 0xce, 0x28, - 0xdb, 0xc1, 0xc1, 0x47, 0x01, 0x0a, 0xe7, 0x89, 0x11, 0xfd, 0x17, 0x04, 0xcf, 0xf6, 0xbe, 0x1d, - 0xa0, 0xd0, 0x49, 0x8c, 0xf0, 0xee, 0xdc, 0xcb, 0x8a, 0x49, 0x50, 0x82, 0x33, 0x45, 0x6b, 0x60, - 0xa0, 0x54, 0x9a, 0xf1, 0x52, 0x14, 0x84, 0x32, 0xad, 0x7c, 0x27, 0xb0, 0xc3, 0x79, 0xb2, 0x3c, - 0xb5, 0xac, 0x7f, 0x1c, 0xde, 0x8b, 0xbb, 0x32, 0xbd, 0x7f, 0x97, 0x58, 0x0f, 0xa5, 0xa7, 0x82, - 0x4f, 0xd0, 0x28, 0x7f, 0x36, 0x64, 0xfd, 0xd1, 0xfd, 0xe8, 0x9c, 0xfd, 0x3b, 0xb7, 0x1f, 0xee, - 0x3f, 0x5a, 0x8c, 0x8e, 0x2d, 0x46, 0x5f, 0x2d, 0x46, 0xef, 0x1d, 0xb6, 0x8e, 0x1d, 0xb6, 0x3e, - 0x3b, 0x6c, 0xbd, 0x5e, 0xe7, 0x54, 0xef, 0xab, 0x6d, 0x94, 0xf1, 0x32, 0x1e, 0x67, 0x1d, 0x6e, - 0x7c, 0x88, 0xa7, 0x3d, 0x75, 0x23, 0x40, 0x6d, 0xff, 0x0f, 0x7b, 0xdd, 0x7c, 0x07, 0x00, 0x00, - 0xff, 0xff, 0xb5, 0x8b, 0x82, 0xb1, 0xa5, 0x01, 0x00, 0x00, + // 276 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x52, 0x2b, 0x48, 0xcc, 0x2c, + 0xca, 0xcc, 0x4b, 0xd7, 0x2f, 0x28, 0xca, 0x2f, 0xcb, 0x4c, 0x49, 0x2d, 0x8a, 0x2f, 0x48, 0xac, + 0xcc, 0x4d, 0xcd, 0x2b, 0x89, 0x2f, 0x2e, 0xc9, 0x2f, 0x4a, 0x4c, 0x4f, 0xd5, 0x2b, 0x28, 0xca, + 0x2f, 0xc9, 0x17, 0x12, 0xc9, 0x49, 0x2c, 0x4b, 0xcc, 0x4b, 0x2d, 0xd1, 0x03, 0xd1, 0x7a, 0x50, + 0x4d, 0x52, 0x26, 0x30, 0xdd, 0xa5, 0x79, 0x99, 0x85, 0xa5, 0xa9, 0xe8, 0x7a, 0xe3, 0x93, 0x73, + 0x32, 0x41, 0x5c, 0x98, 0xd9, 0x10, 0xb3, 0x94, 0x6e, 0x30, 0x72, 0x89, 0x05, 0x40, 0x85, 0x02, + 0x20, 0x3a, 0x82, 0x21, 0x1a, 0x84, 0x44, 0xb8, 0x58, 0x33, 0xf3, 0x52, 0x52, 0x2b, 0x24, 0x18, + 0x15, 0x18, 0x35, 0x38, 0x83, 0x20, 0x1c, 0x90, 0x68, 0x6a, 0x41, 0x7e, 0x72, 0x86, 0x04, 0xb3, + 0x02, 0xa3, 0x06, 0x4b, 0x10, 0x84, 0x23, 0x14, 0xc6, 0xa5, 0x06, 0xb1, 0x16, 0xd5, 0x0c, 0x67, + 0xb0, 0x9d, 0x30, 0xf3, 0xbd, 0x53, 0x2b, 0x8b, 0x25, 0x58, 0x15, 0x98, 0x35, 0x38, 0x83, 0x88, + 0x54, 0x2d, 0xa4, 0xc7, 0x25, 0x94, 0x9c, 0x9f, 0x5b, 0x90, 0x93, 0x98, 0x99, 0x97, 0x5a, 0x54, + 0x1c, 0x92, 0x5f, 0x92, 0x98, 0xe3, 0x5c, 0x2a, 0xc1, 0x06, 0xb6, 0x1a, 0x8b, 0x8c, 0x17, 0x0b, + 0x07, 0x93, 0x00, 0xb3, 0x17, 0x0b, 0x07, 0x8b, 0x00, 0xab, 0x93, 0xe3, 0x89, 0x47, 0x72, 0x8c, + 0x17, 0x1e, 0xc9, 0x31, 0x3e, 0x78, 0x24, 0xc7, 0x38, 0xe1, 0xb1, 0x1c, 0xc3, 0x85, 0xc7, 0x72, + 0x0c, 0x37, 0x1e, 0xcb, 0x31, 0x44, 0xa9, 0xa7, 0x67, 0x96, 0x64, 0x94, 0x26, 0xe9, 0x25, 0xe7, + 0xe7, 0xea, 0x43, 0xc3, 0x12, 0x4c, 0xeb, 0x57, 0xe8, 0xc3, 0x02, 0xb1, 0xa4, 0xb2, 0x20, 0xb5, + 0x38, 0x89, 0x0d, 0x1c, 0x48, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x01, 0xa4, 0x36, 0x92, + 0x9a, 0x01, 0x00, 0x00, } func (m *ProviderPaymentStorage) Marshal() (dAtA []byte, err error) { @@ -140,6 +140,11 @@ func (m *ProviderPaymentStorage) MarshalToSizedBuffer(dAtA []byte) (int, error) _ = i var l int _ = l + if m.ComplainersTotalCu != 0 { + i = encodeVarintProviderPaymentStorage(dAtA, i, uint64(m.ComplainersTotalCu)) + i-- + dAtA[i] = 0x30 + } if len(m.UniquePaymentStorageClientProviderKeys) > 0 { for iNdEx := len(m.UniquePaymentStorageClientProviderKeys) - 1; iNdEx >= 0; iNdEx-- { i -= len(m.UniquePaymentStorageClientProviderKeys[iNdEx]) @@ -149,15 +154,6 @@ func (m *ProviderPaymentStorage) MarshalToSizedBuffer(dAtA []byte) (int, error) dAtA[i] = 0x2a } } - if len(m.UnresponsivenessComplaints) > 0 { - for iNdEx := len(m.UnresponsivenessComplaints) - 1; iNdEx >= 0; iNdEx-- { - i -= len(m.UnresponsivenessComplaints[iNdEx]) - copy(dAtA[i:], m.UnresponsivenessComplaints[iNdEx]) - i = encodeVarintProviderPaymentStorage(dAtA, i, uint64(len(m.UnresponsivenessComplaints[iNdEx]))) - i-- - dAtA[i] = 0x22 - } - } if m.Epoch != 0 { i = encodeVarintProviderPaymentStorage(dAtA, i, uint64(m.Epoch)) i-- @@ -197,18 +193,15 @@ func (m *ProviderPaymentStorage) Size() (n int) { if m.Epoch != 0 { n += 1 + sovProviderPaymentStorage(uint64(m.Epoch)) } - if len(m.UnresponsivenessComplaints) > 0 { - for _, s := range m.UnresponsivenessComplaints { - l = len(s) - n += 1 + l + sovProviderPaymentStorage(uint64(l)) - } - } if len(m.UniquePaymentStorageClientProviderKeys) > 0 { for _, s := range m.UniquePaymentStorageClientProviderKeys { l = len(s) n += 1 + l + sovProviderPaymentStorage(uint64(l)) } } + if m.ComplainersTotalCu != 0 { + n += 1 + sovProviderPaymentStorage(uint64(m.ComplainersTotalCu)) + } return n } @@ -298,9 +291,9 @@ func (m *ProviderPaymentStorage) Unmarshal(dAtA []byte) error { break } } - case 4: + case 5: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UnresponsivenessComplaints", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field UniquePaymentStorageClientProviderKeys", wireType) } var stringLen uint64 for shift := uint(0); ; shift += 7 { @@ -328,13 +321,13 @@ func (m *ProviderPaymentStorage) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.UnresponsivenessComplaints = append(m.UnresponsivenessComplaints, string(dAtA[iNdEx:postIndex])) + m.UniquePaymentStorageClientProviderKeys = append(m.UniquePaymentStorageClientProviderKeys, string(dAtA[iNdEx:postIndex])) iNdEx = postIndex - case 5: - if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field UniquePaymentStorageClientProviderKeys", wireType) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ComplainersTotalCu", wireType) } - var stringLen uint64 + m.ComplainersTotalCu = 0 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowProviderPaymentStorage @@ -344,24 +337,11 @@ func (m *ProviderPaymentStorage) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - stringLen |= uint64(b&0x7F) << shift + m.ComplainersTotalCu |= uint64(b&0x7F) << shift if b < 0x80 { break } } - intStringLen := int(stringLen) - if intStringLen < 0 { - return ErrInvalidLengthProviderPaymentStorage - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return ErrInvalidLengthProviderPaymentStorage - } - if postIndex > l { - return io.ErrUnexpectedEOF - } - m.UniquePaymentStorageClientProviderKeys = append(m.UniquePaymentStorageClientProviderKeys, string(dAtA[iNdEx:postIndex])) - iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipProviderPaymentStorage(dAtA[iNdEx:]) diff --git a/x/pairing/types/relay_test.go b/x/pairing/types/relay_test.go index 31aa1edea2..5edc50873f 100644 --- a/x/pairing/types/relay_test.go +++ b/x/pairing/types/relay_test.go @@ -1,8 +1,9 @@ package types import ( - "github.com/stretchr/testify/assert" "testing" + + "github.com/stretchr/testify/assert" ) // getDummyRequest creates dummy request used in tests