From 2f8b57440803b53c02ed9923f6380eb678b5f498 Mon Sep 17 00:00:00 2001 From: Yarom Swisa Date: Wed, 1 Feb 2023 21:46:24 +0000 Subject: [PATCH 1/4] we now use block hash from stake storage to calc pairing --- docs/static/openapi.yml | 574 ++++++++++-------- testutil/keeper/keepers_init.go | 7 + x/epochstorage/keeper/stake_storage.go | 6 +- .../grpc_query_static_providers_list.go | 2 +- .../msg_server_stake_unstake_gov_test.go | 8 +- x/pairing/keeper/pairing.go | 25 +- x/pairing/keeper/pairing_test.go | 12 + x/pairing/types/expected_keepers.go | 2 +- 8 files changed, 368 insertions(+), 268 deletions(-) diff --git a/docs/static/openapi.yml b/docs/static/openapi.yml index 95fa0aa2c0..b9b342ebd2 100644 --- a/docs/static/openapi.yml +++ b/docs/static/openapi.yml @@ -30145,33 +30145,10 @@ paths: properties: index: type: string - clientsPayments: + providerPaymentStorageKeys: type: array items: - type: object - properties: - index: - type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 - epoch: - type: string - format: uint64 - unresponsiveness_complaints: - type: array - items: - type: string + type: string pagination: type: object properties: @@ -30291,33 +30268,10 @@ paths: properties: index: type: string - clientsPayments: + providerPaymentStorageKeys: type: array items: - type: object - properties: - index: - type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 - epoch: - type: string - format: uint64 - unresponsiveness_complaints: - type: array - items: - type: string + type: string default: description: An unexpected error response. schema: @@ -30519,19 +30473,6 @@ paths: properties: index: type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 epoch: type: string format: uint64 @@ -30539,6 +30480,10 @@ paths: type: array items: type: string + uniquePaymentStorageClientProviderKeys: + type: array + items: + type: string pagination: type: object properties: @@ -30658,19 +30603,6 @@ paths: properties: index: type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 epoch: type: string format: uint64 @@ -30678,6 +30610,10 @@ paths: type: array items: type: string + uniquePaymentStorageClientProviderKeys: + type: array + items: + type: string default: description: An unexpected error response. schema: @@ -31237,10 +31173,19 @@ paths: schema: type: object properties: - chainNames: + chainInfoList: type: array items: - type: string + type: object + properties: + chainName: + type: string + chainID: + type: string + enabledApiInterfaces: + type: array + items: + type: string default: description: An unexpected error response. schema: @@ -31354,16 +31299,17 @@ paths: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered - and flat expected areguments are: [param - index] (example: PARAMS: - [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + and flat expected arguments are: [param index] + (example: PARAMS: [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block compute_units: type: string @@ -31394,6 +31340,34 @@ paths: stateful: type: integer format: int64 + overwrite_block_parsing: + type: object + properties: + parser_arg: + type: array + items: + type: string + parser_func: + type: string + enum: + - EMPTY + - PARSE_BY_ARG + - PARSE_CANONICAL + - PARSE_DICTIONARY + - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT + - DEFAULT + default: EMPTY + title: >- + - PARSE_BY_ARG: means parameters are + ordered and flat expected arguments are: + [param index] (example: PARAMS: + [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) + - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) + - DEFAULT: means parameters are non related to block, and should fetch latest block reserved: type: object properties: @@ -31428,16 +31402,18 @@ paths: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are - ordered and flat expected areguments are: + ordered and flat expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block enabled: type: boolean @@ -31640,15 +31616,17 @@ paths: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and - flat expected areguments are: [param index] + flat expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block compute_units: type: string @@ -31679,6 +31657,34 @@ paths: stateful: type: integer format: int64 + overwrite_block_parsing: + type: object + properties: + parser_arg: + type: array + items: + type: string + parser_func: + type: string + enum: + - EMPTY + - PARSE_BY_ARG + - PARSE_CANONICAL + - PARSE_DICTIONARY + - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT + - DEFAULT + default: EMPTY + title: >- + - PARSE_BY_ARG: means parameters are + ordered and flat expected arguments are: + [param index] (example: PARAMS: + [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) + - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) + - DEFAULT: means parameters are non related to block, and should fetch latest block reserved: type: object properties: @@ -31713,16 +31719,18 @@ paths: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered - and flat expected areguments are: [param + and flat expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block enabled: type: boolean @@ -53550,33 +53558,10 @@ definitions: properties: index: type: string - clientsPayments: + providerPaymentStorageKeys: type: array items: - type: object - properties: - index: - type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 - epoch: - type: string - format: uint64 - unresponsiveness_complaints: - type: array - items: - type: string + type: string lavanet.lava.pairing.MsgRelayPaymentResponse: type: object lavanet.lava.pairing.MsgStakeClientResponse: @@ -53621,19 +53606,6 @@ definitions: properties: index: type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 epoch: type: string format: uint64 @@ -53641,6 +53613,10 @@ definitions: type: array items: type: string + uniquePaymentStorageClientProviderKeys: + type: array + items: + type: string lavanet.lava.pairing.QueryAllEpochPaymentsResponse: type: object properties: @@ -53651,33 +53627,10 @@ definitions: properties: index: type: string - clientsPayments: + providerPaymentStorageKeys: type: array items: - type: object - properties: - index: - type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 - epoch: - type: string - format: uint64 - unresponsiveness_complaints: - type: array - items: - type: string + type: string pagination: type: object properties: @@ -53713,19 +53666,6 @@ definitions: properties: index: type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 epoch: type: string format: uint64 @@ -53733,6 +53673,10 @@ definitions: type: array items: type: string + uniquePaymentStorageClientProviderKeys: + type: array + items: + type: string pagination: type: object properties: @@ -53858,33 +53802,10 @@ definitions: properties: index: type: string - clientsPayments: + providerPaymentStorageKeys: type: array items: - type: object - properties: - index: - type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 - epoch: - type: string - format: uint64 - unresponsiveness_complaints: - type: array - items: - type: string + type: string lavanet.lava.pairing.QueryGetPairingResponse: type: object properties: @@ -53954,19 +53875,6 @@ definitions: properties: index: type: string - uniquePaymentStorageClientProvider: - type: array - items: - type: object - properties: - index: - type: string - block: - type: string - format: uint64 - usedCU: - type: string - format: uint64 epoch: type: string format: uint64 @@ -53974,6 +53882,10 @@ definitions: type: array items: type: string + uniquePaymentStorageClientProviderKeys: + type: array + items: + type: string lavanet.lava.pairing.QueryGetUniquePaymentStorageClientProviderResponse: type: object properties: @@ -54212,6 +54124,33 @@ definitions: stateful: type: integer format: int64 + overwrite_block_parsing: + type: object + properties: + parser_arg: + type: array + items: + type: string + parser_func: + type: string + enum: + - EMPTY + - PARSE_BY_ARG + - PARSE_CANONICAL + - PARSE_DICTIONARY + - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT + - DEFAULT + default: EMPTY + title: >- + - PARSE_BY_ARG: means parameters are ordered and flat expected + arguments are: [param index] (example: PARAMS: + [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) + - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) + - DEFAULT: means parameters are non related to block, and should fetch latest block lavanet.lava.spec.BlockParser: type: object properties: @@ -54227,15 +54166,16 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and flat expected - areguments are: [param index] (example: PARAMS: - [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block lavanet.lava.spec.PARSER_FUNC: type: string @@ -54245,14 +54185,16 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - - PARSE_BY_ARG: means parameters are ordered and flat expected areguments + - PARSE_BY_ARG: means parameters are ordered and flat expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block lavanet.lava.spec.Params: type: object @@ -54286,15 +54228,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and flat expected - areguments are: [param index] (example: PARAMS: + arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block lavanet.lava.spec.QueryAllSpecResponse: type: object @@ -54330,15 +54274,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and flat - expected areguments are: [param index] (example: + expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block compute_units: type: string @@ -54369,6 +54315,33 @@ definitions: stateful: type: integer format: int64 + overwrite_block_parsing: + type: object + properties: + parser_arg: + type: array + items: + type: string + parser_func: + type: string + enum: + - EMPTY + - PARSE_BY_ARG + - PARSE_CANONICAL + - PARSE_DICTIONARY + - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT + - DEFAULT + default: EMPTY + title: >- + - PARSE_BY_ARG: means parameters are ordered and + flat expected arguments are: [param index] + (example: PARAMS: [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) + - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) + - DEFAULT: means parameters are non related to block, and should fetch latest block reserved: type: object properties: @@ -54403,15 +54376,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and - flat expected areguments are: [param index] + flat expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block enabled: type: boolean @@ -54528,15 +54503,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and flat - expected areguments are: [param index] (example: PARAMS: + expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block compute_units: type: string @@ -54567,6 +54544,33 @@ definitions: stateful: type: integer format: int64 + overwrite_block_parsing: + type: object + properties: + parser_arg: + type: array + items: + type: string + parser_func: + type: string + enum: + - EMPTY + - PARSE_BY_ARG + - PARSE_CANONICAL + - PARSE_DICTIONARY + - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT + - DEFAULT + default: EMPTY + title: >- + - PARSE_BY_ARG: means parameters are ordered and + flat expected arguments are: [param index] + (example: PARAMS: [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) + - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) + - DEFAULT: means parameters are non related to block, and should fetch latest block reserved: type: object properties: @@ -54601,15 +54605,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and - flat expected areguments are: [param index] - (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + flat expected arguments are: [param index] (example: + PARAMS: [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block enabled: type: boolean @@ -54686,10 +54692,19 @@ definitions: lavanet.lava.spec.QueryShowAllChainsResponse: type: object properties: - chainNames: + chainInfoList: type: array items: - type: string + type: object + properties: + chainName: + type: string + chainID: + type: string + enabledApiInterfaces: + type: array + items: + type: string lavanet.lava.spec.QueryShowChainInfoResponse: type: object properties: @@ -54730,15 +54745,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and flat expected - areguments are: [param index] (example: PARAMS: + arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block compute_units: type: string @@ -54769,6 +54786,33 @@ definitions: stateful: type: integer format: int64 + overwrite_block_parsing: + type: object + properties: + parser_arg: + type: array + items: + type: string + parser_func: + type: string + enum: + - EMPTY + - PARSE_BY_ARG + - PARSE_CANONICAL + - PARSE_DICTIONARY + - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT + - DEFAULT + default: EMPTY + title: >- + - PARSE_BY_ARG: means parameters are ordered and flat + expected arguments are: [param index] (example: PARAMS: + [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) + - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) + - DEFAULT: means parameters are non related to block, and should fetch latest block reserved: type: object properties: @@ -54803,15 +54847,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and flat expected - areguments are: [param index] (example: PARAMS: + arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block lavanet.lava.spec.Spec: type: object @@ -54842,15 +54888,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and flat - expected areguments are: [param index] (example: PARAMS: + expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block compute_units: type: string @@ -54881,6 +54929,33 @@ definitions: stateful: type: integer format: int64 + overwrite_block_parsing: + type: object + properties: + parser_arg: + type: array + items: + type: string + parser_func: + type: string + enum: + - EMPTY + - PARSE_BY_ARG + - PARSE_CANONICAL + - PARSE_DICTIONARY + - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT + - DEFAULT + default: EMPTY + title: >- + - PARSE_BY_ARG: means parameters are ordered and flat + expected arguments are: [param index] (example: + PARAMS: [<#BlockNum>,"banana"]) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) + - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) + - DEFAULT: means parameters are non related to block, and should fetch latest block reserved: type: object properties: @@ -54915,15 +54990,17 @@ definitions: - PARSE_CANONICAL - PARSE_DICTIONARY - PARSE_DICTIONARY_OR_ORDERED + - PARSE_DICTIONARY_OR_DEFAULT - DEFAULT default: EMPTY title: >- - PARSE_BY_ARG: means parameters are ordered and flat - expected areguments are: [param index] (example: PARAMS: + expected arguments are: [param index] (example: PARAMS: [<#BlockNum>,"banana"]) - - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected areguments are: [param index to object,propname in object] (example: PARAMS: ["banana",{propname:<#BlockNum>}]) - - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {propname:<#BlockNum>,prop2:"banana"}) + - PARSE_CANONICAL: means parameters are ordered and one of them has named properties, expected arguments are: [param index to object,prop_name in object] (example: PARAMS: ["banana",{prop_name:<#BlockNum>}]) + - PARSE_DICTIONARY: means parameters are named, expected arguments are [prop_name,separator] (example: PARAMS: {prop_name:<#BlockNum>,prop2:"banana"}) - PARSE_DICTIONARY_OR_ORDERED: means parameters are named expected arguments are [prop_name,separator,parameter order if not found] + - PARSE_DICTIONARY_OR_DEFAULT: means parameters are named, expected arguments are [prop_name,separator,default value] (example: PARAMS: {prop_name:<#BlockNum>} or /prop_name=blockNum) - DEFAULT: means parameters are non related to block, and should fetch latest block enabled: type: boolean @@ -55004,3 +55081,14 @@ definitions: type: array items: type: string + lavanet.lava.spec.showAllChainsInfoStruct: + type: object + properties: + chainName: + type: string + chainID: + type: string + enabledApiInterfaces: + type: array + items: + type: string diff --git a/testutil/keeper/keepers_init.go b/testutil/keeper/keepers_init.go index 683a903d10..e0c6b14917 100644 --- a/testutil/keeper/keepers_init.go +++ b/testutil/keeper/keepers_init.go @@ -2,6 +2,7 @@ package keeper import ( "context" + "crypto/rand" "testing" "time" @@ -32,6 +33,8 @@ import ( const BLOCK_TIME = 30 * time.Second +const BLOCK_HEADER_LEN = 32 + type Keepers struct { Epochstorage epochstoragekeeper.Keeper Spec speckeeper.Keeper @@ -147,6 +150,10 @@ func AdvanceBlock(ctx context.Context, ks *Keepers, customBlockTime ...time.Dura block := uint64(unwrapedCtx.BlockHeight() + 1) unwrapedCtx = unwrapedCtx.WithBlockHeight(int64(block)) + + headerHash := make([]byte, BLOCK_HEADER_LEN) + rand.Read(headerHash) + unwrapedCtx = unwrapedCtx.WithHeaderHash(headerHash) if len(customBlockTime) > 0 { NewBlock(sdk.WrapSDKContext(unwrapedCtx), ks, customBlockTime...) } else { diff --git a/x/epochstorage/keeper/stake_storage.go b/x/epochstorage/keeper/stake_storage.go index fcaec36369..8d81859a29 100644 --- a/x/epochstorage/keeper/stake_storage.go +++ b/x/epochstorage/keeper/stake_storage.go @@ -470,13 +470,13 @@ func (k Keeper) GetStakeEntryForAllProvidersEpoch(ctx sdk.Context, chainID strin return &stakeStorage.StakeEntries, nil } -func (k Keeper) GetEpochStakeEntries(ctx sdk.Context, block uint64, storageType string, chainID string) (entries []types.StakeEntry, found bool) { +func (k Keeper) GetEpochStakeEntries(ctx sdk.Context, block uint64, storageType string, chainID string) (entries []types.StakeEntry, found bool, epochHash []byte) { key := k.StakeStorageKey(storageType, block, chainID) stakeStorage, found := k.GetStakeStorage(ctx, key) if !found { - return nil, false + return nil, false, nil } - return stakeStorage.StakeEntries, true + return stakeStorage.StakeEntries, true, stakeStorage.EpochBlockHash } // append to epoch stake entries ONLY if it doesn't exist diff --git a/x/pairing/keeper/grpc_query_static_providers_list.go b/x/pairing/keeper/grpc_query_static_providers_list.go index d19fbf8475..3e6608d731 100644 --- a/x/pairing/keeper/grpc_query_static_providers_list.go +++ b/x/pairing/keeper/grpc_query_static_providers_list.go @@ -28,7 +28,7 @@ func (k Keeper) StaticProvidersList(goCtx context.Context, req *types.QueryStati } epoch := k.epochStorageKeeper.GetEpochStart(ctx) - stakes, found := k.epochStorageKeeper.GetEpochStakeEntries(ctx, epoch, epochstoragetypes.ProviderKey, req.GetChainID()) + stakes, found, _ := k.epochStorageKeeper.GetEpochStakeEntries(ctx, epoch, epochstoragetypes.ProviderKey, req.GetChainID()) if !found { return &types.QueryStaticProvidersListResponse{}, nil 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 146b58ab94..292189bffb 100644 --- a/x/pairing/keeper/msg_server_stake_unstake_gov_test.go +++ b/x/pairing/keeper/msg_server_stake_unstake_gov_test.go @@ -86,9 +86,9 @@ func TestStakeGovEpochBlocksDecrease(t *testing.T) { 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()) + _, foundProvider, _ := ts.keepers.Epochstorage.GetEpochStakeEntries(sdk.UnwrapSDKContext(ts.ctx), tt.epoch, epochstoragetypes.ProviderKey, ts.spec.GetIndex()) require.Equal(t, tt.shouldBeStaked, foundProvider) - _, foundClient := ts.keepers.Epochstorage.GetEpochStakeEntries(sdk.UnwrapSDKContext(ts.ctx), tt.epoch, epochstoragetypes.ClientKey, ts.spec.GetIndex()) + _, foundClient, _ := ts.keepers.Epochstorage.GetEpochStakeEntries(sdk.UnwrapSDKContext(ts.ctx), tt.epoch, epochstoragetypes.ClientKey, ts.spec.GetIndex()) require.Equal(t, tt.shouldBeStaked, foundClient) }) } @@ -173,9 +173,9 @@ func TestStakeGovEpochBlocksIncrease(t *testing.T) { 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()) + _, found, _ := ts.keepers.Epochstorage.GetEpochStakeEntries(sdk.UnwrapSDKContext(ts.ctx), tt.epoch, epochstoragetypes.ProviderKey, ts.spec.GetIndex()) require.Equal(t, tt.shouldBeStaked, found) - _, found = ts.keepers.Epochstorage.GetEpochStakeEntries(sdk.UnwrapSDKContext(ts.ctx), tt.epoch, epochstoragetypes.ClientKey, ts.spec.GetIndex()) + _, found, _ = ts.keepers.Epochstorage.GetEpochStakeEntries(sdk.UnwrapSDKContext(ts.ctx), tt.epoch, epochstoragetypes.ClientKey, ts.spec.GetIndex()) require.Equal(t, tt.shouldBeStaked, found) }) } diff --git a/x/pairing/keeper/pairing.go b/x/pairing/keeper/pairing.go index 66dbb6991d..69b44f1863 100644 --- a/x/pairing/keeper/pairing.go +++ b/x/pairing/keeper/pairing.go @@ -10,7 +10,6 @@ import ( epochstoragetypes "github.com/lavanet/lava/x/epochstorage/types" spectypes "github.com/lavanet/lava/x/spec/types" tendermintcrypto "github.com/tendermint/tendermint/crypto" - "github.com/tendermint/tendermint/rpc/core" ) const INVALID_INDEX = -2 @@ -48,7 +47,7 @@ func (k Keeper) VerifyPairingData(ctx sdk.Context, chainID string, clientAddress verifiedUser := false // we get the user stakeEntries at the time of check. for unstaking users, we make sure users can't unstake sooner than blocksToSave so we can charge them if the pairing is valid - userStakedEntries, found := k.epochStorageKeeper.GetEpochStakeEntries(ctx, requestedEpochStart, epochstoragetypes.ClientKey, chainID) + userStakedEntries, found, _ := k.epochStorageKeeper.GetEpochStakeEntries(ctx, requestedEpochStart, epochstoragetypes.ClientKey, chainID) if !found { return nil, utils.LavaError(ctx, logger, "client_entries_pairing", map[string]string{"chainID": chainID, "query Epoch": strconv.FormatUint(requestedEpochStart, 10), "query block": strconv.FormatUint(block, 10), "current epoch": strconv.FormatUint(currentEpochStart, 10)}, "no EpochStakeEntries entries at all for this spec") } @@ -84,12 +83,12 @@ func (k Keeper) GetPairingForClient(ctx sdk.Context, chainID string, clientAddre return nil, fmt.Errorf("invalid user for pairing: %s", err) } - possibleProviders, found := k.epochStorageKeeper.GetEpochStakeEntries(ctx, currentEpoch, epochstoragetypes.ProviderKey, chainID) + possibleProviders, found, epochHash := k.epochStorageKeeper.GetEpochStakeEntries(ctx, currentEpoch, epochstoragetypes.ProviderKey, chainID) if !found { return nil, fmt.Errorf("did not find providers for pairing: epoch:%d, chainID: %s", currentEpoch, chainID) } - providers, _, errorRet = k.calculatePairingForClient(ctx, possibleProviders, clientAddress, currentEpoch, chainID, clientStakeEntry.Geolocation) + providers, _, errorRet = k.calculatePairingForClient(ctx, possibleProviders, clientAddress, currentEpoch, chainID, clientStakeEntry.Geolocation, epochHash) return } @@ -107,12 +106,12 @@ func (k Keeper) ValidatePairingForClient(ctx sdk.Context, chainID string, client return false, nil, INVALID_INDEX, fmt.Errorf("invalid user for pairing: %s", err) } - providerStakeEntries, found := k.epochStorageKeeper.GetEpochStakeEntries(ctx, epochStart, epochstoragetypes.ProviderKey, chainID) + providerStakeEntries, found, blockHash := k.epochStorageKeeper.GetEpochStakeEntries(ctx, epochStart, epochstoragetypes.ProviderKey, chainID) if !found { return false, nil, INVALID_INDEX, fmt.Errorf("could not get provider epoch stake entries for: %d, %s", epochStart, chainID) } - _, validAddresses, errorRet := k.calculatePairingForClient(ctx, providerStakeEntries, clientAddress, epochStart, chainID, userStake.Geolocation) + _, validAddresses, errorRet := k.calculatePairingForClient(ctx, providerStakeEntries, clientAddress, epochStart, chainID, userStake.Geolocation, blockHash) if errorRet != nil { return false, nil, INVALID_INDEX, errorRet } @@ -124,7 +123,7 @@ func (k Keeper) ValidatePairingForClient(ctx sdk.Context, chainID string, client return false, userStake, INVALID_INDEX, nil } -func (k Keeper) calculatePairingForClient(ctx sdk.Context, providers []epochstoragetypes.StakeEntry, clientAddress sdk.AccAddress, epochStartBlock uint64, chainID string, geolocation uint64) (validProviders []epochstoragetypes.StakeEntry, addrList []sdk.AccAddress, err error) { +func (k Keeper) calculatePairingForClient(ctx sdk.Context, providers []epochstoragetypes.StakeEntry, clientAddress sdk.AccAddress, epochStartBlock uint64, chainID string, geolocation uint64, epochHash []byte) (validProviders []epochstoragetypes.StakeEntry, addrList []sdk.AccAddress, err error) { if epochStartBlock > uint64(ctx.BlockHeight()) { k.Logger(ctx).Error("\ninvalid session start\n") panic(fmt.Sprintf("invalid session start saved in keeper %d, current block was %d", epochStartBlock, uint64(ctx.BlockHeight()))) @@ -145,7 +144,7 @@ func (k Keeper) calculatePairingForClient(ctx sdk.Context, providers []epochstor if spec.ProvidersTypes == spectypes.Spec_dynamic { // calculates a hash and randomly chooses the providers - validProviders = k.returnSubsetOfProvidersByStake(ctx, clientAddress, validProviders, servicersToPairCount, epochStartBlock, chainID) + validProviders = k.returnSubsetOfProvidersByStake(ctx, clientAddress, validProviders, servicersToPairCount, epochStartBlock, chainID, epochHash) } else { validProviders = k.returnSubsetOfProvidersByHighestStake(ctx, validProviders, servicersToPairCount) } @@ -181,7 +180,7 @@ func (k Keeper) getGeolocationProviders(ctx sdk.Context, providers []epochstorag } // this function randomly chooses count providers by weight -func (k Keeper) returnSubsetOfProvidersByStake(ctx sdk.Context, clientAddress sdk.AccAddress, providersMaps []epochstoragetypes.StakeEntry, count uint64, block uint64, chainID string) (returnedProviders []epochstoragetypes.StakeEntry) { +func (k Keeper) returnSubsetOfProvidersByStake(ctx sdk.Context, clientAddress sdk.AccAddress, providersMaps []epochstoragetypes.StakeEntry, count uint64, block uint64, chainID string, epochHash []byte) (returnedProviders []epochstoragetypes.StakeEntry) { stakeSum := sdk.NewCoin(epochstoragetypes.TokenDenom, sdk.NewInt(0)) hashData := make([]byte, 0) for _, stakedProvider := range providersMaps { @@ -193,13 +192,7 @@ func (k Keeper) returnSubsetOfProvidersByStake(ctx sdk.Context, clientAddress sd } // add the session start block hash to the function to make it as unpredictable as we can - block_height := int64(block) - epochStartBlock, err := core.Block(nil, &block_height) - if err != nil { - k.Logger(ctx).Error("Failed To Get block from tendermint core") - } - sessionBlockHash := epochStartBlock.Block.Hash() - hashData = append(hashData, sessionBlockHash...) + hashData = append(hashData, epochHash...) hashData = append(hashData, chainID...) // to make this pairing unique per chainID hashData = append(hashData, clientAddress...) // to make this pairing unique per consumer diff --git a/x/pairing/keeper/pairing_test.go b/x/pairing/keeper/pairing_test.go index 46b0111f0b..2a87a676cf 100644 --- a/x/pairing/keeper/pairing_test.go +++ b/x/pairing/keeper/pairing_test.go @@ -38,6 +38,7 @@ func TestPairingUniqueness(t *testing.T) { ctx = testkeeper.AdvanceEpoch(ctx, keepers) + // test that 2 different clients get different pairings providers1, err := keepers.Pairing.GetPairingForClient(sdk.UnwrapSDKContext(ctx), spec.Index, consumer1.Addr) require.Nil(t, err) @@ -62,6 +63,17 @@ func TestPairingUniqueness(t *testing.T) { require.True(t, diffrent) + ctx = testkeeper.AdvanceEpoch(ctx, keepers) + + // test that in different epoch we get different pairings for consumer1 + providers11, err := keepers.Pairing.GetPairingForClient(sdk.UnwrapSDKContext(ctx), spec.Index, consumer1.Addr) + require.Nil(t, err) + + require.Equal(t, len(providers1), len(providers11)) + for i := range providers1 { + require.NotEqual(t, providers1[i].Address, providers11[i].Address) + } + } // Test that verifies that new get-pairing return values (CurrentEpoch, TimeLeftToNextPairing, SpecLastUpdatedBlock) is working properly diff --git a/x/pairing/types/expected_keepers.go b/x/pairing/types/expected_keepers.go index 1d6aa8aa9b..4fcaa6b866 100644 --- a/x/pairing/types/expected_keepers.go +++ b/x/pairing/types/expected_keepers.go @@ -37,7 +37,7 @@ type EpochstorageKeeper interface { GetStakeEntryByAddressCurrent(ctx sdk.Context, storageType string, chainID string, address sdk.AccAddress) (value epochstoragetypes.StakeEntry, found bool, index uint64) UnstakeEntryByAddress(ctx sdk.Context, storageType string, address sdk.AccAddress) (value epochstoragetypes.StakeEntry, found bool, index uint64) GetStakeStorageCurrent(ctx sdk.Context, storageType string, chainID string) (epochstoragetypes.StakeStorage, bool) - GetEpochStakeEntries(ctx sdk.Context, block uint64, storageType string, chainID string) (entries []epochstoragetypes.StakeEntry, found bool) + GetEpochStakeEntries(ctx sdk.Context, block uint64, storageType string, chainID string) (entries []epochstoragetypes.StakeEntry, found bool, epochHash []byte) GetStakeEntryByAddressFromStorage(ctx sdk.Context, stakeStorage epochstoragetypes.StakeStorage, address sdk.AccAddress) (value epochstoragetypes.StakeEntry, found bool, index uint64) GetNextEpoch(ctx sdk.Context, block uint64) (nextEpoch uint64, erro error) GetStakeEntryForClientEpoch(ctx sdk.Context, chainID string, selectedClient sdk.AccAddress, epoch uint64) (entry *epochstoragetypes.StakeEntry, err error) From b319dccb6182db7451da6f813e8735abec9aff38 Mon Sep 17 00:00:00 2001 From: Yarom Swisa Date: Wed, 1 Feb 2023 21:50:48 +0000 Subject: [PATCH 2/4] added minstake to test networks --- cookbook/spec_add_arbitrum.json | 8 ++++++++ cookbook/spec_add_cosmoshub.json | 8 ++++++++ cookbook/spec_add_fantom.json | 8 ++++++++ cookbook/spec_add_juno.json | 8 ++++++++ cookbook/spec_add_osmosis.json | 8 ++++++++ cookbook/spec_add_polygon.json | 8 ++++++++ 6 files changed, 48 insertions(+) diff --git a/cookbook/spec_add_arbitrum.json b/cookbook/spec_add_arbitrum.json index 01874de3e8..a65f0384b2 100644 --- a/cookbook/spec_add_arbitrum.json +++ b/cookbook/spec_add_arbitrum.json @@ -1305,6 +1305,14 @@ "blocks_in_finalization_proof": 3, "average_block_time": "500", "allowed_block_lag_for_qos_sync": "20", + "min_stake_provider": { + "denom": "ulava", + "amount": "1000" + }, + "min_stake_client": { + "denom": "ulava", + "amount": "100" + }, "apis": [ { "name": "rpc_modules", diff --git a/cookbook/spec_add_cosmoshub.json b/cookbook/spec_add_cosmoshub.json index d8a373a779..86095c94b5 100644 --- a/cookbook/spec_add_cosmoshub.json +++ b/cookbook/spec_add_cosmoshub.json @@ -5797,6 +5797,14 @@ "blocks_in_finalization_proof": 1, "average_block_time": "6500", "allowed_block_lag_for_qos_sync": "10", + "min_stake_provider": { + "denom": "ulava", + "amount": "1000" + }, + "min_stake_client": { + "denom": "ulava", + "amount": "100" + }, "apis": [ { "name": "abci_info", diff --git a/cookbook/spec_add_fantom.json b/cookbook/spec_add_fantom.json index 7c0aa44801..e8d10b991b 100644 --- a/cookbook/spec_add_fantom.json +++ b/cookbook/spec_add_fantom.json @@ -1613,6 +1613,14 @@ "blocks_in_finalization_proof": 1, "average_block_time": "1500", "allowed_block_lag_for_qos_sync": "5", + "min_stake_provider": { + "denom": "ulava", + "amount": "1000" + }, + "min_stake_client": { + "denom": "ulava", + "amount": "100" + }, "apis": [ { "name": "web3_clientVersion", diff --git a/cookbook/spec_add_juno.json b/cookbook/spec_add_juno.json index b2fb7a096a..34e36ef5df 100644 --- a/cookbook/spec_add_juno.json +++ b/cookbook/spec_add_juno.json @@ -6565,6 +6565,14 @@ "blocks_in_finalization_proof": 1, "average_block_time": "6500", "allowed_block_lag_for_qos_sync": "2", + "min_stake_provider": { + "denom": "ulava", + "amount": "1000" + }, + "min_stake_client": { + "denom": "ulava", + "amount": "100" + }, "apis": [ { "name": "abci_info", diff --git a/cookbook/spec_add_osmosis.json b/cookbook/spec_add_osmosis.json index c1d030ad26..b71800baef 100644 --- a/cookbook/spec_add_osmosis.json +++ b/cookbook/spec_add_osmosis.json @@ -9565,6 +9565,14 @@ "blocks_in_finalization_proof": 1, "average_block_time": "6500", "allowed_block_lag_for_qos_sync": "3", + "min_stake_provider": { + "denom": "ulava", + "amount": "1000" + }, + "min_stake_client": { + "denom": "ulava", + "amount": "100" + }, "apis": [ { "name": "abci_info", diff --git a/cookbook/spec_add_polygon.json b/cookbook/spec_add_polygon.json index 20137e2c12..bdc4ff7b94 100644 --- a/cookbook/spec_add_polygon.json +++ b/cookbook/spec_add_polygon.json @@ -1401,6 +1401,14 @@ "blocks_in_finalization_proof": 3, "average_block_time": "2000", "allowed_block_lag_for_qos_sync": "30", + "min_stake_provider": { + "denom": "ulava", + "amount": "1000" + }, + "min_stake_client": { + "denom": "ulava", + "amount": "100" + }, "apis": [ { "name": "rpc_modules", From 7b19cb3abc6a656da2834bf7f27df52ddcba9bee Mon Sep 17 00:00:00 2001 From: Yarom Swisa Date: Thu, 2 Feb 2023 00:55:46 +0000 Subject: [PATCH 3/4] doing some more testing --- x/pairing/keeper/pairing_test.go | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/x/pairing/keeper/pairing_test.go b/x/pairing/keeper/pairing_test.go index 2a87a676cf..63a85b51b3 100644 --- a/x/pairing/keeper/pairing_test.go +++ b/x/pairing/keeper/pairing_test.go @@ -47,7 +47,7 @@ func TestPairingUniqueness(t *testing.T) { require.Equal(t, len(providers1), len(providers2)) - diffrent := false + different := false for _, provider := range providers1 { found := false @@ -57,11 +57,11 @@ func TestPairingUniqueness(t *testing.T) { } } if !found { - diffrent = true + different = true } } - require.True(t, diffrent) + require.True(t, different) ctx = testkeeper.AdvanceEpoch(ctx, keepers) @@ -70,10 +70,33 @@ func TestPairingUniqueness(t *testing.T) { require.Nil(t, err) require.Equal(t, len(providers1), len(providers11)) + different = false for i := range providers1 { - require.NotEqual(t, providers1[i].Address, providers11[i].Address) + if providers1[i].Address != providers11[i].Address { + different = true + break + } } + require.True(t, different) + + //test that get pairing gives the same results for the whole epoch + epochBlocks := keepers.Epochstorage.EpochBlocksRaw(sdk.UnwrapSDKContext(ctx)) + for i := uint64(0); i < epochBlocks-1; i++ { + ctx = testkeeper.AdvanceBlock(ctx, keepers) + + providers111, err := keepers.Pairing.GetPairingForClient(sdk.UnwrapSDKContext(ctx), spec.Index, consumer1.Addr) + require.Nil(t, err) + + for i := range providers1 { + require.Equal(t, providers11[i].Address, providers111[i].Address) + providerAddr, err := sdk.AccAddressFromBech32(providers11[i].Address) + require.Nil(t, err) + valid, _, _, _ := keepers.Pairing.ValidatePairingForClient(sdk.UnwrapSDKContext(ctx), spec.Index, consumer1.Addr, providerAddr, uint64(sdk.UnwrapSDKContext(ctx).BlockHeight())) + require.True(t, valid) + } + + } } // Test that verifies that new get-pairing return values (CurrentEpoch, TimeLeftToNextPairing, SpecLastUpdatedBlock) is working properly From e74ab7d598edff3426a798f6546e751f93df2546 Mon Sep 17 00:00:00 2001 From: Yarom Swisa Date: Thu, 2 Feb 2023 01:30:47 +0000 Subject: [PATCH 4/4] index testing --- x/pairing/keeper/pairing_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x/pairing/keeper/pairing_test.go b/x/pairing/keeper/pairing_test.go index 63a85b51b3..b037c5d5a0 100644 --- a/x/pairing/keeper/pairing_test.go +++ b/x/pairing/keeper/pairing_test.go @@ -81,6 +81,7 @@ func TestPairingUniqueness(t *testing.T) { //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++ { ctx = testkeeper.AdvanceBlock(ctx, keepers) @@ -92,8 +93,13 @@ func TestPairingUniqueness(t *testing.T) { providerAddr, err := sdk.AccAddressFromBech32(providers11[i].Address) require.Nil(t, err) - valid, _, _, _ := keepers.Pairing.ValidatePairingForClient(sdk.UnwrapSDKContext(ctx), spec.Index, consumer1.Addr, providerAddr, uint64(sdk.UnwrapSDKContext(ctx).BlockHeight())) + valid, _, foundIndex, _ := keepers.Pairing.ValidatePairingForClient(sdk.UnwrapSDKContext(ctx), spec.Index, consumer1.Addr, providerAddr, uint64(sdk.UnwrapSDKContext(ctx).BlockHeight())) require.True(t, valid) + if _, ok := foundIndexMap[providers11[i].Address]; !ok { + foundIndexMap[providers11[i].Address] = foundIndex + } else { + require.Equal(t, foundIndexMap[providers11[i].Address], foundIndex) + } } }